xref: /petsc/src/mat/interface/matrix.c (revision b8d122ce9324c229bca2eb96411ba97eeb599f4e)
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 
44 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL};
45 
46 /*@
47    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,
48                   for sparse matrices that already have locations it fills the locations with random numbers
49 
50    Logically Collective on Mat
51 
52    Input Parameters:
53 +  x  - the matrix
54 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
55           it will create one internally.
56 
57    Output Parameter:
58 .  x  - the matrix
59 
60    Example of Usage:
61 .vb
62      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
63      MatSetRandom(x,rctx);
64      PetscRandomDestroy(rctx);
65 .ve
66 
67    Level: intermediate
68 
69 
70 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
71 @*/
72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
73 {
74   PetscErrorCode ierr;
75   PetscRandom    randObj = NULL;
76 
77   PetscFunctionBegin;
78   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
79   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
80   PetscValidType(x,1);
81 
82   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
83 
84   if (!rctx) {
85     MPI_Comm comm;
86     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
87     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
88     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
89     rctx = randObj;
90   }
91 
92   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
93   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
94   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
95 
96   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
97   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
98   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
99   PetscFunctionReturn(0);
100 }
101 
102 /*@
103    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
104 
105    Logically Collective on Mat
106 
107    Input Parameters:
108 .  mat - the factored matrix
109 
110    Output Parameter:
111 +  pivot - the pivot value computed
112 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
113          the share the matrix
114 
115    Level: advanced
116 
117    Notes:
118     This routine does not work for factorizations done with external packages.
119 
120     This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
121 
122     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
123 
124 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
125 @*/
126 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
127 {
128   PetscFunctionBegin;
129   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
130   *pivot = mat->factorerror_zeropivot_value;
131   *row   = mat->factorerror_zeropivot_row;
132   PetscFunctionReturn(0);
133 }
134 
135 /*@
136    MatFactorGetError - gets the error code from a factorization
137 
138    Logically Collective on Mat
139 
140    Input Parameters:
141 .  mat - the factored matrix
142 
143    Output Parameter:
144 .  err  - the error code
145 
146    Level: advanced
147 
148    Notes:
149     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
150 
151 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
152 @*/
153 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
154 {
155   PetscFunctionBegin;
156   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
157   *err = mat->factorerrortype;
158   PetscFunctionReturn(0);
159 }
160 
161 /*@
162    MatFactorClearError - clears the error code in a factorization
163 
164    Logically Collective on Mat
165 
166    Input Parameter:
167 .  mat - the factored matrix
168 
169    Level: developer
170 
171    Notes:
172     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
173 
174 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
175 @*/
176 PetscErrorCode MatFactorClearError(Mat mat)
177 {
178   PetscFunctionBegin;
179   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
180   mat->factorerrortype             = MAT_FACTOR_NOERROR;
181   mat->factorerror_zeropivot_value = 0.0;
182   mat->factorerror_zeropivot_row   = 0;
183   PetscFunctionReturn(0);
184 }
185 
186 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
187 {
188   PetscErrorCode    ierr;
189   Vec               r,l;
190   const PetscScalar *al;
191   PetscInt          i,nz,gnz,N,n;
192 
193   PetscFunctionBegin;
194   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
195   if (!cols) { /* nonzero rows */
196     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
197     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
198     ierr = VecSet(l,0.0);CHKERRQ(ierr);
199     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
200     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
201     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
202   } else { /* nonzero columns */
203     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
204     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
205     ierr = VecSet(r,0.0);CHKERRQ(ierr);
206     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
207     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
208     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
209   }
210   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
211   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
212   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRMPI(ierr);
213   if (gnz != N) {
214     PetscInt *nzr;
215     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
216     if (nz) {
217       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
218       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
219     }
220     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
221   } else *nonzero = NULL;
222   if (!cols) { /* nonzero rows */
223     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
224   } else {
225     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
226   }
227   ierr = VecDestroy(&l);CHKERRQ(ierr);
228   ierr = VecDestroy(&r);CHKERRQ(ierr);
229   PetscFunctionReturn(0);
230 }
231 
232 /*@
233       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
234 
235   Input Parameter:
236 .    A  - the matrix
237 
238   Output Parameter:
239 .    keptrows - the rows that are not completely zero
240 
241   Notes:
242     keptrows is set to NULL if all rows are nonzero.
243 
244   Level: intermediate
245 
246  @*/
247 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
248 {
249   PetscErrorCode ierr;
250 
251   PetscFunctionBegin;
252   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
253   PetscValidType(mat,1);
254   PetscValidPointer(keptrows,2);
255   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
256   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
257   if (!mat->ops->findnonzerorows) {
258     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
259   } else {
260     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
261   }
262   PetscFunctionReturn(0);
263 }
264 
265 /*@
266       MatFindZeroRows - Locate all rows that are completely zero in the matrix
267 
268   Input Parameter:
269 .    A  - the matrix
270 
271   Output Parameter:
272 .    zerorows - the rows that are completely zero
273 
274   Notes:
275     zerorows is set to NULL if no rows are zero.
276 
277   Level: intermediate
278 
279  @*/
280 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
281 {
282   PetscErrorCode ierr;
283   IS keptrows;
284   PetscInt m, n;
285 
286   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
287   PetscValidType(mat,1);
288 
289   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
290   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
291      In keeping with this convention, we set zerorows to NULL if there are no zero
292      rows. */
293   if (keptrows == NULL) {
294     *zerorows = NULL;
295   } else {
296     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
297     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
298     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
299   }
300   PetscFunctionReturn(0);
301 }
302 
303 /*@
304    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
305 
306    Not Collective
307 
308    Input Parameters:
309 .   A - the matrix
310 
311    Output Parameters:
312 .   a - the diagonal part (which is a SEQUENTIAL matrix)
313 
314    Notes:
315     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
316           Use caution, as the reference count on the returned matrix is not incremented and it is used as
317           part of the containing MPI Mat's normal operation.
318 
319    Level: advanced
320 
321 @*/
322 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
323 {
324   PetscErrorCode ierr;
325 
326   PetscFunctionBegin;
327   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
328   PetscValidType(A,1);
329   PetscValidPointer(a,2);
330   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
331   if (!A->ops->getdiagonalblock) {
332     PetscMPIInt size;
333     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRMPI(ierr);
334     if (size == 1) {
335       *a = A;
336       PetscFunctionReturn(0);
337     } else SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for matrix type %s",((PetscObject)A)->type_name);
338   }
339   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
340   PetscFunctionReturn(0);
341 }
342 
343 /*@
344    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
345 
346    Collective on Mat
347 
348    Input Parameters:
349 .  mat - the matrix
350 
351    Output Parameter:
352 .   trace - the sum of the diagonal entries
353 
354    Level: advanced
355 
356 @*/
357 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
358 {
359   PetscErrorCode ierr;
360   Vec            diag;
361 
362   PetscFunctionBegin;
363   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
364   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
365   ierr = VecSum(diag,trace);CHKERRQ(ierr);
366   ierr = VecDestroy(&diag);CHKERRQ(ierr);
367   PetscFunctionReturn(0);
368 }
369 
370 /*@
371    MatRealPart - Zeros out the imaginary part of the matrix
372 
373    Logically Collective on Mat
374 
375    Input Parameters:
376 .  mat - the matrix
377 
378    Level: advanced
379 
380 
381 .seealso: MatImaginaryPart()
382 @*/
383 PetscErrorCode MatRealPart(Mat mat)
384 {
385   PetscErrorCode ierr;
386 
387   PetscFunctionBegin;
388   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
389   PetscValidType(mat,1);
390   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
391   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
392   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
393   MatCheckPreallocated(mat,1);
394   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
395   PetscFunctionReturn(0);
396 }
397 
398 /*@C
399    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
400 
401    Collective on Mat
402 
403    Input Parameter:
404 .  mat - the matrix
405 
406    Output Parameters:
407 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
408 -   ghosts - the global indices of the ghost points
409 
410    Notes:
411     the nghosts and ghosts are suitable to pass into VecCreateGhost()
412 
413    Level: advanced
414 
415 @*/
416 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
417 {
418   PetscErrorCode ierr;
419 
420   PetscFunctionBegin;
421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
422   PetscValidType(mat,1);
423   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
424   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
425   if (!mat->ops->getghosts) {
426     if (nghosts) *nghosts = 0;
427     if (ghosts) *ghosts = NULL;
428   } else {
429     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
430   }
431   PetscFunctionReturn(0);
432 }
433 
434 
435 /*@
436    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
437 
438    Logically Collective on Mat
439 
440    Input Parameters:
441 .  mat - the matrix
442 
443    Level: advanced
444 
445 
446 .seealso: MatRealPart()
447 @*/
448 PetscErrorCode MatImaginaryPart(Mat mat)
449 {
450   PetscErrorCode ierr;
451 
452   PetscFunctionBegin;
453   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
454   PetscValidType(mat,1);
455   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
456   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
457   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
458   MatCheckPreallocated(mat,1);
459   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
460   PetscFunctionReturn(0);
461 }
462 
463 /*@
464    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
465 
466    Not Collective
467 
468    Input Parameter:
469 .  mat - the matrix
470 
471    Output Parameters:
472 +  missing - is any diagonal missing
473 -  dd - first diagonal entry that is missing (optional) on this process
474 
475    Level: advanced
476 
477 
478 .seealso: MatRealPart()
479 @*/
480 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
481 {
482   PetscErrorCode ierr;
483 
484   PetscFunctionBegin;
485   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
486   PetscValidType(mat,1);
487   PetscValidPointer(missing,2);
488   if (!mat->assembled) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name);
489   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
490   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
491   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
492   PetscFunctionReturn(0);
493 }
494 
495 /*@C
496    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
497    for each row that you get to ensure that your application does
498    not bleed memory.
499 
500    Not Collective
501 
502    Input Parameters:
503 +  mat - the matrix
504 -  row - the row to get
505 
506    Output Parameters:
507 +  ncols -  if not NULL, the number of nonzeros in the row
508 .  cols - if not NULL, the column numbers
509 -  vals - if not NULL, the values
510 
511    Notes:
512    This routine is provided for people who need to have direct access
513    to the structure of a matrix.  We hope that we provide enough
514    high-level matrix routines that few users will need it.
515 
516    MatGetRow() always returns 0-based column indices, regardless of
517    whether the internal representation is 0-based (default) or 1-based.
518 
519    For better efficiency, set cols and/or vals to NULL if you do
520    not wish to extract these quantities.
521 
522    The user can only examine the values extracted with MatGetRow();
523    the values cannot be altered.  To change the matrix entries, one
524    must use MatSetValues().
525 
526    You can only have one call to MatGetRow() outstanding for a particular
527    matrix at a time, per processor. MatGetRow() can only obtain rows
528    associated with the given processor, it cannot get rows from the
529    other processors; for that we suggest using MatCreateSubMatrices(), then
530    MatGetRow() on the submatrix. The row index passed to MatGetRow()
531    is in the global number of rows.
532 
533    Fortran Notes:
534    The calling sequence from Fortran is
535 .vb
536    MatGetRow(matrix,row,ncols,cols,values,ierr)
537          Mat     matrix (input)
538          integer row    (input)
539          integer ncols  (output)
540          integer cols(maxcols) (output)
541          double precision (or double complex) values(maxcols) output
542 .ve
543    where maxcols >= maximum nonzeros in any row of the matrix.
544 
545 
546    Caution:
547    Do not try to change the contents of the output arrays (cols and vals).
548    In some cases, this may corrupt the matrix.
549 
550    Level: advanced
551 
552 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
553 @*/
554 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
555 {
556   PetscErrorCode ierr;
557   PetscInt       incols;
558 
559   PetscFunctionBegin;
560   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
561   PetscValidType(mat,1);
562   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
563   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
564   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
565   MatCheckPreallocated(mat,1);
566   if (row < mat->rmap->rstart || row >= mat->rmap->rend) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %D not in [%D,%D)",row,mat->rmap->rstart,mat->rmap->rend);
567   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
568   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
569   if (ncols) *ncols = incols;
570   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
571   PetscFunctionReturn(0);
572 }
573 
574 /*@
575    MatConjugate - replaces the matrix values with their complex conjugates
576 
577    Logically Collective on Mat
578 
579    Input Parameters:
580 .  mat - the matrix
581 
582    Level: advanced
583 
584 .seealso:  VecConjugate()
585 @*/
586 PetscErrorCode MatConjugate(Mat mat)
587 {
588 #if defined(PETSC_USE_COMPLEX)
589   PetscErrorCode ierr;
590 
591   PetscFunctionBegin;
592   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
593   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
594   if (!mat->ops->conjugate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name);
595   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
596 #else
597   PetscFunctionBegin;
598 #endif
599   PetscFunctionReturn(0);
600 }
601 
602 /*@C
603    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
604 
605    Not Collective
606 
607    Input Parameters:
608 +  mat - the matrix
609 .  row - the row to get
610 .  ncols, cols - the number of nonzeros and their columns
611 -  vals - if nonzero the column values
612 
613    Notes:
614    This routine should be called after you have finished examining the entries.
615 
616    This routine zeros out ncols, cols, and vals. This is to prevent accidental
617    us of the array after it has been restored. If you pass NULL, it will
618    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
619 
620    Fortran Notes:
621    The calling sequence from Fortran is
622 .vb
623    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
624       Mat     matrix (input)
625       integer row    (input)
626       integer ncols  (output)
627       integer cols(maxcols) (output)
628       double precision (or double complex) values(maxcols) output
629 .ve
630    Where maxcols >= maximum nonzeros in any row of the matrix.
631 
632    In Fortran MatRestoreRow() MUST be called after MatGetRow()
633    before another call to MatGetRow() can be made.
634 
635    Level: advanced
636 
637 .seealso:  MatGetRow()
638 @*/
639 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
640 {
641   PetscErrorCode ierr;
642 
643   PetscFunctionBegin;
644   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
645   if (ncols) PetscValidIntPointer(ncols,3);
646   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
647   if (!mat->ops->restorerow) PetscFunctionReturn(0);
648   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
649   if (ncols) *ncols = 0;
650   if (cols)  *cols = NULL;
651   if (vals)  *vals = NULL;
652   PetscFunctionReturn(0);
653 }
654 
655 /*@
656    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
657    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
658 
659    Not Collective
660 
661    Input Parameters:
662 .  mat - the matrix
663 
664    Notes:
665    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.
666 
667    Level: advanced
668 
669 .seealso: MatRestoreRowUpperTriangular()
670 @*/
671 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
672 {
673   PetscErrorCode ierr;
674 
675   PetscFunctionBegin;
676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
677   PetscValidType(mat,1);
678   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
679   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
680   MatCheckPreallocated(mat,1);
681   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
682   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
683   PetscFunctionReturn(0);
684 }
685 
686 /*@
687    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
688 
689    Not Collective
690 
691    Input Parameters:
692 .  mat - the matrix
693 
694    Notes:
695    This routine should be called after you have finished MatGetRow/MatRestoreRow().
696 
697 
698    Level: advanced
699 
700 .seealso:  MatGetRowUpperTriangular()
701 @*/
702 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
703 {
704   PetscErrorCode ierr;
705 
706   PetscFunctionBegin;
707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
708   PetscValidType(mat,1);
709   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
710   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
711   MatCheckPreallocated(mat,1);
712   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
713   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
714   PetscFunctionReturn(0);
715 }
716 
717 /*@C
718    MatSetOptionsPrefix - Sets the prefix used for searching for all
719    Mat options in the database.
720 
721    Logically Collective on Mat
722 
723    Input Parameter:
724 +  A - the Mat context
725 -  prefix - the prefix to prepend to all option names
726 
727    Notes:
728    A hyphen (-) must NOT be given at the beginning of the prefix name.
729    The first character of all runtime options is AUTOMATICALLY the hyphen.
730 
731    Level: advanced
732 
733 .seealso: MatSetFromOptions()
734 @*/
735 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
736 {
737   PetscErrorCode ierr;
738 
739   PetscFunctionBegin;
740   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
741   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
742   PetscFunctionReturn(0);
743 }
744 
745 /*@C
746    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
747    Mat options in the database.
748 
749    Logically Collective on Mat
750 
751    Input Parameters:
752 +  A - the Mat context
753 -  prefix - the prefix to prepend to all option names
754 
755    Notes:
756    A hyphen (-) must NOT be given at the beginning of the prefix name.
757    The first character of all runtime options is AUTOMATICALLY the hyphen.
758 
759    Level: advanced
760 
761 .seealso: MatGetOptionsPrefix()
762 @*/
763 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
764 {
765   PetscErrorCode ierr;
766 
767   PetscFunctionBegin;
768   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
769   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
770   PetscFunctionReturn(0);
771 }
772 
773 /*@C
774    MatGetOptionsPrefix - Gets the prefix used for searching for all
775    Mat options in the database.
776 
777    Not Collective
778 
779    Input Parameter:
780 .  A - the Mat context
781 
782    Output Parameter:
783 .  prefix - pointer to the prefix string used
784 
785    Notes:
786     On the fortran side, the user should pass in a string 'prefix' of
787    sufficient length to hold the prefix.
788 
789    Level: advanced
790 
791 .seealso: MatAppendOptionsPrefix()
792 @*/
793 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
794 {
795   PetscErrorCode ierr;
796 
797   PetscFunctionBegin;
798   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
799   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
800   PetscFunctionReturn(0);
801 }
802 
803 /*@
804    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
805 
806    Collective on Mat
807 
808    Input Parameters:
809 .  A - the Mat context
810 
811    Notes:
812    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
813    Currently support MPIAIJ and SEQAIJ.
814 
815    Level: beginner
816 
817 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
818 @*/
819 PetscErrorCode MatResetPreallocation(Mat A)
820 {
821   PetscErrorCode ierr;
822 
823   PetscFunctionBegin;
824   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
825   PetscValidType(A,1);
826   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
827   PetscFunctionReturn(0);
828 }
829 
830 
831 /*@
832    MatSetUp - Sets up the internal matrix data structures for later use.
833 
834    Collective on Mat
835 
836    Input Parameters:
837 .  A - the Mat context
838 
839    Notes:
840    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
841 
842    If a suitable preallocation routine is used, this function does not need to be called.
843 
844    See the Performance chapter of the PETSc users manual for how to preallocate matrices
845 
846    Level: beginner
847 
848 .seealso: MatCreate(), MatDestroy()
849 @*/
850 PetscErrorCode MatSetUp(Mat A)
851 {
852   PetscMPIInt    size;
853   PetscErrorCode ierr;
854 
855   PetscFunctionBegin;
856   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
857   if (!((PetscObject)A)->type_name) {
858     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRMPI(ierr);
859     if (size == 1) {
860       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
861     } else {
862       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
863     }
864   }
865   if (!A->preallocated && A->ops->setup) {
866     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
867     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
868   }
869   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
870   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
871   A->preallocated = PETSC_TRUE;
872   PetscFunctionReturn(0);
873 }
874 
875 #if defined(PETSC_HAVE_SAWS)
876 #include <petscviewersaws.h>
877 #endif
878 
879 /*@C
880    MatViewFromOptions - View from Options
881 
882    Collective on Mat
883 
884    Input Parameters:
885 +  A - the Mat context
886 .  obj - Optional object
887 -  name - command line option
888 
889    Level: intermediate
890 .seealso:  Mat, MatView, PetscObjectViewFromOptions(), MatCreate()
891 @*/
892 PetscErrorCode  MatViewFromOptions(Mat A,PetscObject obj,const char name[])
893 {
894   PetscErrorCode ierr;
895 
896   PetscFunctionBegin;
897   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
898   ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr);
899   PetscFunctionReturn(0);
900 }
901 
902 /*@C
903    MatView - Visualizes a matrix object.
904 
905    Collective on Mat
906 
907    Input Parameters:
908 +  mat - the matrix
909 -  viewer - visualization context
910 
911   Notes:
912   The available visualization contexts include
913 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
914 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
915 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
916 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
917 
918    The user can open alternative visualization contexts with
919 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
920 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
921          specified file; corresponding input uses MatLoad()
922 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
923          an X window display
924 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
925          Currently only the sequential dense and AIJ
926          matrix types support the Socket viewer.
927 
928    The user can call PetscViewerPushFormat() to specify the output
929    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
930    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
931 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
932 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
933 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
934 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
935          format common among all matrix types
936 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
937          format (which is in many cases the same as the default)
938 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
939          size and structure (not the matrix entries)
940 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
941          the matrix structure
942 
943    Options Database Keys:
944 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
945 .  -mat_view ::ascii_info_detail - Prints more detailed info
946 .  -mat_view - Prints matrix in ASCII format
947 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
948 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
949 .  -display <name> - Sets display name (default is host)
950 .  -draw_pause <sec> - Sets number of seconds to pause after display
951 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
952 .  -viewer_socket_machine <machine> -
953 .  -viewer_socket_port <port> -
954 .  -mat_view binary - save matrix to file in binary format
955 -  -viewer_binary_filename <name> -
956    Level: beginner
957 
958    Notes:
959     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
960     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
961 
962     In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer).
963 
964     See the manual page for MatLoad() for the exact format of the binary file when the binary
965       viewer is used.
966 
967       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
968       viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python.
969 
970       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
971       and then use the following mouse functions.
972 + left mouse: zoom in
973 . middle mouse: zoom out
974 - right mouse: continue with the simulation
975 
976 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
977           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
978 @*/
979 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
980 {
981   PetscErrorCode    ierr;
982   PetscInt          rows,cols,rbs,cbs;
983   PetscBool         isascii,isstring,issaws;
984   PetscViewerFormat format;
985   PetscMPIInt       size;
986 
987   PetscFunctionBegin;
988   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
989   PetscValidType(mat,1);
990   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);}
991   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
992   PetscCheckSameComm(mat,1,viewer,2);
993   MatCheckPreallocated(mat,1);
994 
995   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
996   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
997   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
998 
999   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1000   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
1001   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1002   if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1003     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail");
1004   }
1005 
1006   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1007   if (isascii) {
1008     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1009     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1010     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1011       MatNullSpace nullsp,transnullsp;
1012 
1013       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1014       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1015       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1016       if (rbs != 1 || cbs != 1) {
1017         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1018         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1019       } else {
1020         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1021       }
1022       if (mat->factortype) {
1023         MatSolverType solver;
1024         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1025         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1026       }
1027       if (mat->ops->getinfo) {
1028         MatInfo info;
1029         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1030         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1031         if (!mat->factortype) {
1032           ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1033         }
1034       }
1035       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1036       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1037       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1038       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1039       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1040       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1041       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1042       ierr = MatProductView(mat,viewer);CHKERRQ(ierr);
1043       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1044     }
1045   } else if (issaws) {
1046 #if defined(PETSC_HAVE_SAWS)
1047     PetscMPIInt rank;
1048 
1049     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1050     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
1051     if (!((PetscObject)mat)->amsmem && !rank) {
1052       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1053     }
1054 #endif
1055   } else if (isstring) {
1056     const char *type;
1057     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1058     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1059     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1060   }
1061   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1062     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1063     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1064     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1065   } else if (mat->ops->view) {
1066     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1067     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1068     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1069   }
1070   if (isascii) {
1071     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1072     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1073       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1074     }
1075   }
1076   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1077   PetscFunctionReturn(0);
1078 }
1079 
1080 #if defined(PETSC_USE_DEBUG)
1081 #include <../src/sys/totalview/tv_data_display.h>
1082 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1083 {
1084   TV_add_row("Local rows", "int", &mat->rmap->n);
1085   TV_add_row("Local columns", "int", &mat->cmap->n);
1086   TV_add_row("Global rows", "int", &mat->rmap->N);
1087   TV_add_row("Global columns", "int", &mat->cmap->N);
1088   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1089   return TV_format_OK;
1090 }
1091 #endif
1092 
1093 /*@C
1094    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1095    with MatView().  The matrix format is determined from the options database.
1096    Generates a parallel MPI matrix if the communicator has more than one
1097    processor.  The default matrix type is AIJ.
1098 
1099    Collective on PetscViewer
1100 
1101    Input Parameters:
1102 +  mat - the newly loaded matrix, this needs to have been created with MatCreate()
1103             or some related function before a call to MatLoad()
1104 -  viewer - binary/HDF5 file viewer
1105 
1106    Options Database Keys:
1107    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1108    block size
1109 .    -matload_block_size <bs>
1110 
1111    Level: beginner
1112 
1113    Notes:
1114    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1115    Mat before calling this routine if you wish to set it from the options database.
1116 
1117    MatLoad() automatically loads into the options database any options
1118    given in the file filename.info where filename is the name of the file
1119    that was passed to the PetscViewerBinaryOpen(). The options in the info
1120    file will be ignored if you use the -viewer_binary_skip_info option.
1121 
1122    If the type or size of mat is not set before a call to MatLoad, PETSc
1123    sets the default matrix type AIJ and sets the local and global sizes.
1124    If type and/or size is already set, then the same are used.
1125 
1126    In parallel, each processor can load a subset of rows (or the
1127    entire matrix).  This routine is especially useful when a large
1128    matrix is stored on disk and only part of it is desired on each
1129    processor.  For example, a parallel solver may access only some of
1130    the rows from each processor.  The algorithm used here reads
1131    relatively small blocks of data rather than reading the entire
1132    matrix and then subsetting it.
1133 
1134    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1135    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1136    or the sequence like
1137 $    PetscViewer v;
1138 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1139 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1140 $    PetscViewerSetFromOptions(v);
1141 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1142 $    PetscViewerFileSetName(v,"datafile");
1143    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1144 $ -viewer_type {binary,hdf5}
1145 
1146    See the example src/ksp/ksp/tutorials/ex27.c with the first approach,
1147    and src/mat/tutorials/ex10.c with the second approach.
1148 
1149    Notes about the PETSc binary format:
1150    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1151    is read onto rank 0 and then shipped to its destination rank, one after another.
1152    Multiple objects, both matrices and vectors, can be stored within the same file.
1153    Their PetscObject name is ignored; they are loaded in the order of their storage.
1154 
1155    Most users should not need to know the details of the binary storage
1156    format, since MatLoad() and MatView() completely hide these details.
1157    But for anyone who's interested, the standard binary matrix storage
1158    format is
1159 
1160 $    PetscInt    MAT_FILE_CLASSID
1161 $    PetscInt    number of rows
1162 $    PetscInt    number of columns
1163 $    PetscInt    total number of nonzeros
1164 $    PetscInt    *number nonzeros in each row
1165 $    PetscInt    *column indices of all nonzeros (starting index is zero)
1166 $    PetscScalar *values of all nonzeros
1167 
1168    PETSc automatically does the byte swapping for
1169 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1170 linux, Windows and the paragon; thus if you write your own binary
1171 read/write routines you have to swap the bytes; see PetscBinaryRead()
1172 and PetscBinaryWrite() to see how this may be done.
1173 
1174    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1175    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1176    Each processor's chunk is loaded independently by its owning rank.
1177    Multiple objects, both matrices and vectors, can be stored within the same file.
1178    They are looked up by their PetscObject name.
1179 
1180    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1181    by default the same structure and naming of the AIJ arrays and column count
1182    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1183 $    save example.mat A b -v7.3
1184    can be directly read by this routine (see Reference 1 for details).
1185    Note that depending on your MATLAB version, this format might be a default,
1186    otherwise you can set it as default in Preferences.
1187 
1188    Unless -nocompression flag is used to save the file in MATLAB,
1189    PETSc must be configured with ZLIB package.
1190 
1191    See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c
1192 
1193    Current HDF5 (MAT-File) limitations:
1194    This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices.
1195 
1196    Corresponding MatView() is not yet implemented.
1197 
1198    The loaded matrix is actually a transpose of the original one in MATLAB,
1199    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1200    With this format, matrix is automatically transposed by PETSc,
1201    unless the matrix is marked as SPD or symmetric
1202    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1203 
1204    References:
1205 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1206 
1207 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1208 
1209  @*/
1210 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer)
1211 {
1212   PetscErrorCode ierr;
1213   PetscBool      flg;
1214 
1215   PetscFunctionBegin;
1216   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1217   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1218 
1219   if (!((PetscObject)mat)->type_name) {
1220     ierr = MatSetType(mat,MATAIJ);CHKERRQ(ierr);
1221   }
1222 
1223   flg  = PETSC_FALSE;
1224   ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1225   if (flg) {
1226     ierr = MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1227     ierr = MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1228   }
1229   flg  = PETSC_FALSE;
1230   ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1231   if (flg) {
1232     ierr = MatSetOption(mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1233   }
1234 
1235   if (!mat->ops->load) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name);
1236   ierr = PetscLogEventBegin(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr);
1237   ierr = (*mat->ops->load)(mat,viewer);CHKERRQ(ierr);
1238   ierr = PetscLogEventEnd(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr);
1239   PetscFunctionReturn(0);
1240 }
1241 
1242 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1243 {
1244   PetscErrorCode ierr;
1245   Mat_Redundant  *redund = *redundant;
1246   PetscInt       i;
1247 
1248   PetscFunctionBegin;
1249   if (redund){
1250     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1251       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1252       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1253       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1254     } else {
1255       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1256       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1257       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1258       for (i=0; i<redund->nrecvs; i++) {
1259         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1260         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1261       }
1262       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1263     }
1264 
1265     if (redund->subcomm) {
1266       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1267     }
1268     ierr = PetscFree(redund);CHKERRQ(ierr);
1269   }
1270   PetscFunctionReturn(0);
1271 }
1272 
1273 /*@C
1274    MatDestroy - Frees space taken by a matrix.
1275 
1276    Collective on Mat
1277 
1278    Input Parameter:
1279 .  A - the matrix
1280 
1281    Level: beginner
1282 
1283 @*/
1284 PetscErrorCode MatDestroy(Mat *A)
1285 {
1286   PetscErrorCode ierr;
1287 
1288   PetscFunctionBegin;
1289   if (!*A) PetscFunctionReturn(0);
1290   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1291   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1292 
1293   /* if memory was published with SAWs then destroy it */
1294   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1295   if ((*A)->ops->destroy) {
1296     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1297   }
1298 
1299   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1300   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1301   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1302   for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) {
1303     ierr = PetscFree((*A)->preferredordering[i]);CHKERRQ(ierr);
1304   }
1305   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1306   ierr = MatProductClear(*A);CHKERRQ(ierr);
1307   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1308   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1309   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1310   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1311   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1312   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1313   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1314   PetscFunctionReturn(0);
1315 }
1316 
1317 /*@C
1318    MatSetValues - Inserts or adds a block of values into a matrix.
1319    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1320    MUST be called after all calls to MatSetValues() have been completed.
1321 
1322    Not Collective
1323 
1324    Input Parameters:
1325 +  mat - the matrix
1326 .  v - a logically two-dimensional array of values
1327 .  m, idxm - the number of rows and their global indices
1328 .  n, idxn - the number of columns and their global indices
1329 -  addv - either ADD_VALUES or INSERT_VALUES, where
1330    ADD_VALUES adds values to any existing entries, and
1331    INSERT_VALUES replaces existing entries with new values
1332 
1333    Notes:
1334    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1335       MatSetUp() before using this routine
1336 
1337    By default the values, v, are row-oriented. See MatSetOption() for other options.
1338 
1339    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1340    options cannot be mixed without intervening calls to the assembly
1341    routines.
1342 
1343    MatSetValues() uses 0-based row and column numbers in Fortran
1344    as well as in C.
1345 
1346    Negative indices may be passed in idxm and idxn, these rows and columns are
1347    simply ignored. This allows easily inserting element stiffness matrices
1348    with homogeneous Dirchlet boundary conditions that you don't want represented
1349    in the matrix.
1350 
1351    Efficiency Alert:
1352    The routine MatSetValuesBlocked() may offer much better efficiency
1353    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1354 
1355    Level: beginner
1356 
1357    Developer Notes:
1358     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1359                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1360 
1361 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1362           InsertMode, INSERT_VALUES, ADD_VALUES
1363 @*/
1364 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1365 {
1366   PetscErrorCode ierr;
1367 
1368   PetscFunctionBeginHot;
1369   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1370   PetscValidType(mat,1);
1371   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1372   PetscValidIntPointer(idxm,3);
1373   PetscValidIntPointer(idxn,5);
1374   MatCheckPreallocated(mat,1);
1375 
1376   if (mat->insertmode == NOT_SET_VALUES) {
1377     mat->insertmode = addv;
1378   } else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1379   if (PetscDefined(USE_DEBUG)) {
1380     PetscInt       i,j;
1381 
1382     if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1383     if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1384 
1385     for (i=0; i<m; i++) {
1386       for (j=0; j<n; j++) {
1387         if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1388 #if defined(PETSC_USE_COMPLEX)
1389           SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1390 #else
1391           SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1392 #endif
1393       }
1394     }
1395     for (i=0; i<m; i++) if (idxm[i] >= mat->rmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %D, maximum is %D",idxm[i],mat->rmap->N-1);
1396     for (i=0; i<n; i++) if (idxn[i] >= mat->cmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %D, maximum is %D",idxn[i],mat->cmap->N-1);
1397   }
1398 
1399   if (mat->assembled) {
1400     mat->was_assembled = PETSC_TRUE;
1401     mat->assembled     = PETSC_FALSE;
1402   }
1403   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1404   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1405   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1406   PetscFunctionReturn(0);
1407 }
1408 
1409 
1410 /*@
1411    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1412         values into a matrix
1413 
1414    Not Collective
1415 
1416    Input Parameters:
1417 +  mat - the matrix
1418 .  row - the (block) row to set
1419 -  v - a logically two-dimensional array of values
1420 
1421    Notes:
1422    By the values, v, are column-oriented (for the block version) and sorted
1423 
1424    All the nonzeros in the row must be provided
1425 
1426    The matrix must have previously had its column indices set
1427 
1428    The row must belong to this process
1429 
1430    Level: intermediate
1431 
1432 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1433           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1434 @*/
1435 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1436 {
1437   PetscErrorCode ierr;
1438   PetscInt       globalrow;
1439 
1440   PetscFunctionBegin;
1441   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1442   PetscValidType(mat,1);
1443   PetscValidScalarPointer(v,3);
1444   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1445   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1446   PetscFunctionReturn(0);
1447 }
1448 
1449 /*@
1450    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1451         values into a matrix
1452 
1453    Not Collective
1454 
1455    Input Parameters:
1456 +  mat - the matrix
1457 .  row - the (block) row to set
1458 -  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
1459 
1460    Notes:
1461    The values, v, are column-oriented for the block version.
1462 
1463    All the nonzeros in the row must be provided
1464 
1465    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1466 
1467    The row must belong to this process
1468 
1469    Level: advanced
1470 
1471 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1472           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1473 @*/
1474 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1475 {
1476   PetscErrorCode ierr;
1477 
1478   PetscFunctionBeginHot;
1479   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1480   PetscValidType(mat,1);
1481   MatCheckPreallocated(mat,1);
1482   PetscValidScalarPointer(v,3);
1483   if (PetscUnlikely(mat->insertmode == ADD_VALUES)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1484   if (PetscUnlikely(mat->factortype)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1485   mat->insertmode = INSERT_VALUES;
1486 
1487   if (mat->assembled) {
1488     mat->was_assembled = PETSC_TRUE;
1489     mat->assembled     = PETSC_FALSE;
1490   }
1491   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1492   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1493   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1494   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1495   PetscFunctionReturn(0);
1496 }
1497 
1498 /*@
1499    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1500      Using structured grid indexing
1501 
1502    Not Collective
1503 
1504    Input Parameters:
1505 +  mat - the matrix
1506 .  m - number of rows being entered
1507 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1508 .  n - number of columns being entered
1509 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1510 .  v - a logically two-dimensional array of values
1511 -  addv - either ADD_VALUES or INSERT_VALUES, where
1512    ADD_VALUES adds values to any existing entries, and
1513    INSERT_VALUES replaces existing entries with new values
1514 
1515    Notes:
1516    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1517 
1518    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1519    options cannot be mixed without intervening calls to the assembly
1520    routines.
1521 
1522    The grid coordinates are across the entire grid, not just the local portion
1523 
1524    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1525    as well as in C.
1526 
1527    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1528 
1529    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1530    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1531 
1532    The columns and rows in the stencil passed in MUST be contained within the
1533    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1534    if you create a DMDA with an overlap of one grid level and on a particular process its first
1535    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1536    first i index you can use in your column and row indices in MatSetStencil() is 5.
1537 
1538    In Fortran idxm and idxn should be declared as
1539 $     MatStencil idxm(4,m),idxn(4,n)
1540    and the values inserted using
1541 $    idxm(MatStencil_i,1) = i
1542 $    idxm(MatStencil_j,1) = j
1543 $    idxm(MatStencil_k,1) = k
1544 $    idxm(MatStencil_c,1) = c
1545    etc
1546 
1547    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1548    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1549    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1550    DM_BOUNDARY_PERIODIC boundary type.
1551 
1552    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
1553    a single value per point) you can skip filling those indices.
1554 
1555    Inspired by the structured grid interface to the HYPRE package
1556    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1557 
1558    Efficiency Alert:
1559    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1560    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1561 
1562    Level: beginner
1563 
1564 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1565           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1566 @*/
1567 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1568 {
1569   PetscErrorCode ierr;
1570   PetscInt       buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn;
1571   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1572   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1573 
1574   PetscFunctionBegin;
1575   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1576   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1577   PetscValidType(mat,1);
1578   PetscValidPointer(idxm,3);
1579   PetscValidPointer(idxn,5);
1580 
1581   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1582     jdxm = buf; jdxn = buf+m;
1583   } else {
1584     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1585     jdxm = bufm; jdxn = bufn;
1586   }
1587   for (i=0; i<m; i++) {
1588     for (j=0; j<3-sdim; j++) dxm++;
1589     tmp = *dxm++ - starts[0];
1590     for (j=0; j<dim-1; j++) {
1591       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1592       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1593     }
1594     if (mat->stencil.noc) dxm++;
1595     jdxm[i] = tmp;
1596   }
1597   for (i=0; i<n; i++) {
1598     for (j=0; j<3-sdim; j++) dxn++;
1599     tmp = *dxn++ - starts[0];
1600     for (j=0; j<dim-1; j++) {
1601       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1602       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1603     }
1604     if (mat->stencil.noc) dxn++;
1605     jdxn[i] = tmp;
1606   }
1607   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1608   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1609   PetscFunctionReturn(0);
1610 }
1611 
1612 /*@
1613    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1614      Using structured grid indexing
1615 
1616    Not Collective
1617 
1618    Input Parameters:
1619 +  mat - the matrix
1620 .  m - number of rows being entered
1621 .  idxm - grid coordinates for matrix rows being entered
1622 .  n - number of columns being entered
1623 .  idxn - grid coordinates for matrix columns being entered
1624 .  v - a logically two-dimensional array of values
1625 -  addv - either ADD_VALUES or INSERT_VALUES, where
1626    ADD_VALUES adds values to any existing entries, and
1627    INSERT_VALUES replaces existing entries with new values
1628 
1629    Notes:
1630    By default the values, v, are row-oriented and unsorted.
1631    See MatSetOption() for other options.
1632 
1633    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1634    options cannot be mixed without intervening calls to the assembly
1635    routines.
1636 
1637    The grid coordinates are across the entire grid, not just the local portion
1638 
1639    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1640    as well as in C.
1641 
1642    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1643 
1644    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1645    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1646 
1647    The columns and rows in the stencil passed in MUST be contained within the
1648    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1649    if you create a DMDA with an overlap of one grid level and on a particular process its first
1650    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1651    first i index you can use in your column and row indices in MatSetStencil() is 5.
1652 
1653    In Fortran idxm and idxn should be declared as
1654 $     MatStencil idxm(4,m),idxn(4,n)
1655    and the values inserted using
1656 $    idxm(MatStencil_i,1) = i
1657 $    idxm(MatStencil_j,1) = j
1658 $    idxm(MatStencil_k,1) = k
1659    etc
1660 
1661    Negative indices may be passed in idxm and idxn, these rows and columns are
1662    simply ignored. This allows easily inserting element stiffness matrices
1663    with homogeneous Dirchlet boundary conditions that you don't want represented
1664    in the matrix.
1665 
1666    Inspired by the structured grid interface to the HYPRE package
1667    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1668 
1669    Level: beginner
1670 
1671 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1672           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1673           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1674 @*/
1675 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1676 {
1677   PetscErrorCode ierr;
1678   PetscInt       buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn;
1679   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1680   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1681 
1682   PetscFunctionBegin;
1683   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1684   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1685   PetscValidType(mat,1);
1686   PetscValidPointer(idxm,3);
1687   PetscValidPointer(idxn,5);
1688   PetscValidScalarPointer(v,6);
1689 
1690   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1691     jdxm = buf; jdxn = buf+m;
1692   } else {
1693     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1694     jdxm = bufm; jdxn = bufn;
1695   }
1696   for (i=0; i<m; i++) {
1697     for (j=0; j<3-sdim; j++) dxm++;
1698     tmp = *dxm++ - starts[0];
1699     for (j=0; j<sdim-1; j++) {
1700       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1701       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1702     }
1703     dxm++;
1704     jdxm[i] = tmp;
1705   }
1706   for (i=0; i<n; i++) {
1707     for (j=0; j<3-sdim; j++) dxn++;
1708     tmp = *dxn++ - starts[0];
1709     for (j=0; j<sdim-1; j++) {
1710       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1711       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1712     }
1713     dxn++;
1714     jdxn[i] = tmp;
1715   }
1716   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1717   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1718   PetscFunctionReturn(0);
1719 }
1720 
1721 /*@
1722    MatSetStencil - Sets the grid information for setting values into a matrix via
1723         MatSetValuesStencil()
1724 
1725    Not Collective
1726 
1727    Input Parameters:
1728 +  mat - the matrix
1729 .  dim - dimension of the grid 1, 2, or 3
1730 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1731 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1732 -  dof - number of degrees of freedom per node
1733 
1734 
1735    Inspired by the structured grid interface to the HYPRE package
1736    (www.llnl.gov/CASC/hyper)
1737 
1738    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1739    user.
1740 
1741    Level: beginner
1742 
1743 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1744           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1745 @*/
1746 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1747 {
1748   PetscInt i;
1749 
1750   PetscFunctionBegin;
1751   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1752   PetscValidIntPointer(dims,3);
1753   PetscValidIntPointer(starts,4);
1754 
1755   mat->stencil.dim = dim + (dof > 1);
1756   for (i=0; i<dim; i++) {
1757     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1758     mat->stencil.starts[i] = starts[dim-i-1];
1759   }
1760   mat->stencil.dims[dim]   = dof;
1761   mat->stencil.starts[dim] = 0;
1762   mat->stencil.noc         = (PetscBool)(dof == 1);
1763   PetscFunctionReturn(0);
1764 }
1765 
1766 /*@C
1767    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1768 
1769    Not Collective
1770 
1771    Input Parameters:
1772 +  mat - the matrix
1773 .  v - a logically two-dimensional array of values
1774 .  m, idxm - the number of block rows and their global block indices
1775 .  n, idxn - the number of block columns and their global block indices
1776 -  addv - either ADD_VALUES or INSERT_VALUES, where
1777    ADD_VALUES adds values to any existing entries, and
1778    INSERT_VALUES replaces existing entries with new values
1779 
1780    Notes:
1781    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1782    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1783 
1784    The m and n count the NUMBER of blocks in the row direction and column direction,
1785    NOT the total number of rows/columns; for example, if the block size is 2 and
1786    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1787    The values in idxm would be 1 2; that is the first index for each block divided by
1788    the block size.
1789 
1790    Note that you must call MatSetBlockSize() when constructing this matrix (before
1791    preallocating it).
1792 
1793    By default the values, v, are row-oriented, so the layout of
1794    v is the same as for MatSetValues(). See MatSetOption() for other options.
1795 
1796    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1797    options cannot be mixed without intervening calls to the assembly
1798    routines.
1799 
1800    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1801    as well as in C.
1802 
1803    Negative indices may be passed in idxm and idxn, these rows and columns are
1804    simply ignored. This allows easily inserting element stiffness matrices
1805    with homogeneous Dirchlet boundary conditions that you don't want represented
1806    in the matrix.
1807 
1808    Each time an entry is set within a sparse matrix via MatSetValues(),
1809    internal searching must be done to determine where to place the
1810    data in the matrix storage space.  By instead inserting blocks of
1811    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1812    reduced.
1813 
1814    Example:
1815 $   Suppose m=n=2 and block size(bs) = 2 The array is
1816 $
1817 $   1  2  | 3  4
1818 $   5  6  | 7  8
1819 $   - - - | - - -
1820 $   9  10 | 11 12
1821 $   13 14 | 15 16
1822 $
1823 $   v[] should be passed in like
1824 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1825 $
1826 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1827 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1828 
1829    Level: intermediate
1830 
1831 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1832 @*/
1833 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1834 {
1835   PetscErrorCode ierr;
1836 
1837   PetscFunctionBeginHot;
1838   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1839   PetscValidType(mat,1);
1840   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1841   PetscValidIntPointer(idxm,3);
1842   PetscValidIntPointer(idxn,5);
1843   PetscValidScalarPointer(v,6);
1844   MatCheckPreallocated(mat,1);
1845   if (mat->insertmode == NOT_SET_VALUES) {
1846     mat->insertmode = addv;
1847   } else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1848   if (PetscDefined(USE_DEBUG)) {
1849     if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1850     if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1851   }
1852   if (PetscDefined(USE_DEBUG)) {
1853     PetscInt rbs,cbs,M,N,i;
1854     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1855     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
1856     for (i=0; i<m; i++) {
1857       if (idxm[i]*rbs >= M) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %D (index %D) greater than row length %D",i,idxm[i],M);
1858     }
1859     for (i=0; i<n; i++) {
1860       if (idxn[i]*cbs >= N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %D (index %D) great than column length %D",i,idxn[i],N);
1861     }
1862   }
1863   if (mat->assembled) {
1864     mat->was_assembled = PETSC_TRUE;
1865     mat->assembled     = PETSC_FALSE;
1866   }
1867   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1868   if (mat->ops->setvaluesblocked) {
1869     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1870   } else {
1871     PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn;
1872     PetscInt i,j,bs,cbs;
1873     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1874     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1875       iidxm = buf; iidxn = buf + m*bs;
1876     } else {
1877       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1878       iidxm = bufr; iidxn = bufc;
1879     }
1880     for (i=0; i<m; i++) {
1881       for (j=0; j<bs; j++) {
1882         iidxm[i*bs+j] = bs*idxm[i] + j;
1883       }
1884     }
1885     for (i=0; i<n; i++) {
1886       for (j=0; j<cbs; j++) {
1887         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1888       }
1889     }
1890     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1891     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1892   }
1893   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1894   PetscFunctionReturn(0);
1895 }
1896 
1897 /*@C
1898    MatGetValues - Gets a block of values from a matrix.
1899 
1900    Not Collective; can only return values that are owned by the give process
1901 
1902    Input Parameters:
1903 +  mat - the matrix
1904 .  v - a logically two-dimensional array for storing the values
1905 .  m, idxm - the number of rows and their global indices
1906 -  n, idxn - the number of columns and their global indices
1907 
1908    Notes:
1909      The user must allocate space (m*n PetscScalars) for the values, v.
1910      The values, v, are then returned in a row-oriented format,
1911      analogous to that used by default in MatSetValues().
1912 
1913      MatGetValues() uses 0-based row and column numbers in
1914      Fortran as well as in C.
1915 
1916      MatGetValues() requires that the matrix has been assembled
1917      with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1918      MatSetValues() and MatGetValues() CANNOT be made in succession
1919      without intermediate matrix assembly.
1920 
1921      Negative row or column indices will be ignored and those locations in v[] will be
1922      left unchanged.
1923 
1924      For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank.
1925      That is, rows with global index greater than or equal to restart and less than rend where restart and rend are obtainable
1926      from MatGetOwnershipRange(mat,&rstart,&rend).
1927 
1928    Level: advanced
1929 
1930 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues(), MatGetOwnershipRange(), MatGetValuesLocal()
1931 @*/
1932 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1933 {
1934   PetscErrorCode ierr;
1935 
1936   PetscFunctionBegin;
1937   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1938   PetscValidType(mat,1);
1939   if (!m || !n) PetscFunctionReturn(0);
1940   PetscValidIntPointer(idxm,3);
1941   PetscValidIntPointer(idxn,5);
1942   PetscValidScalarPointer(v,6);
1943   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1944   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1945   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1946   MatCheckPreallocated(mat,1);
1947 
1948   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1949   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1950   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1951   PetscFunctionReturn(0);
1952 }
1953 
1954 /*@C
1955    MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices
1956      defined previously by MatSetLocalToGlobalMapping()
1957 
1958    Not Collective
1959 
1960    Input Parameters:
1961 +  mat - the matrix
1962 .  nrow, irow - number of rows and their local indices
1963 -  ncol, icol - number of columns and their local indices
1964 
1965    Output Parameter:
1966 .  y -  a logically two-dimensional array of values
1967 
1968    Notes:
1969      If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine.
1970 
1971      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,
1972      are greater than or equal to restart and less than rend where restart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can
1973      determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set
1974      with MatSetLocalToGlobalMapping().
1975 
1976    Developer Notes:
1977       This is labelled with C so does not automatically generate Fortran stubs and interfaces
1978       because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1979 
1980    Level: advanced
1981 
1982 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1983            MatSetValuesLocal(), MatGetValues()
1984 @*/
1985 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[])
1986 {
1987   PetscErrorCode ierr;
1988 
1989   PetscFunctionBeginHot;
1990   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1991   PetscValidType(mat,1);
1992   MatCheckPreallocated(mat,1);
1993   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */
1994   PetscValidIntPointer(irow,3);
1995   PetscValidIntPointer(icol,5);
1996   if (PetscDefined(USE_DEBUG)) {
1997     if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1998     if (!mat->ops->getvalueslocal && !mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1999   }
2000   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2001   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
2002   if (mat->ops->getvalueslocal) {
2003     ierr = (*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y);CHKERRQ(ierr);
2004   } else {
2005     PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm;
2006     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2007       irowm = buf; icolm = buf+nrow;
2008     } else {
2009       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2010       irowm = bufr; icolm = bufc;
2011     }
2012     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
2013     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
2014     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2015     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2016     ierr = MatGetValues(mat,nrow,irowm,ncol,icolm,y);CHKERRQ(ierr);
2017     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2018   }
2019   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
2020   PetscFunctionReturn(0);
2021 }
2022 
2023 /*@
2024   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
2025   the same size. Currently, this can only be called once and creates the given matrix.
2026 
2027   Not Collective
2028 
2029   Input Parameters:
2030 + mat - the matrix
2031 . nb - the number of blocks
2032 . bs - the number of rows (and columns) in each block
2033 . rows - a concatenation of the rows for each block
2034 - v - a concatenation of logically two-dimensional arrays of values
2035 
2036   Notes:
2037   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2038 
2039   Level: advanced
2040 
2041 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2042           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2043 @*/
2044 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2045 {
2046   PetscErrorCode ierr;
2047 
2048   PetscFunctionBegin;
2049   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2050   PetscValidType(mat,1);
2051   PetscValidIntPointer(rows,4);
2052   PetscValidScalarPointer(v,5);
2053   if (PetscUnlikelyDebug(mat->factortype)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2054 
2055   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2056   if (mat->ops->setvaluesbatch) {
2057     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2058   } else {
2059     PetscInt b;
2060     for (b = 0; b < nb; ++b) {
2061       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2062     }
2063   }
2064   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2065   PetscFunctionReturn(0);
2066 }
2067 
2068 /*@
2069    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2070    the routine MatSetValuesLocal() to allow users to insert matrix entries
2071    using a local (per-processor) numbering.
2072 
2073    Not Collective
2074 
2075    Input Parameters:
2076 +  x - the matrix
2077 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2078 - cmapping - column mapping
2079 
2080    Level: intermediate
2081 
2082 
2083 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal(), MatGetValuesLocal()
2084 @*/
2085 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2086 {
2087   PetscErrorCode ierr;
2088 
2089   PetscFunctionBegin;
2090   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2091   PetscValidType(x,1);
2092   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2093   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2094 
2095   if (x->ops->setlocaltoglobalmapping) {
2096     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2097   } else {
2098     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2099     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2100   }
2101   PetscFunctionReturn(0);
2102 }
2103 
2104 
2105 /*@
2106    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2107 
2108    Not Collective
2109 
2110    Input Parameters:
2111 .  A - the matrix
2112 
2113    Output Parameters:
2114 + rmapping - row mapping
2115 - cmapping - column mapping
2116 
2117    Level: advanced
2118 
2119 
2120 .seealso:  MatSetValuesLocal()
2121 @*/
2122 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2123 {
2124   PetscFunctionBegin;
2125   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2126   PetscValidType(A,1);
2127   if (rmapping) PetscValidPointer(rmapping,2);
2128   if (cmapping) PetscValidPointer(cmapping,3);
2129   if (rmapping) *rmapping = A->rmap->mapping;
2130   if (cmapping) *cmapping = A->cmap->mapping;
2131   PetscFunctionReturn(0);
2132 }
2133 
2134 /*@
2135    MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix
2136 
2137    Logically Collective on A
2138 
2139    Input Parameters:
2140 +  A - the matrix
2141 . rmap - row layout
2142 - cmap - column layout
2143 
2144    Level: advanced
2145 
2146 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping(), MatGetLayouts()
2147 @*/
2148 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap)
2149 {
2150   PetscErrorCode ierr;
2151 
2152   PetscFunctionBegin;
2153   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2154 
2155   ierr = PetscLayoutReference(rmap,&A->rmap);CHKERRQ(ierr);
2156   ierr = PetscLayoutReference(cmap,&A->cmap);CHKERRQ(ierr);
2157   PetscFunctionReturn(0);
2158 }
2159 
2160 /*@
2161    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2162 
2163    Not Collective
2164 
2165    Input Parameters:
2166 .  A - the matrix
2167 
2168    Output Parameters:
2169 + rmap - row layout
2170 - cmap - column layout
2171 
2172    Level: advanced
2173 
2174 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping(), MatSetLayouts()
2175 @*/
2176 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2177 {
2178   PetscFunctionBegin;
2179   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2180   PetscValidType(A,1);
2181   if (rmap) PetscValidPointer(rmap,2);
2182   if (cmap) PetscValidPointer(cmap,3);
2183   if (rmap) *rmap = A->rmap;
2184   if (cmap) *cmap = A->cmap;
2185   PetscFunctionReturn(0);
2186 }
2187 
2188 /*@C
2189    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2190    using a local numbering of the nodes.
2191 
2192    Not Collective
2193 
2194    Input Parameters:
2195 +  mat - the matrix
2196 .  nrow, irow - number of rows and their local indices
2197 .  ncol, icol - number of columns and their local indices
2198 .  y -  a logically two-dimensional array of values
2199 -  addv - either INSERT_VALUES or ADD_VALUES, where
2200    ADD_VALUES adds values to any existing entries, and
2201    INSERT_VALUES replaces existing entries with new values
2202 
2203    Notes:
2204    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2205       MatSetUp() before using this routine
2206 
2207    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2208 
2209    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2210    options cannot be mixed without intervening calls to the assembly
2211    routines.
2212 
2213    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2214    MUST be called after all calls to MatSetValuesLocal() have been completed.
2215 
2216    Level: intermediate
2217 
2218    Developer Notes:
2219     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2220                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2221 
2222 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2223            MatSetValueLocal(), MatGetValuesLocal()
2224 @*/
2225 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2226 {
2227   PetscErrorCode ierr;
2228 
2229   PetscFunctionBeginHot;
2230   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2231   PetscValidType(mat,1);
2232   MatCheckPreallocated(mat,1);
2233   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2234   PetscValidIntPointer(irow,3);
2235   PetscValidIntPointer(icol,5);
2236   if (mat->insertmode == NOT_SET_VALUES) {
2237     mat->insertmode = addv;
2238   }
2239   else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2240   if (PetscDefined(USE_DEBUG)) {
2241     if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2242     if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2243   }
2244 
2245   if (mat->assembled) {
2246     mat->was_assembled = PETSC_TRUE;
2247     mat->assembled     = PETSC_FALSE;
2248   }
2249   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2250   if (mat->ops->setvalueslocal) {
2251     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2252   } else {
2253     PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm;
2254     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2255       irowm = buf; icolm = buf+nrow;
2256     } else {
2257       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2258       irowm = bufr; icolm = bufc;
2259     }
2260     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping()).");
2261     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatSetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping()).");
2262     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2263     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2264     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2265     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2266   }
2267   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2268   PetscFunctionReturn(0);
2269 }
2270 
2271 /*@C
2272    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2273    using a local ordering of the nodes a block at a time.
2274 
2275    Not Collective
2276 
2277    Input Parameters:
2278 +  x - the matrix
2279 .  nrow, irow - number of rows and their local indices
2280 .  ncol, icol - number of columns and their local indices
2281 .  y -  a logically two-dimensional array of values
2282 -  addv - either INSERT_VALUES or ADD_VALUES, where
2283    ADD_VALUES adds values to any existing entries, and
2284    INSERT_VALUES replaces existing entries with new values
2285 
2286    Notes:
2287    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2288       MatSetUp() before using this routine
2289 
2290    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2291       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2292 
2293    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2294    options cannot be mixed without intervening calls to the assembly
2295    routines.
2296 
2297    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2298    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2299 
2300    Level: intermediate
2301 
2302    Developer Notes:
2303     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2304                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2305 
2306 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2307            MatSetValuesLocal(),  MatSetValuesBlocked()
2308 @*/
2309 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2310 {
2311   PetscErrorCode ierr;
2312 
2313   PetscFunctionBeginHot;
2314   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2315   PetscValidType(mat,1);
2316   MatCheckPreallocated(mat,1);
2317   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2318   PetscValidIntPointer(irow,3);
2319   PetscValidIntPointer(icol,5);
2320   PetscValidScalarPointer(y,6);
2321   if (mat->insertmode == NOT_SET_VALUES) {
2322     mat->insertmode = addv;
2323   } else if (PetscUnlikely(mat->insertmode != addv)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2324   if (PetscDefined(USE_DEBUG)) {
2325     if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2326     if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2327   }
2328 
2329   if (mat->assembled) {
2330     mat->was_assembled = PETSC_TRUE;
2331     mat->assembled     = PETSC_FALSE;
2332   }
2333   if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2334     PetscInt irbs, rbs;
2335     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2336     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2337     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2338   }
2339   if (PetscUnlikelyDebug(mat->cmap->mapping)) {
2340     PetscInt icbs, cbs;
2341     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2342     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2343     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2344   }
2345   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2346   if (mat->ops->setvaluesblockedlocal) {
2347     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2348   } else {
2349     PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm;
2350     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2351       irowm = buf; icolm = buf + nrow;
2352     } else {
2353       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2354       irowm = bufr; icolm = bufc;
2355     }
2356     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2357     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2358     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2359     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2360   }
2361   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2362   PetscFunctionReturn(0);
2363 }
2364 
2365 /*@
2366    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2367 
2368    Collective on Mat
2369 
2370    Input Parameters:
2371 +  mat - the matrix
2372 -  x   - the vector to be multiplied
2373 
2374    Output Parameters:
2375 .  y - the result
2376 
2377    Notes:
2378    The vectors x and y cannot be the same.  I.e., one cannot
2379    call MatMult(A,y,y).
2380 
2381    Level: developer
2382 
2383 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2384 @*/
2385 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2386 {
2387   PetscErrorCode ierr;
2388 
2389   PetscFunctionBegin;
2390   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2391   PetscValidType(mat,1);
2392   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2393   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2394 
2395   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2396   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2397   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2398   MatCheckPreallocated(mat,1);
2399 
2400   if (!mat->ops->multdiagonalblock) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2401   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2402   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2403   PetscFunctionReturn(0);
2404 }
2405 
2406 /* --------------------------------------------------------*/
2407 /*@
2408    MatMult - Computes the matrix-vector product, y = Ax.
2409 
2410    Neighbor-wise Collective on Mat
2411 
2412    Input Parameters:
2413 +  mat - the matrix
2414 -  x   - the vector to be multiplied
2415 
2416    Output Parameters:
2417 .  y - the result
2418 
2419    Notes:
2420    The vectors x and y cannot be the same.  I.e., one cannot
2421    call MatMult(A,y,y).
2422 
2423    Level: beginner
2424 
2425 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2426 @*/
2427 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2428 {
2429   PetscErrorCode ierr;
2430 
2431   PetscFunctionBegin;
2432   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2433   PetscValidType(mat,1);
2434   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2435   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2436   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2437   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2438   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2439 #if !defined(PETSC_HAVE_CONSTRAINTS)
2440   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2441   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2442   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2443 #endif
2444   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2445   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2446   MatCheckPreallocated(mat,1);
2447 
2448   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2449   if (!mat->ops->mult) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name);
2450   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2451   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2452   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2453   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2454   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2455   PetscFunctionReturn(0);
2456 }
2457 
2458 /*@
2459    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2460 
2461    Neighbor-wise Collective on Mat
2462 
2463    Input Parameters:
2464 +  mat - the matrix
2465 -  x   - the vector to be multiplied
2466 
2467    Output Parameters:
2468 .  y - the result
2469 
2470    Notes:
2471    The vectors x and y cannot be the same.  I.e., one cannot
2472    call MatMultTranspose(A,y,y).
2473 
2474    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2475    use MatMultHermitianTranspose()
2476 
2477    Level: beginner
2478 
2479 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2480 @*/
2481 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2482 {
2483   PetscErrorCode (*op)(Mat,Vec,Vec)=NULL,ierr;
2484 
2485   PetscFunctionBegin;
2486   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2487   PetscValidType(mat,1);
2488   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2489   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2490 
2491   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2492   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2493   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2494 #if !defined(PETSC_HAVE_CONSTRAINTS)
2495   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2496   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2497 #endif
2498   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2499   MatCheckPreallocated(mat,1);
2500 
2501   if (!mat->ops->multtranspose) {
2502     if (mat->symmetric && mat->ops->mult) op = mat->ops->mult;
2503     if (!op) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined or is symmetric and does not have a multiply defined",((PetscObject)mat)->type_name);
2504   } else op = mat->ops->multtranspose;
2505   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2506   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2507   ierr = (*op)(mat,x,y);CHKERRQ(ierr);
2508   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2509   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2510   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2511   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2512   PetscFunctionReturn(0);
2513 }
2514 
2515 /*@
2516    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2517 
2518    Neighbor-wise Collective on Mat
2519 
2520    Input Parameters:
2521 +  mat - the matrix
2522 -  x   - the vector to be multilplied
2523 
2524    Output Parameters:
2525 .  y - the result
2526 
2527    Notes:
2528    The vectors x and y cannot be the same.  I.e., one cannot
2529    call MatMultHermitianTranspose(A,y,y).
2530 
2531    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2532 
2533    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2534 
2535    Level: beginner
2536 
2537 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2538 @*/
2539 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2540 {
2541   PetscErrorCode ierr;
2542 
2543   PetscFunctionBegin;
2544   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2545   PetscValidType(mat,1);
2546   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2547   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2548 
2549   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2550   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2551   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2552 #if !defined(PETSC_HAVE_CONSTRAINTS)
2553   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2554   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2555 #endif
2556   MatCheckPreallocated(mat,1);
2557 
2558   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2559 #if defined(PETSC_USE_COMPLEX)
2560   if (mat->ops->multhermitiantranspose || (mat->hermitian && mat->ops->mult)) {
2561     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2562     if (mat->ops->multhermitiantranspose) {
2563       ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2564     } else {
2565       ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2566     }
2567     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2568   } else {
2569     Vec w;
2570     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2571     ierr = VecCopy(x,w);CHKERRQ(ierr);
2572     ierr = VecConjugate(w);CHKERRQ(ierr);
2573     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2574     ierr = VecDestroy(&w);CHKERRQ(ierr);
2575     ierr = VecConjugate(y);CHKERRQ(ierr);
2576   }
2577   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2578 #else
2579   ierr = MatMultTranspose(mat,x,y);CHKERRQ(ierr);
2580 #endif
2581   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2582   PetscFunctionReturn(0);
2583 }
2584 
2585 /*@
2586     MatMultAdd -  Computes v3 = v2 + A * v1.
2587 
2588     Neighbor-wise Collective on Mat
2589 
2590     Input Parameters:
2591 +   mat - the matrix
2592 -   v1, v2 - the vectors
2593 
2594     Output Parameters:
2595 .   v3 - the result
2596 
2597     Notes:
2598     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2599     call MatMultAdd(A,v1,v2,v1).
2600 
2601     Level: beginner
2602 
2603 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2604 @*/
2605 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2606 {
2607   PetscErrorCode ierr;
2608 
2609   PetscFunctionBegin;
2610   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2611   PetscValidType(mat,1);
2612   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2613   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2614   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2615 
2616   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2617   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2618   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2619   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2620      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2621   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2622   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2623   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2624   MatCheckPreallocated(mat,1);
2625 
2626   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name);
2627   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2628   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2629   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2630   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2631   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2632   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2633   PetscFunctionReturn(0);
2634 }
2635 
2636 /*@
2637    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2638 
2639    Neighbor-wise Collective on Mat
2640 
2641    Input Parameters:
2642 +  mat - the matrix
2643 -  v1, v2 - the vectors
2644 
2645    Output Parameters:
2646 .  v3 - the result
2647 
2648    Notes:
2649    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2650    call MatMultTransposeAdd(A,v1,v2,v1).
2651 
2652    Level: beginner
2653 
2654 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2655 @*/
2656 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2657 {
2658   PetscErrorCode ierr;
2659 
2660   PetscFunctionBegin;
2661   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2662   PetscValidType(mat,1);
2663   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2664   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2665   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2666 
2667   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2668   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2669   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2670   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2671   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2672   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2673   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2674   MatCheckPreallocated(mat,1);
2675 
2676   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2677   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2678   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2679   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2680   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2681   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2682   PetscFunctionReturn(0);
2683 }
2684 
2685 /*@
2686    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2687 
2688    Neighbor-wise Collective on Mat
2689 
2690    Input Parameters:
2691 +  mat - the matrix
2692 -  v1, v2 - the vectors
2693 
2694    Output Parameters:
2695 .  v3 - the result
2696 
2697    Notes:
2698    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2699    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2700 
2701    Level: beginner
2702 
2703 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2704 @*/
2705 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2706 {
2707   PetscErrorCode ierr;
2708 
2709   PetscFunctionBegin;
2710   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2711   PetscValidType(mat,1);
2712   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2713   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2714   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2715 
2716   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2717   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2718   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2719   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2720   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2721   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2722   MatCheckPreallocated(mat,1);
2723 
2724   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2725   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2726   if (mat->ops->multhermitiantransposeadd) {
2727     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2728   } else {
2729     Vec w,z;
2730     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2731     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2732     ierr = VecConjugate(w);CHKERRQ(ierr);
2733     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2734     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2735     ierr = VecDestroy(&w);CHKERRQ(ierr);
2736     ierr = VecConjugate(z);CHKERRQ(ierr);
2737     if (v2 != v3) {
2738       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2739     } else {
2740       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2741     }
2742     ierr = VecDestroy(&z);CHKERRQ(ierr);
2743   }
2744   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2745   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2746   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2747   PetscFunctionReturn(0);
2748 }
2749 
2750 /*@
2751    MatMultConstrained - The inner multiplication routine for a
2752    constrained matrix P^T A P.
2753 
2754    Neighbor-wise Collective on Mat
2755 
2756    Input Parameters:
2757 +  mat - the matrix
2758 -  x   - the vector to be multilplied
2759 
2760    Output Parameters:
2761 .  y - the result
2762 
2763    Notes:
2764    The vectors x and y cannot be the same.  I.e., one cannot
2765    call MatMult(A,y,y).
2766 
2767    Level: beginner
2768 
2769 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2770 @*/
2771 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2772 {
2773   PetscErrorCode ierr;
2774 
2775   PetscFunctionBegin;
2776   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2777   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2778   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2779   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2780   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2781   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2782   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2783   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2784   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2785 
2786   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2787   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2788   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2789   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2790   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2791   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2792   PetscFunctionReturn(0);
2793 }
2794 
2795 /*@
2796    MatMultTransposeConstrained - The inner multiplication routine for a
2797    constrained matrix P^T A^T P.
2798 
2799    Neighbor-wise Collective on Mat
2800 
2801    Input Parameters:
2802 +  mat - the matrix
2803 -  x   - the vector to be multilplied
2804 
2805    Output Parameters:
2806 .  y - the result
2807 
2808    Notes:
2809    The vectors x and y cannot be the same.  I.e., one cannot
2810    call MatMult(A,y,y).
2811 
2812    Level: beginner
2813 
2814 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2815 @*/
2816 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2817 {
2818   PetscErrorCode ierr;
2819 
2820   PetscFunctionBegin;
2821   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2822   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2823   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2824   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2825   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2826   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2827   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2828   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2829 
2830   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2831   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2832   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2833   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2834   PetscFunctionReturn(0);
2835 }
2836 
2837 /*@C
2838    MatGetFactorType - gets the type of factorization it is
2839 
2840    Not Collective
2841 
2842    Input Parameters:
2843 .  mat - the matrix
2844 
2845    Output Parameters:
2846 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2847 
2848    Level: intermediate
2849 
2850 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2851 @*/
2852 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2853 {
2854   PetscFunctionBegin;
2855   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2856   PetscValidType(mat,1);
2857   PetscValidPointer(t,2);
2858   *t = mat->factortype;
2859   PetscFunctionReturn(0);
2860 }
2861 
2862 /*@C
2863    MatSetFactorType - sets the type of factorization it is
2864 
2865    Logically Collective on Mat
2866 
2867    Input Parameters:
2868 +  mat - the matrix
2869 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2870 
2871    Level: intermediate
2872 
2873 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2874 @*/
2875 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2876 {
2877   PetscFunctionBegin;
2878   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2879   PetscValidType(mat,1);
2880   mat->factortype = t;
2881   PetscFunctionReturn(0);
2882 }
2883 
2884 /* ------------------------------------------------------------*/
2885 /*@C
2886    MatGetInfo - Returns information about matrix storage (number of
2887    nonzeros, memory, etc.).
2888 
2889    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2890 
2891    Input Parameters:
2892 .  mat - the matrix
2893 
2894    Output Parameters:
2895 +  flag - flag indicating the type of parameters to be returned
2896    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2897    MAT_GLOBAL_SUM - sum over all processors)
2898 -  info - matrix information context
2899 
2900    Notes:
2901    The MatInfo context contains a variety of matrix data, including
2902    number of nonzeros allocated and used, number of mallocs during
2903    matrix assembly, etc.  Additional information for factored matrices
2904    is provided (such as the fill ratio, number of mallocs during
2905    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2906    when using the runtime options
2907 $       -info -mat_view ::ascii_info
2908 
2909    Example for C/C++ Users:
2910    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2911    data within the MatInfo context.  For example,
2912 .vb
2913       MatInfo info;
2914       Mat     A;
2915       double  mal, nz_a, nz_u;
2916 
2917       MatGetInfo(A,MAT_LOCAL,&info);
2918       mal  = info.mallocs;
2919       nz_a = info.nz_allocated;
2920 .ve
2921 
2922    Example for Fortran Users:
2923    Fortran users should declare info as a double precision
2924    array of dimension MAT_INFO_SIZE, and then extract the parameters
2925    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2926    a complete list of parameter names.
2927 .vb
2928       double  precision info(MAT_INFO_SIZE)
2929       double  precision mal, nz_a
2930       Mat     A
2931       integer ierr
2932 
2933       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2934       mal = info(MAT_INFO_MALLOCS)
2935       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2936 .ve
2937 
2938     Level: intermediate
2939 
2940     Developer Note: fortran interface is not autogenerated as the f90
2941     interface defintion cannot be generated correctly [due to MatInfo]
2942 
2943 .seealso: MatStashGetInfo()
2944 
2945 @*/
2946 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2947 {
2948   PetscErrorCode ierr;
2949 
2950   PetscFunctionBegin;
2951   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2952   PetscValidType(mat,1);
2953   PetscValidPointer(info,3);
2954   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2955   MatCheckPreallocated(mat,1);
2956   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2957   PetscFunctionReturn(0);
2958 }
2959 
2960 /*
2961    This is used by external packages where it is not easy to get the info from the actual
2962    matrix factorization.
2963 */
2964 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2965 {
2966   PetscErrorCode ierr;
2967 
2968   PetscFunctionBegin;
2969   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2970   PetscFunctionReturn(0);
2971 }
2972 
2973 /* ----------------------------------------------------------*/
2974 
2975 /*@C
2976    MatLUFactor - Performs in-place LU factorization of matrix.
2977 
2978    Collective on Mat
2979 
2980    Input Parameters:
2981 +  mat - the matrix
2982 .  row - row permutation
2983 .  col - column permutation
2984 -  info - options for factorization, includes
2985 $          fill - expected fill as ratio of original fill.
2986 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2987 $                   Run with the option -info to determine an optimal value to use
2988 
2989    Notes:
2990    Most users should employ the simplified KSP interface for linear solvers
2991    instead of working directly with matrix algebra routines such as this.
2992    See, e.g., KSPCreate().
2993 
2994    This changes the state of the matrix to a factored matrix; it cannot be used
2995    for example with MatSetValues() unless one first calls MatSetUnfactored().
2996 
2997    Level: developer
2998 
2999 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
3000           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
3001 
3002     Developer Note: fortran interface is not autogenerated as the f90
3003     interface defintion cannot be generated correctly [due to MatFactorInfo]
3004 
3005 @*/
3006 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3007 {
3008   PetscErrorCode ierr;
3009   MatFactorInfo  tinfo;
3010 
3011   PetscFunctionBegin;
3012   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3013   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3014   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3015   if (info) PetscValidPointer(info,4);
3016   PetscValidType(mat,1);
3017   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3018   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3019   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3020   MatCheckPreallocated(mat,1);
3021   if (!info) {
3022     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3023     info = &tinfo;
3024   }
3025 
3026   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
3027   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
3028   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
3029   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3030   PetscFunctionReturn(0);
3031 }
3032 
3033 /*@C
3034    MatILUFactor - Performs in-place ILU factorization of matrix.
3035 
3036    Collective on Mat
3037 
3038    Input Parameters:
3039 +  mat - the matrix
3040 .  row - row permutation
3041 .  col - column permutation
3042 -  info - structure containing
3043 $      levels - number of levels of fill.
3044 $      expected fill - as ratio of original fill.
3045 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3046                 missing diagonal entries)
3047 
3048    Notes:
3049    Probably really in-place only when level of fill is zero, otherwise allocates
3050    new space to store factored matrix and deletes previous memory.
3051 
3052    Most users should employ the simplified KSP interface for linear solvers
3053    instead of working directly with matrix algebra routines such as this.
3054    See, e.g., KSPCreate().
3055 
3056    Level: developer
3057 
3058 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3059 
3060     Developer Note: fortran interface is not autogenerated as the f90
3061     interface defintion cannot be generated correctly [due to MatFactorInfo]
3062 
3063 @*/
3064 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3065 {
3066   PetscErrorCode ierr;
3067 
3068   PetscFunctionBegin;
3069   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3070   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3071   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3072   PetscValidPointer(info,4);
3073   PetscValidType(mat,1);
3074   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3075   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3076   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3077   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3078   MatCheckPreallocated(mat,1);
3079 
3080   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3081   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3082   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3083   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3084   PetscFunctionReturn(0);
3085 }
3086 
3087 /*@C
3088    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3089    Call this routine before calling MatLUFactorNumeric().
3090 
3091    Collective on Mat
3092 
3093    Input Parameters:
3094 +  fact - the factor matrix obtained with MatGetFactor()
3095 .  mat - the matrix
3096 .  row, col - row and column permutations
3097 -  info - options for factorization, includes
3098 $          fill - expected fill as ratio of original fill.
3099 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3100 $                   Run with the option -info to determine an optimal value to use
3101 
3102 
3103    Notes:
3104     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3105 
3106    Most users should employ the simplified KSP interface for linear solvers
3107    instead of working directly with matrix algebra routines such as this.
3108    See, e.g., KSPCreate().
3109 
3110    Level: developer
3111 
3112 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3113 
3114     Developer Note: fortran interface is not autogenerated as the f90
3115     interface defintion cannot be generated correctly [due to MatFactorInfo]
3116 
3117 @*/
3118 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3119 {
3120   PetscErrorCode ierr;
3121   MatFactorInfo  tinfo;
3122 
3123   PetscFunctionBegin;
3124   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3125   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3);
3126   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4);
3127   if (info) PetscValidPointer(info,5);
3128   PetscValidType(mat,2);
3129   PetscValidPointer(fact,1);
3130   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3131   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3132   if (!(fact)->ops->lufactorsymbolic) {
3133     MatSolverType stype;
3134     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
3135     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype);
3136   }
3137   MatCheckPreallocated(mat,2);
3138   if (!info) {
3139     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3140     info = &tinfo;
3141   }
3142 
3143   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3144   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3145   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3146   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3147   PetscFunctionReturn(0);
3148 }
3149 
3150 /*@C
3151    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3152    Call this routine after first calling MatLUFactorSymbolic().
3153 
3154    Collective on Mat
3155 
3156    Input Parameters:
3157 +  fact - the factor matrix obtained with MatGetFactor()
3158 .  mat - the matrix
3159 -  info - options for factorization
3160 
3161    Notes:
3162    See MatLUFactor() for in-place factorization.  See
3163    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3164 
3165    Most users should employ the simplified KSP interface for linear solvers
3166    instead of working directly with matrix algebra routines such as this.
3167    See, e.g., KSPCreate().
3168 
3169    Level: developer
3170 
3171 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3172 
3173     Developer Note: fortran interface is not autogenerated as the f90
3174     interface defintion cannot be generated correctly [due to MatFactorInfo]
3175 
3176 @*/
3177 #if defined(PETSC_HAVE_NVTX)
3178 #include <nvToolsExt.h>
3179 #endif
3180 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3181 {
3182   MatFactorInfo  tinfo;
3183   PetscErrorCode ierr;
3184 
3185   PetscFunctionBegin;
3186   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3187   PetscValidType(mat,2);
3188   PetscValidPointer(fact,1);
3189   PetscValidHeaderSpecific(fact,MAT_CLASSID,1);
3190   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3191   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3192 
3193   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3194   MatCheckPreallocated(mat,2);
3195   if (!info) {
3196     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3197     info = &tinfo;
3198   }
3199 #if defined(PETSC_HAVE_NVTX)
3200   nvtxRangePushA("LU Factor");
3201 #endif
3202   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3203   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3204   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3205 #if defined(PETSC_HAVE_NVTX)
3206   nvtxRangePop();
3207 #endif
3208   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3209   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3210   PetscFunctionReturn(0);
3211 }
3212 
3213 /*@C
3214    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3215    symmetric matrix.
3216 
3217    Collective on Mat
3218 
3219    Input Parameters:
3220 +  mat - the matrix
3221 .  perm - row and column permutations
3222 -  f - expected fill as ratio of original fill
3223 
3224    Notes:
3225    See MatLUFactor() for the nonsymmetric case.  See also
3226    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3227 
3228    Most users should employ the simplified KSP interface for linear solvers
3229    instead of working directly with matrix algebra routines such as this.
3230    See, e.g., KSPCreate().
3231 
3232    Level: developer
3233 
3234 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3235           MatGetOrdering()
3236 
3237     Developer Note: fortran interface is not autogenerated as the f90
3238     interface defintion cannot be generated correctly [due to MatFactorInfo]
3239 
3240 @*/
3241 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3242 {
3243   PetscErrorCode ierr;
3244   MatFactorInfo  tinfo;
3245 
3246   PetscFunctionBegin;
3247   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3248   PetscValidType(mat,1);
3249   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3250   if (info) PetscValidPointer(info,3);
3251   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3252   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3253   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3254   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3255   MatCheckPreallocated(mat,1);
3256   if (!info) {
3257     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3258     info = &tinfo;
3259   }
3260 
3261   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3262   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3263   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3264   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3265   PetscFunctionReturn(0);
3266 }
3267 
3268 /*@C
3269    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3270    of a symmetric matrix.
3271 
3272    Collective on Mat
3273 
3274    Input Parameters:
3275 +  fact - the factor matrix obtained with MatGetFactor()
3276 .  mat - the matrix
3277 .  perm - row and column permutations
3278 -  info - options for factorization, includes
3279 $          fill - expected fill as ratio of original fill.
3280 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3281 $                   Run with the option -info to determine an optimal value to use
3282 
3283    Notes:
3284    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3285    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3286 
3287    Most users should employ the simplified KSP interface for linear solvers
3288    instead of working directly with matrix algebra routines such as this.
3289    See, e.g., KSPCreate().
3290 
3291    Level: developer
3292 
3293 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3294           MatGetOrdering()
3295 
3296     Developer Note: fortran interface is not autogenerated as the f90
3297     interface defintion cannot be generated correctly [due to MatFactorInfo]
3298 
3299 @*/
3300 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3301 {
3302   PetscErrorCode ierr;
3303   MatFactorInfo  tinfo;
3304 
3305   PetscFunctionBegin;
3306   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3307   PetscValidType(mat,2);
3308   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3);
3309   if (info) PetscValidPointer(info,4);
3310   PetscValidPointer(fact,1);
3311   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3312   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3313   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3314   if (!(fact)->ops->choleskyfactorsymbolic) {
3315     MatSolverType stype;
3316     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
3317     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype);
3318   }
3319   MatCheckPreallocated(mat,2);
3320   if (!info) {
3321     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3322     info = &tinfo;
3323   }
3324 
3325   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3326   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3327   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3328   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3329   PetscFunctionReturn(0);
3330 }
3331 
3332 /*@C
3333    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3334    of a symmetric matrix. Call this routine after first calling
3335    MatCholeskyFactorSymbolic().
3336 
3337    Collective on Mat
3338 
3339    Input Parameters:
3340 +  fact - the factor matrix obtained with MatGetFactor()
3341 .  mat - the initial matrix
3342 .  info - options for factorization
3343 -  fact - the symbolic factor of mat
3344 
3345 
3346    Notes:
3347    Most users should employ the simplified KSP interface for linear solvers
3348    instead of working directly with matrix algebra routines such as this.
3349    See, e.g., KSPCreate().
3350 
3351    Level: developer
3352 
3353 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3354 
3355     Developer Note: fortran interface is not autogenerated as the f90
3356     interface defintion cannot be generated correctly [due to MatFactorInfo]
3357 
3358 @*/
3359 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3360 {
3361   MatFactorInfo  tinfo;
3362   PetscErrorCode ierr;
3363 
3364   PetscFunctionBegin;
3365   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3366   PetscValidType(mat,2);
3367   PetscValidPointer(fact,1);
3368   PetscValidHeaderSpecific(fact,MAT_CLASSID,1);
3369   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3370   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3371   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3372   MatCheckPreallocated(mat,2);
3373   if (!info) {
3374     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3375     info = &tinfo;
3376   }
3377 
3378   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3379   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3380   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3381   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3382   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3383   PetscFunctionReturn(0);
3384 }
3385 
3386 /*@C
3387    MatQRFactor - Performs in-place QR factorization of matrix.
3388 
3389    Collective on Mat
3390 
3391    Input Parameters:
3392 +  mat - the matrix
3393 .  col - column permutation
3394 -  info - options for factorization, includes
3395 $          fill - expected fill as ratio of original fill.
3396 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3397 $                   Run with the option -info to determine an optimal value to use
3398 
3399    Notes:
3400    Most users should employ the simplified KSP interface for linear solvers
3401    instead of working directly with matrix algebra routines such as this.
3402    See, e.g., KSPCreate().
3403 
3404    This changes the state of the matrix to a factored matrix; it cannot be used
3405    for example with MatSetValues() unless one first calls MatSetUnfactored().
3406 
3407    Level: developer
3408 
3409 .seealso: MatQRFactorSymbolic(), MatQRFactorNumeric(), MatLUFactor(),
3410           MatSetUnfactored(), MatFactorInfo, MatGetFactor()
3411 
3412     Developer Note: fortran interface is not autogenerated as the f90
3413     interface defintion cannot be generated correctly [due to MatFactorInfo]
3414 
3415 @*/
3416 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info)
3417 {
3418   PetscErrorCode ierr;
3419 
3420   PetscFunctionBegin;
3421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3422   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2);
3423   if (info) PetscValidPointer(info,3);
3424   PetscValidType(mat,1);
3425   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3426   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3427   MatCheckPreallocated(mat,1);
3428   ierr = PetscLogEventBegin(MAT_QRFactor,mat,col,0,0);CHKERRQ(ierr);
3429   ierr = PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info));CHKERRQ(ierr);
3430   ierr = PetscLogEventEnd(MAT_QRFactor,mat,col,0,0);CHKERRQ(ierr);
3431   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3432   PetscFunctionReturn(0);
3433 }
3434 
3435 /*@C
3436    MatQRFactorSymbolic - Performs symbolic QR factorization of matrix.
3437    Call this routine before calling MatQRFactorNumeric().
3438 
3439    Collective on Mat
3440 
3441    Input Parameters:
3442 +  fact - the factor matrix obtained with MatGetFactor()
3443 .  mat - the matrix
3444 .  col - column permutation
3445 -  info - options for factorization, includes
3446 $          fill - expected fill as ratio of original fill.
3447 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3448 $                   Run with the option -info to determine an optimal value to use
3449 
3450    Most users should employ the simplified KSP interface for linear solvers
3451    instead of working directly with matrix algebra routines such as this.
3452    See, e.g., KSPCreate().
3453 
3454    Level: developer
3455 
3456 .seealso: MatQRFactor(), MatQRFactorNumeric(), MatLUFactor(), MatFactorInfo, MatFactorInfoInitialize()
3457 
3458     Developer Note: fortran interface is not autogenerated as the f90
3459     interface defintion cannot be generated correctly [due to MatFactorInfo]
3460 
3461 @*/
3462 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info)
3463 {
3464   PetscErrorCode ierr;
3465   MatFactorInfo  tinfo;
3466 
3467   PetscFunctionBegin;
3468   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3469   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3470   if (info) PetscValidPointer(info,4);
3471   PetscValidType(mat,2);
3472   PetscValidPointer(fact,1);
3473   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3474   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3475   MatCheckPreallocated(mat,2);
3476   if (!info) {
3477     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3478     info = &tinfo;
3479   }
3480 
3481   ierr = PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0);CHKERRQ(ierr);
3482   ierr = PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info));CHKERRQ(ierr);
3483   ierr = PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0);CHKERRQ(ierr);
3484   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3485   PetscFunctionReturn(0);
3486 }
3487 
3488 /*@C
3489    MatQRFactorNumeric - Performs numeric QR factorization of a matrix.
3490    Call this routine after first calling MatQRFactorSymbolic().
3491 
3492    Collective on Mat
3493 
3494    Input Parameters:
3495 +  fact - the factor matrix obtained with MatGetFactor()
3496 .  mat - the matrix
3497 -  info - options for factorization
3498 
3499    Notes:
3500    See MatQRFactor() for in-place factorization.
3501 
3502    Most users should employ the simplified KSP interface for linear solvers
3503    instead of working directly with matrix algebra routines such as this.
3504    See, e.g., KSPCreate().
3505 
3506    Level: developer
3507 
3508 .seealso: MatQRFactorSymbolic(), MatLUFactor()
3509 
3510     Developer Note: fortran interface is not autogenerated as the f90
3511     interface defintion cannot be generated correctly [due to MatFactorInfo]
3512 
3513 @*/
3514 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3515 {
3516   MatFactorInfo  tinfo;
3517   PetscErrorCode ierr;
3518 
3519   PetscFunctionBegin;
3520   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3521   PetscValidType(mat,2);
3522   PetscValidPointer(fact,1);
3523   PetscValidHeaderSpecific(fact,MAT_CLASSID,1);
3524   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3525   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3526 
3527   MatCheckPreallocated(mat,2);
3528   if (!info) {
3529     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3530     info = &tinfo;
3531   }
3532 
3533   ierr = PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3534   ierr = PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info));CHKERRQ(ierr);
3535   ierr = PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3536   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3537   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3538   PetscFunctionReturn(0);
3539 }
3540 
3541 /* ----------------------------------------------------------------*/
3542 /*@
3543    MatSolve - Solves A x = b, given a factored matrix.
3544 
3545    Neighbor-wise Collective on Mat
3546 
3547    Input Parameters:
3548 +  mat - the factored matrix
3549 -  b - the right-hand-side vector
3550 
3551    Output Parameter:
3552 .  x - the result vector
3553 
3554    Notes:
3555    The vectors b and x cannot be the same.  I.e., one cannot
3556    call MatSolve(A,x,x).
3557 
3558    Notes:
3559    Most users should employ the simplified KSP interface for linear solvers
3560    instead of working directly with matrix algebra routines such as this.
3561    See, e.g., KSPCreate().
3562 
3563    Level: developer
3564 
3565 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3566 @*/
3567 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3568 {
3569   PetscErrorCode ierr;
3570 
3571   PetscFunctionBegin;
3572   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3573   PetscValidType(mat,1);
3574   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3575   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3576   PetscCheckSameComm(mat,1,b,2);
3577   PetscCheckSameComm(mat,1,x,3);
3578   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3579   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3580   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3581   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3582   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3583   MatCheckPreallocated(mat,1);
3584 
3585   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3586   if (mat->factorerrortype) {
3587     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3588     ierr = VecSetInf(x);CHKERRQ(ierr);
3589   } else {
3590     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3591     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3592   }
3593   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3594   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3595   PetscFunctionReturn(0);
3596 }
3597 
3598 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)
3599 {
3600   PetscErrorCode ierr;
3601   Vec            b,x;
3602   PetscInt       m,N,i;
3603   PetscScalar    *bb,*xx;
3604   PetscErrorCode (*f)(Mat,Vec,Vec);
3605 
3606   PetscFunctionBegin;
3607   if (A->factorerrortype) {
3608     ierr = PetscInfo1(A,"MatFactorError %D\n",A->factorerrortype);CHKERRQ(ierr);
3609     ierr = MatSetInf(X);CHKERRQ(ierr);
3610     PetscFunctionReturn(0);
3611   }
3612   f = trans ? A->ops->solvetranspose : A->ops->solve;
3613   if (!f) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3614 
3615   ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3616   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3617   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3618   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3619   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3620   for (i=0; i<N; i++) {
3621     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3622     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3623     ierr = (*f)(A,b,x);CHKERRQ(ierr);
3624     ierr = VecResetArray(x);CHKERRQ(ierr);
3625     ierr = VecResetArray(b);CHKERRQ(ierr);
3626   }
3627   ierr = VecDestroy(&b);CHKERRQ(ierr);
3628   ierr = VecDestroy(&x);CHKERRQ(ierr);
3629   ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3630   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3631   PetscFunctionReturn(0);
3632 }
3633 
3634 /*@
3635    MatMatSolve - Solves A X = B, given a factored matrix.
3636 
3637    Neighbor-wise Collective on Mat
3638 
3639    Input Parameters:
3640 +  A - the factored matrix
3641 -  B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS)
3642 
3643    Output Parameter:
3644 .  X - the result matrix (dense matrix)
3645 
3646    Notes:
3647    If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO;
3648    otherwise, B and X cannot be the same.
3649 
3650    Notes:
3651    Most users should usually employ the simplified KSP interface for linear solvers
3652    instead of working directly with matrix algebra routines such as this.
3653    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3654    at a time.
3655 
3656    Level: developer
3657 
3658 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3659 @*/
3660 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3661 {
3662   PetscErrorCode ierr;
3663 
3664   PetscFunctionBegin;
3665   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3666   PetscValidType(A,1);
3667   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3668   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3669   PetscCheckSameComm(A,1,B,2);
3670   PetscCheckSameComm(A,1,X,3);
3671   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3672   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3673   if (X->cmap->N != B->cmap->N) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3674   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3675   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3676   MatCheckPreallocated(A,1);
3677 
3678   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3679   if (!A->ops->matsolve) {
3680     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3681     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3682   } else {
3683     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3684   }
3685   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3686   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3687   PetscFunctionReturn(0);
3688 }
3689 
3690 /*@
3691    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3692 
3693    Neighbor-wise Collective on Mat
3694 
3695    Input Parameters:
3696 +  A - the factored matrix
3697 -  B - the right-hand-side matrix  (dense matrix)
3698 
3699    Output Parameter:
3700 .  X - the result matrix (dense matrix)
3701 
3702    Notes:
3703    The matrices B and X cannot be the same.  I.e., one cannot
3704    call MatMatSolveTranspose(A,X,X).
3705 
3706    Notes:
3707    Most users should usually employ the simplified KSP interface for linear solvers
3708    instead of working directly with matrix algebra routines such as this.
3709    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3710    at a time.
3711 
3712    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3713 
3714    Level: developer
3715 
3716 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3717 @*/
3718 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3719 {
3720   PetscErrorCode ierr;
3721 
3722   PetscFunctionBegin;
3723   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3724   PetscValidType(A,1);
3725   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3726   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3727   PetscCheckSameComm(A,1,B,2);
3728   PetscCheckSameComm(A,1,X,3);
3729   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3730   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3731   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3732   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3733   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3734   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3735   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3736   MatCheckPreallocated(A,1);
3737 
3738   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3739   if (!A->ops->matsolvetranspose) {
3740     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3741     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3742   } else {
3743     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3744   }
3745   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3746   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3747   PetscFunctionReturn(0);
3748 }
3749 
3750 /*@
3751    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3752 
3753    Neighbor-wise Collective on Mat
3754 
3755    Input Parameters:
3756 +  A - the factored matrix
3757 -  Bt - the transpose of right-hand-side matrix
3758 
3759    Output Parameter:
3760 .  X - the result matrix (dense matrix)
3761 
3762    Notes:
3763    Most users should usually employ the simplified KSP interface for linear solvers
3764    instead of working directly with matrix algebra routines such as this.
3765    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3766    at a time.
3767 
3768    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().
3769 
3770    Level: developer
3771 
3772 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3773 @*/
3774 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3775 {
3776   PetscErrorCode ierr;
3777 
3778   PetscFunctionBegin;
3779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3780   PetscValidType(A,1);
3781   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3782   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3783   PetscCheckSameComm(A,1,Bt,2);
3784   PetscCheckSameComm(A,1,X,3);
3785 
3786   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3787   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3788   if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N);
3789   if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix");
3790   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3791   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3792   MatCheckPreallocated(A,1);
3793 
3794   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3795   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3796   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3797   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3798   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3799   PetscFunctionReturn(0);
3800 }
3801 
3802 /*@
3803    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3804                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3805 
3806    Neighbor-wise Collective on Mat
3807 
3808    Input Parameters:
3809 +  mat - the factored matrix
3810 -  b - the right-hand-side vector
3811 
3812    Output Parameter:
3813 .  x - the result vector
3814 
3815    Notes:
3816    MatSolve() should be used for most applications, as it performs
3817    a forward solve followed by a backward solve.
3818 
3819    The vectors b and x cannot be the same,  i.e., one cannot
3820    call MatForwardSolve(A,x,x).
3821 
3822    For matrix in seqsbaij format with block size larger than 1,
3823    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3824    MatForwardSolve() solves U^T*D y = b, and
3825    MatBackwardSolve() solves U x = y.
3826    Thus they do not provide a symmetric preconditioner.
3827 
3828    Most users should employ the simplified KSP interface for linear solvers
3829    instead of working directly with matrix algebra routines such as this.
3830    See, e.g., KSPCreate().
3831 
3832    Level: developer
3833 
3834 .seealso: MatSolve(), MatBackwardSolve()
3835 @*/
3836 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3837 {
3838   PetscErrorCode ierr;
3839 
3840   PetscFunctionBegin;
3841   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3842   PetscValidType(mat,1);
3843   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3844   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3845   PetscCheckSameComm(mat,1,b,2);
3846   PetscCheckSameComm(mat,1,x,3);
3847   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3848   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3849   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3850   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3851   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3852   MatCheckPreallocated(mat,1);
3853 
3854   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3855   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3856   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3857   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3858   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3859   PetscFunctionReturn(0);
3860 }
3861 
3862 /*@
3863    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3864                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3865 
3866    Neighbor-wise Collective on Mat
3867 
3868    Input Parameters:
3869 +  mat - the factored matrix
3870 -  b - the right-hand-side vector
3871 
3872    Output Parameter:
3873 .  x - the result vector
3874 
3875    Notes:
3876    MatSolve() should be used for most applications, as it performs
3877    a forward solve followed by a backward solve.
3878 
3879    The vectors b and x cannot be the same.  I.e., one cannot
3880    call MatBackwardSolve(A,x,x).
3881 
3882    For matrix in seqsbaij format with block size larger than 1,
3883    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3884    MatForwardSolve() solves U^T*D y = b, and
3885    MatBackwardSolve() solves U x = y.
3886    Thus they do not provide a symmetric preconditioner.
3887 
3888    Most users should employ the simplified KSP interface for linear solvers
3889    instead of working directly with matrix algebra routines such as this.
3890    See, e.g., KSPCreate().
3891 
3892    Level: developer
3893 
3894 .seealso: MatSolve(), MatForwardSolve()
3895 @*/
3896 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3897 {
3898   PetscErrorCode ierr;
3899 
3900   PetscFunctionBegin;
3901   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3902   PetscValidType(mat,1);
3903   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3904   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3905   PetscCheckSameComm(mat,1,b,2);
3906   PetscCheckSameComm(mat,1,x,3);
3907   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3908   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3909   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3910   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3911   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3912   MatCheckPreallocated(mat,1);
3913 
3914   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3915   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3916   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3917   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3918   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3919   PetscFunctionReturn(0);
3920 }
3921 
3922 /*@
3923    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3924 
3925    Neighbor-wise Collective on Mat
3926 
3927    Input Parameters:
3928 +  mat - the factored matrix
3929 .  b - the right-hand-side vector
3930 -  y - the vector to be added to
3931 
3932    Output Parameter:
3933 .  x - the result vector
3934 
3935    Notes:
3936    The vectors b and x cannot be the same.  I.e., one cannot
3937    call MatSolveAdd(A,x,y,x).
3938 
3939    Most users should employ the simplified KSP interface for linear solvers
3940    instead of working directly with matrix algebra routines such as this.
3941    See, e.g., KSPCreate().
3942 
3943    Level: developer
3944 
3945 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3946 @*/
3947 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3948 {
3949   PetscScalar    one = 1.0;
3950   Vec            tmp;
3951   PetscErrorCode ierr;
3952 
3953   PetscFunctionBegin;
3954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3955   PetscValidType(mat,1);
3956   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
3957   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3958   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3959   PetscCheckSameComm(mat,1,b,2);
3960   PetscCheckSameComm(mat,1,y,3);
3961   PetscCheckSameComm(mat,1,x,4);
3962   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3963   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3964   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3965   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3966   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3967   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3968   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3969    MatCheckPreallocated(mat,1);
3970 
3971   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3972   if (mat->factorerrortype) {
3973     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3974     ierr = VecSetInf(x);CHKERRQ(ierr);
3975   } else if (mat->ops->solveadd) {
3976     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3977   } else {
3978     /* do the solve then the add manually */
3979     if (x != y) {
3980       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3981       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3982     } else {
3983       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3984       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3985       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3986       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3987       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3988       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3989     }
3990   }
3991   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3992   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3993   PetscFunctionReturn(0);
3994 }
3995 
3996 /*@
3997    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3998 
3999    Neighbor-wise Collective on Mat
4000 
4001    Input Parameters:
4002 +  mat - the factored matrix
4003 -  b - the right-hand-side vector
4004 
4005    Output Parameter:
4006 .  x - the result vector
4007 
4008    Notes:
4009    The vectors b and x cannot be the same.  I.e., one cannot
4010    call MatSolveTranspose(A,x,x).
4011 
4012    Most users should employ the simplified KSP interface for linear solvers
4013    instead of working directly with matrix algebra routines such as this.
4014    See, e.g., KSPCreate().
4015 
4016    Level: developer
4017 
4018 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
4019 @*/
4020 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
4021 {
4022   PetscErrorCode ierr;
4023 
4024   PetscFunctionBegin;
4025   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4026   PetscValidType(mat,1);
4027   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4028   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4029   PetscCheckSameComm(mat,1,b,2);
4030   PetscCheckSameComm(mat,1,x,3);
4031   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
4032   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
4033   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
4034   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
4035   MatCheckPreallocated(mat,1);
4036   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
4037   if (mat->factorerrortype) {
4038     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
4039     ierr = VecSetInf(x);CHKERRQ(ierr);
4040   } else {
4041     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
4042     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
4043   }
4044   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
4045   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4046   PetscFunctionReturn(0);
4047 }
4048 
4049 /*@
4050    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
4051                       factored matrix.
4052 
4053    Neighbor-wise Collective on Mat
4054 
4055    Input Parameters:
4056 +  mat - the factored matrix
4057 .  b - the right-hand-side vector
4058 -  y - the vector to be added to
4059 
4060    Output Parameter:
4061 .  x - the result vector
4062 
4063    Notes:
4064    The vectors b and x cannot be the same.  I.e., one cannot
4065    call MatSolveTransposeAdd(A,x,y,x).
4066 
4067    Most users should employ the simplified KSP interface for linear solvers
4068    instead of working directly with matrix algebra routines such as this.
4069    See, e.g., KSPCreate().
4070 
4071    Level: developer
4072 
4073 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
4074 @*/
4075 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
4076 {
4077   PetscScalar    one = 1.0;
4078   PetscErrorCode ierr;
4079   Vec            tmp;
4080 
4081   PetscFunctionBegin;
4082   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4083   PetscValidType(mat,1);
4084   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
4085   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4086   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
4087   PetscCheckSameComm(mat,1,b,2);
4088   PetscCheckSameComm(mat,1,y,3);
4089   PetscCheckSameComm(mat,1,x,4);
4090   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
4091   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
4092   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
4093   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
4094   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
4095   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
4096    MatCheckPreallocated(mat,1);
4097 
4098   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
4099   if (mat->factorerrortype) {
4100     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
4101     ierr = VecSetInf(x);CHKERRQ(ierr);
4102   } else if (mat->ops->solvetransposeadd){
4103     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
4104   } else {
4105     /* do the solve then the add manually */
4106     if (x != y) {
4107       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
4108       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
4109     } else {
4110       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
4111       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
4112       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
4113       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
4114       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
4115       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
4116     }
4117   }
4118   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
4119   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4120   PetscFunctionReturn(0);
4121 }
4122 /* ----------------------------------------------------------------*/
4123 
4124 /*@
4125    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
4126 
4127    Neighbor-wise Collective on Mat
4128 
4129    Input Parameters:
4130 +  mat - the matrix
4131 .  b - the right hand side
4132 .  omega - the relaxation factor
4133 .  flag - flag indicating the type of SOR (see below)
4134 .  shift -  diagonal shift
4135 .  its - the number of iterations
4136 -  lits - the number of local iterations
4137 
4138    Output Parameters:
4139 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
4140 
4141    SOR Flags:
4142 +     SOR_FORWARD_SWEEP - forward SOR
4143 .     SOR_BACKWARD_SWEEP - backward SOR
4144 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
4145 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
4146 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
4147 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
4148 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
4149          upper/lower triangular part of matrix to
4150          vector (with omega)
4151 -     SOR_ZERO_INITIAL_GUESS - zero initial guess
4152 
4153    Notes:
4154    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
4155    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
4156    on each processor.
4157 
4158    Application programmers will not generally use MatSOR() directly,
4159    but instead will employ the KSP/PC interface.
4160 
4161    Notes:
4162     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
4163 
4164    Notes for Advanced Users:
4165    The flags are implemented as bitwise inclusive or operations.
4166    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
4167    to specify a zero initial guess for SSOR.
4168 
4169    Most users should employ the simplified KSP interface for linear solvers
4170    instead of working directly with matrix algebra routines such as this.
4171    See, e.g., KSPCreate().
4172 
4173    Vectors x and b CANNOT be the same
4174 
4175    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
4176 
4177    Level: developer
4178 
4179 @*/
4180 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4181 {
4182   PetscErrorCode ierr;
4183 
4184   PetscFunctionBegin;
4185   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4186   PetscValidType(mat,1);
4187   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4188   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4189   PetscCheckSameComm(mat,1,b,2);
4190   PetscCheckSameComm(mat,1,x,8);
4191   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4192   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4193   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4194   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
4195   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
4196   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
4197   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4198   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4199   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4200 
4201   MatCheckPreallocated(mat,1);
4202   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4203   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4204   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4205   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4206   PetscFunctionReturn(0);
4207 }
4208 
4209 /*
4210       Default matrix copy routine.
4211 */
4212 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4213 {
4214   PetscErrorCode    ierr;
4215   PetscInt          i,rstart = 0,rend = 0,nz;
4216   const PetscInt    *cwork;
4217   const PetscScalar *vwork;
4218 
4219   PetscFunctionBegin;
4220   if (B->assembled) {
4221     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4222   }
4223   if (str == SAME_NONZERO_PATTERN) {
4224     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4225     for (i=rstart; i<rend; i++) {
4226       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4227       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4228       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4229     }
4230   } else {
4231     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4232   }
4233   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4234   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4235   PetscFunctionReturn(0);
4236 }
4237 
4238 /*@
4239    MatCopy - Copies a matrix to another matrix.
4240 
4241    Collective on Mat
4242 
4243    Input Parameters:
4244 +  A - the matrix
4245 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4246 
4247    Output Parameter:
4248 .  B - where the copy is put
4249 
4250    Notes:
4251    If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash.
4252 
4253    MatCopy() copies the matrix entries of a matrix to another existing
4254    matrix (after first zeroing the second matrix).  A related routine is
4255    MatConvert(), which first creates a new matrix and then copies the data.
4256 
4257    Level: intermediate
4258 
4259 .seealso: MatConvert(), MatDuplicate()
4260 
4261 @*/
4262 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4263 {
4264   PetscErrorCode ierr;
4265   PetscInt       i;
4266 
4267   PetscFunctionBegin;
4268   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4269   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4270   PetscValidType(A,1);
4271   PetscValidType(B,2);
4272   PetscCheckSameComm(A,1,B,2);
4273   MatCheckPreallocated(B,2);
4274   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4275   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4276   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4277   MatCheckPreallocated(A,1);
4278   if (A == B) PetscFunctionReturn(0);
4279 
4280   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4281   if (A->ops->copy) {
4282     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4283   } else { /* generic conversion */
4284     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4285   }
4286 
4287   B->stencil.dim = A->stencil.dim;
4288   B->stencil.noc = A->stencil.noc;
4289   for (i=0; i<=A->stencil.dim; i++) {
4290     B->stencil.dims[i]   = A->stencil.dims[i];
4291     B->stencil.starts[i] = A->stencil.starts[i];
4292   }
4293 
4294   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4295   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4296   PetscFunctionReturn(0);
4297 }
4298 
4299 /*@C
4300    MatConvert - Converts a matrix to another matrix, either of the same
4301    or different type.
4302 
4303    Collective on Mat
4304 
4305    Input Parameters:
4306 +  mat - the matrix
4307 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4308    same type as the original matrix.
4309 -  reuse - denotes if the destination matrix is to be created or reused.
4310    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
4311    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).
4312 
4313    Output Parameter:
4314 .  M - pointer to place new matrix
4315 
4316    Notes:
4317    MatConvert() first creates a new matrix and then copies the data from
4318    the first matrix.  A related routine is MatCopy(), which copies the matrix
4319    entries of one matrix to another already existing matrix context.
4320 
4321    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4322    the MPI communicator of the generated matrix is always the same as the communicator
4323    of the input matrix.
4324 
4325    Level: intermediate
4326 
4327 .seealso: MatCopy(), MatDuplicate()
4328 @*/
4329 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4330 {
4331   PetscErrorCode ierr;
4332   PetscBool      sametype,issame,flg,issymmetric,ishermitian;
4333   char           convname[256],mtype[256];
4334   Mat            B;
4335 
4336   PetscFunctionBegin;
4337   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4338   PetscValidType(mat,1);
4339   PetscValidPointer(M,4);
4340   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4341   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4342   MatCheckPreallocated(mat,1);
4343 
4344   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg);CHKERRQ(ierr);
4345   if (flg) newtype = mtype;
4346 
4347   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4348   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4349   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4350   if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
4351 
4352   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4353     ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4354     PetscFunctionReturn(0);
4355   }
4356 
4357   /* Cache Mat options because some converter use MatHeaderReplace  */
4358   issymmetric = mat->symmetric;
4359   ishermitian = mat->hermitian;
4360 
4361   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4362     ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4363     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4364   } else {
4365     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4366     const char     *prefix[3] = {"seq","mpi",""};
4367     PetscInt       i;
4368     /*
4369        Order of precedence:
4370        0) See if newtype is a superclass of the current matrix.
4371        1) See if a specialized converter is known to the current matrix.
4372        2) See if a specialized converter is known to the desired matrix class.
4373        3) See if a good general converter is registered for the desired class
4374           (as of 6/27/03 only MATMPIADJ falls into this category).
4375        4) See if a good general converter is known for the current matrix.
4376        5) Use a really basic converter.
4377     */
4378 
4379     /* 0) See if newtype is a superclass of the current matrix.
4380           i.e mat is mpiaij and newtype is aij */
4381     for (i=0; i<2; i++) {
4382       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4383       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4384       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4385       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4386       if (flg) {
4387         if (reuse == MAT_INPLACE_MATRIX) {
4388           ierr = PetscInfo(mat,"Early return\n");CHKERRQ(ierr);
4389           PetscFunctionReturn(0);
4390         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4391           ierr = PetscInfo(mat,"Calling MatDuplicate\n");CHKERRQ(ierr);
4392           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4393           PetscFunctionReturn(0);
4394         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4395           ierr = PetscInfo(mat,"Calling MatCopy\n");CHKERRQ(ierr);
4396           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4397           PetscFunctionReturn(0);
4398         }
4399       }
4400     }
4401     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4402     for (i=0; i<3; i++) {
4403       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4404       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4405       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4406       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4407       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4408       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4409       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4410       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4411       if (conv) goto foundconv;
4412     }
4413 
4414     /* 2)  See if a specialized converter is known to the desired matrix class. */
4415     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4416     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4417     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
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,newtype,sizeof(convname));CHKERRQ(ierr);
4424       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4425       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4426       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4427       if (conv) {
4428         ierr = MatDestroy(&B);CHKERRQ(ierr);
4429         goto foundconv;
4430       }
4431     }
4432 
4433     /* 3) See if a good general converter is registered for the desired class */
4434     conv = B->ops->convertfrom;
4435     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4436     ierr = MatDestroy(&B);CHKERRQ(ierr);
4437     if (conv) goto foundconv;
4438 
4439     /* 4) See if a good general converter is known for the current matrix */
4440     if (mat->ops->convert) conv = mat->ops->convert;
4441 
4442     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4443     if (conv) goto foundconv;
4444 
4445     /* 5) Use a really basic converter. */
4446     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4447     conv = MatConvert_Basic;
4448 
4449 foundconv:
4450     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4451     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4452     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4453       /* the block sizes must be same if the mappings are copied over */
4454       (*M)->rmap->bs = mat->rmap->bs;
4455       (*M)->cmap->bs = mat->cmap->bs;
4456       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4457       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4458       (*M)->rmap->mapping = mat->rmap->mapping;
4459       (*M)->cmap->mapping = mat->cmap->mapping;
4460     }
4461     (*M)->stencil.dim = mat->stencil.dim;
4462     (*M)->stencil.noc = mat->stencil.noc;
4463     for (i=0; i<=mat->stencil.dim; i++) {
4464       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4465       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4466     }
4467     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4468   }
4469   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4470 
4471   /* Copy Mat options */
4472   if (issymmetric) {
4473     ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
4474   }
4475   if (ishermitian) {
4476     ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
4477   }
4478   PetscFunctionReturn(0);
4479 }
4480 
4481 /*@C
4482    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4483 
4484    Not Collective
4485 
4486    Input Parameter:
4487 .  mat - the matrix, must be a factored matrix
4488 
4489    Output Parameter:
4490 .   type - the string name of the package (do not free this string)
4491 
4492    Notes:
4493       In Fortran you pass in a empty string and the package name will be copied into it.
4494     (Make sure the string is long enough)
4495 
4496    Level: intermediate
4497 
4498 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4499 @*/
4500 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4501 {
4502   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4503 
4504   PetscFunctionBegin;
4505   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4506   PetscValidType(mat,1);
4507   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4508   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4509   if (!conv) {
4510     *type = MATSOLVERPETSC;
4511   } else {
4512     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4513   }
4514   PetscFunctionReturn(0);
4515 }
4516 
4517 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4518 struct _MatSolverTypeForSpecifcType {
4519   MatType                        mtype;
4520   PetscErrorCode                 (*createfactor[MAT_FACTOR_NUM_TYPES])(Mat,MatFactorType,Mat*);
4521   MatSolverTypeForSpecifcType next;
4522 };
4523 
4524 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4525 struct _MatSolverTypeHolder {
4526   char                        *name;
4527   MatSolverTypeForSpecifcType handlers;
4528   MatSolverTypeHolder         next;
4529 };
4530 
4531 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4532 
4533 /*@C
4534    MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type
4535 
4536    Input Parameters:
4537 +    package - name of the package, for example petsc or superlu
4538 .    mtype - the matrix type that works with this package
4539 .    ftype - the type of factorization supported by the package
4540 -    createfactor - routine that will create the factored matrix ready to be used
4541 
4542     Level: intermediate
4543 
4544 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4545 @*/
4546 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*))
4547 {
4548   PetscErrorCode              ierr;
4549   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4550   PetscBool                   flg;
4551   MatSolverTypeForSpecifcType inext,iprev = NULL;
4552 
4553   PetscFunctionBegin;
4554   ierr = MatInitializePackage();CHKERRQ(ierr);
4555   if (!next) {
4556     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4557     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4558     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4559     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4560     MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor;
4561     PetscFunctionReturn(0);
4562   }
4563   while (next) {
4564     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4565     if (flg) {
4566       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4567       inext = next->handlers;
4568       while (inext) {
4569         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4570         if (flg) {
4571           inext->createfactor[(int)ftype-1] = createfactor;
4572           PetscFunctionReturn(0);
4573         }
4574         iprev = inext;
4575         inext = inext->next;
4576       }
4577       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4578       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4579       iprev->next->createfactor[(int)ftype-1] = createfactor;
4580       PetscFunctionReturn(0);
4581     }
4582     prev = next;
4583     next = next->next;
4584   }
4585   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4586   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4587   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4588   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4589   prev->next->handlers->createfactor[(int)ftype-1] = createfactor;
4590   PetscFunctionReturn(0);
4591 }
4592 
4593 /*@C
4594    MatSolveTypeGet - Gets the function that creates the factor matrix if it exist
4595 
4596    Input Parameters:
4597 +    type - name of the package, for example petsc or superlu
4598 .    ftype - the type of factorization supported by the type
4599 -    mtype - the matrix type that works with this type
4600 
4601    Output Parameters:
4602 +   foundtype - PETSC_TRUE if the type was registered
4603 .   foundmtype - PETSC_TRUE if the type supports the requested mtype
4604 -   createfactor - routine that will create the factored matrix ready to be used or NULL if not found
4605 
4606     Level: intermediate
4607 
4608 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatSolverTypeRegister(), MatGetFactor()
4609 @*/
4610 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*))
4611 {
4612   PetscErrorCode              ierr;
4613   MatSolverTypeHolder         next = MatSolverTypeHolders;
4614   PetscBool                   flg;
4615   MatSolverTypeForSpecifcType inext;
4616 
4617   PetscFunctionBegin;
4618   if (foundtype) *foundtype = PETSC_FALSE;
4619   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4620   if (createfactor) *createfactor    = NULL;
4621 
4622   if (type) {
4623     while (next) {
4624       ierr = PetscStrcasecmp(type,next->name,&flg);CHKERRQ(ierr);
4625       if (flg) {
4626         if (foundtype) *foundtype = PETSC_TRUE;
4627         inext = next->handlers;
4628         while (inext) {
4629           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4630           if (flg) {
4631             if (foundmtype) *foundmtype = PETSC_TRUE;
4632             if (createfactor)  *createfactor  = inext->createfactor[(int)ftype-1];
4633             PetscFunctionReturn(0);
4634           }
4635           inext = inext->next;
4636         }
4637       }
4638       next = next->next;
4639     }
4640   } else {
4641     while (next) {
4642       inext = next->handlers;
4643       while (inext) {
4644         ierr = PetscStrcmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4645         if (flg && inext->createfactor[(int)ftype-1]) {
4646           if (foundtype) *foundtype = PETSC_TRUE;
4647           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4648           if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4649           PetscFunctionReturn(0);
4650         }
4651         inext = inext->next;
4652       }
4653       next = next->next;
4654     }
4655     /* try with base classes inext->mtype */
4656     next = MatSolverTypeHolders;
4657     while (next) {
4658       inext = next->handlers;
4659       while (inext) {
4660         ierr = PetscStrbeginswith(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   }
4672   PetscFunctionReturn(0);
4673 }
4674 
4675 PetscErrorCode MatSolverTypeDestroy(void)
4676 {
4677   PetscErrorCode              ierr;
4678   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4679   MatSolverTypeForSpecifcType inext,iprev;
4680 
4681   PetscFunctionBegin;
4682   while (next) {
4683     ierr = PetscFree(next->name);CHKERRQ(ierr);
4684     inext = next->handlers;
4685     while (inext) {
4686       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4687       iprev = inext;
4688       inext = inext->next;
4689       ierr = PetscFree(iprev);CHKERRQ(ierr);
4690     }
4691     prev = next;
4692     next = next->next;
4693     ierr = PetscFree(prev);CHKERRQ(ierr);
4694   }
4695   MatSolverTypeHolders = NULL;
4696   PetscFunctionReturn(0);
4697 }
4698 
4699 /*@C
4700    MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4701 
4702    Logically Collective on Mat
4703 
4704    Input Parameters:
4705 .  mat - the matrix
4706 
4707    Output Parameters:
4708 .  flg - PETSC_TRUE if uses the ordering
4709 
4710    Notes:
4711       Most internal PETSc factorizations use the ordering passed to the factorization routine but external
4712       packages do not, thus we want to skip generating the ordering when it is not needed or used.
4713 
4714    Level: developer
4715 
4716 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4717 @*/
4718 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg)
4719 {
4720   PetscFunctionBegin;
4721   *flg = mat->canuseordering;
4722   PetscFunctionReturn(0);
4723 }
4724 
4725 /*@C
4726    MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object
4727 
4728    Logically Collective on Mat
4729 
4730    Input Parameters:
4731 .  mat - the matrix
4732 
4733    Output Parameters:
4734 .  otype - the preferred type
4735 
4736    Level: developer
4737 
4738 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4739 @*/
4740 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype)
4741 {
4742   PetscFunctionBegin;
4743   *otype = mat->preferredordering[ftype];
4744   if (!*otype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering");
4745   PetscFunctionReturn(0);
4746 }
4747 
4748 /*@C
4749    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4750 
4751    Collective on Mat
4752 
4753    Input Parameters:
4754 +  mat - the matrix
4755 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4756 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4757 
4758    Output Parameters:
4759 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4760 
4761    Notes:
4762       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4763      such as pastix, superlu, mumps etc.
4764 
4765       PETSc must have been ./configure to use the external solver, using the option --download-package
4766 
4767    Developer Notes:
4768       This should actually be called MatCreateFactor() since it creates a new factor object
4769 
4770    Level: intermediate
4771 
4772 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatFactorGetCanUseOrdering(), MatSolverTypeRegister()
4773 @*/
4774 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4775 {
4776   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4777   PetscBool      foundtype,foundmtype;
4778 
4779   PetscFunctionBegin;
4780   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4781   PetscValidType(mat,1);
4782 
4783   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4784   MatCheckPreallocated(mat,1);
4785 
4786   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv);CHKERRQ(ierr);
4787   if (!foundtype) {
4788     if (type) {
4789       SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver type %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type);
4790     } else {
4791       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver type for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4792     }
4793   }
4794   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4795   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4796 
4797   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4798   PetscFunctionReturn(0);
4799 }
4800 
4801 /*@C
4802    MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type
4803 
4804    Not Collective
4805 
4806    Input Parameters:
4807 +  mat - the matrix
4808 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4809 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4810 
4811    Output Parameter:
4812 .    flg - PETSC_TRUE if the factorization is available
4813 
4814    Notes:
4815       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4816      such as pastix, superlu, mumps etc.
4817 
4818       PETSc must have been ./configure to use the external solver, using the option --download-package
4819 
4820    Developer Notes:
4821       This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object
4822 
4823    Level: intermediate
4824 
4825 .seealso: MatCopy(), MatDuplicate(), MatGetFactor(), MatSolverTypeRegister()
4826 @*/
4827 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4828 {
4829   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4830 
4831   PetscFunctionBegin;
4832   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4833   PetscValidType(mat,1);
4834 
4835   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4836   MatCheckPreallocated(mat,1);
4837 
4838   *flg = PETSC_FALSE;
4839   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4840   if (gconv) {
4841     *flg = PETSC_TRUE;
4842   }
4843   PetscFunctionReturn(0);
4844 }
4845 
4846 #include <petscdmtypes.h>
4847 
4848 /*@
4849    MatDuplicate - Duplicates a matrix including the non-zero structure.
4850 
4851    Collective on Mat
4852 
4853    Input Parameters:
4854 +  mat - the matrix
4855 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4856         See the manual page for MatDuplicateOption for an explanation of these options.
4857 
4858    Output Parameter:
4859 .  M - pointer to place new matrix
4860 
4861    Level: intermediate
4862 
4863    Notes:
4864     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4865     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.
4866 
4867 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4868 @*/
4869 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4870 {
4871   PetscErrorCode ierr;
4872   Mat            B;
4873   PetscInt       i;
4874   DM             dm;
4875   void           (*viewf)(void);
4876 
4877   PetscFunctionBegin;
4878   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4879   PetscValidType(mat,1);
4880   PetscValidPointer(M,3);
4881   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4882   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4883   MatCheckPreallocated(mat,1);
4884 
4885   *M = NULL;
4886   if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name);
4887   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4888   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4889   B    = *M;
4890 
4891   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4892   if (viewf) {
4893     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4894   }
4895 
4896   B->stencil.dim = mat->stencil.dim;
4897   B->stencil.noc = mat->stencil.noc;
4898   for (i=0; i<=mat->stencil.dim; i++) {
4899     B->stencil.dims[i]   = mat->stencil.dims[i];
4900     B->stencil.starts[i] = mat->stencil.starts[i];
4901   }
4902 
4903   B->nooffproczerorows = mat->nooffproczerorows;
4904   B->nooffprocentries  = mat->nooffprocentries;
4905 
4906   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4907   if (dm) {
4908     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4909   }
4910   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4911   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4912   PetscFunctionReturn(0);
4913 }
4914 
4915 /*@
4916    MatGetDiagonal - Gets the diagonal of a matrix.
4917 
4918    Logically Collective on Mat
4919 
4920    Input Parameters:
4921 +  mat - the matrix
4922 -  v - the vector for storing the diagonal
4923 
4924    Output Parameter:
4925 .  v - the diagonal of the matrix
4926 
4927    Level: intermediate
4928 
4929    Note:
4930    Currently only correct in parallel for square matrices.
4931 
4932 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4933 @*/
4934 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4935 {
4936   PetscErrorCode ierr;
4937 
4938   PetscFunctionBegin;
4939   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4940   PetscValidType(mat,1);
4941   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4942   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4943   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4944   MatCheckPreallocated(mat,1);
4945 
4946   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4947   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4948   PetscFunctionReturn(0);
4949 }
4950 
4951 /*@C
4952    MatGetRowMin - Gets the minimum value (of the real part) of each
4953         row of the matrix
4954 
4955    Logically Collective on Mat
4956 
4957    Input Parameters:
4958 .  mat - the matrix
4959 
4960    Output Parameter:
4961 +  v - the vector for storing the maximums
4962 -  idx - the indices of the column found for each row (optional)
4963 
4964    Level: intermediate
4965 
4966    Notes:
4967     The result of this call are the same as if one converted the matrix to dense format
4968       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4969 
4970     This code is only implemented for a couple of matrix formats.
4971 
4972 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4973           MatGetRowMax()
4974 @*/
4975 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4976 {
4977   PetscErrorCode ierr;
4978 
4979   PetscFunctionBegin;
4980   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4981   PetscValidType(mat,1);
4982   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4983   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4984 
4985   if (!mat->cmap->N) {
4986     ierr = VecSet(v,PETSC_MAX_REAL);CHKERRQ(ierr);
4987     if (idx) {
4988       PetscInt i,m = mat->rmap->n;
4989       for (i=0; i<m; i++) idx[i] = -1;
4990     }
4991   } else {
4992     if (!mat->ops->getrowmin) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4993     MatCheckPreallocated(mat,1);
4994   }
4995   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4996   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4997   PetscFunctionReturn(0);
4998 }
4999 
5000 /*@C
5001    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
5002         row of the matrix
5003 
5004    Logically Collective on Mat
5005 
5006    Input Parameters:
5007 .  mat - the matrix
5008 
5009    Output Parameter:
5010 +  v - the vector for storing the minimums
5011 -  idx - the indices of the column found for each row (or NULL if not needed)
5012 
5013    Level: intermediate
5014 
5015    Notes:
5016     if a row is completely empty or has only 0.0 values then the idx[] value for that
5017     row is 0 (the first column).
5018 
5019     This code is only implemented for a couple of matrix formats.
5020 
5021 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
5022 @*/
5023 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
5024 {
5025   PetscErrorCode ierr;
5026 
5027   PetscFunctionBegin;
5028   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5029   PetscValidType(mat,1);
5030   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5031   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5032   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5033 
5034   if (!mat->cmap->N) {
5035     ierr = VecSet(v,0.0);CHKERRQ(ierr);
5036     if (idx) {
5037       PetscInt i,m = mat->rmap->n;
5038       for (i=0; i<m; i++) idx[i] = -1;
5039     }
5040   } else {
5041     if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5042     MatCheckPreallocated(mat,1);
5043     if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
5044     ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
5045   }
5046   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5047   PetscFunctionReturn(0);
5048 }
5049 
5050 /*@C
5051    MatGetRowMax - Gets the maximum value (of the real part) of each
5052         row of the matrix
5053 
5054    Logically Collective on Mat
5055 
5056    Input Parameters:
5057 .  mat - the matrix
5058 
5059    Output Parameter:
5060 +  v - the vector for storing the maximums
5061 -  idx - the indices of the column found for each row (optional)
5062 
5063    Level: intermediate
5064 
5065    Notes:
5066     The result of this call are the same as if one converted the matrix to dense format
5067       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
5068 
5069     This code is only implemented for a couple of matrix formats.
5070 
5071 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
5072 @*/
5073 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
5074 {
5075   PetscErrorCode ierr;
5076 
5077   PetscFunctionBegin;
5078   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5079   PetscValidType(mat,1);
5080   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5081   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5082 
5083   if (!mat->cmap->N) {
5084     ierr = VecSet(v,PETSC_MIN_REAL);CHKERRQ(ierr);
5085     if (idx) {
5086       PetscInt i,m = mat->rmap->n;
5087       for (i=0; i<m; i++) idx[i] = -1;
5088     }
5089   } else {
5090     if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5091     MatCheckPreallocated(mat,1);
5092     ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
5093   }
5094   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5095   PetscFunctionReturn(0);
5096 }
5097 
5098 /*@C
5099    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
5100         row of the matrix
5101 
5102    Logically Collective on Mat
5103 
5104    Input Parameters:
5105 .  mat - the matrix
5106 
5107    Output Parameter:
5108 +  v - the vector for storing the maximums
5109 -  idx - the indices of the column found for each row (or NULL if not needed)
5110 
5111    Level: intermediate
5112 
5113    Notes:
5114     if a row is completely empty or has only 0.0 values then the idx[] value for that
5115     row is 0 (the first column).
5116 
5117     This code is only implemented for a couple of matrix formats.
5118 
5119 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
5120 @*/
5121 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
5122 {
5123   PetscErrorCode ierr;
5124 
5125   PetscFunctionBegin;
5126   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5127   PetscValidType(mat,1);
5128   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5129   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5130 
5131   if (!mat->cmap->N) {
5132     ierr = VecSet(v,0.0);CHKERRQ(ierr);
5133     if (idx) {
5134       PetscInt i,m = mat->rmap->n;
5135       for (i=0; i<m; i++) idx[i] = -1;
5136     }
5137   } else {
5138     if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5139     MatCheckPreallocated(mat,1);
5140     if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
5141     ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
5142   }
5143   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5144   PetscFunctionReturn(0);
5145 }
5146 
5147 /*@
5148    MatGetRowSum - Gets the sum of each row of the matrix
5149 
5150    Logically or Neighborhood Collective on Mat
5151 
5152    Input Parameters:
5153 .  mat - the matrix
5154 
5155    Output Parameter:
5156 .  v - the vector for storing the sum of rows
5157 
5158    Level: intermediate
5159 
5160    Notes:
5161     This code is slow since it is not currently specialized for different formats
5162 
5163 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
5164 @*/
5165 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
5166 {
5167   Vec            ones;
5168   PetscErrorCode ierr;
5169 
5170   PetscFunctionBegin;
5171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5172   PetscValidType(mat,1);
5173   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5174   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5175   MatCheckPreallocated(mat,1);
5176   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
5177   ierr = VecSet(ones,1.);CHKERRQ(ierr);
5178   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
5179   ierr = VecDestroy(&ones);CHKERRQ(ierr);
5180   PetscFunctionReturn(0);
5181 }
5182 
5183 /*@
5184    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
5185 
5186    Collective on Mat
5187 
5188    Input Parameters:
5189 +  mat - the matrix to transpose
5190 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5191 
5192    Output Parameter:
5193 .  B - the transpose
5194 
5195    Notes:
5196      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
5197 
5198      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
5199 
5200      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
5201 
5202    Level: intermediate
5203 
5204 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5205 @*/
5206 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
5207 {
5208   PetscErrorCode ierr;
5209 
5210   PetscFunctionBegin;
5211   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5212   PetscValidType(mat,1);
5213   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5214   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5215   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5216   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
5217   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
5218   MatCheckPreallocated(mat,1);
5219 
5220   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
5221   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
5222   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
5223   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
5224   PetscFunctionReturn(0);
5225 }
5226 
5227 /*@
5228    MatIsTranspose - Test whether a matrix is another one's transpose,
5229         or its own, in which case it tests symmetry.
5230 
5231    Collective on Mat
5232 
5233    Input Parameter:
5234 +  A - the matrix to test
5235 -  B - the matrix to test against, this can equal the first parameter
5236 
5237    Output Parameters:
5238 .  flg - the result
5239 
5240    Notes:
5241    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5242    has a running time of the order of the number of nonzeros; the parallel
5243    test involves parallel copies of the block-offdiagonal parts of the matrix.
5244 
5245    Level: intermediate
5246 
5247 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
5248 @*/
5249 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5250 {
5251   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5252 
5253   PetscFunctionBegin;
5254   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5255   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5256   PetscValidBoolPointer(flg,4);
5257   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
5258   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
5259   *flg = PETSC_FALSE;
5260   if (f && g) {
5261     if (f == g) {
5262       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5263     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5264   } else {
5265     MatType mattype;
5266     if (!f) {
5267       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5268     } else {
5269       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5270     }
5271     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
5272   }
5273   PetscFunctionReturn(0);
5274 }
5275 
5276 /*@
5277    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5278 
5279    Collective on Mat
5280 
5281    Input Parameters:
5282 +  mat - the matrix to transpose and complex conjugate
5283 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5284 
5285    Output Parameter:
5286 .  B - the Hermitian
5287 
5288    Level: intermediate
5289 
5290 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5291 @*/
5292 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5293 {
5294   PetscErrorCode ierr;
5295 
5296   PetscFunctionBegin;
5297   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5298 #if defined(PETSC_USE_COMPLEX)
5299   ierr = MatConjugate(*B);CHKERRQ(ierr);
5300 #endif
5301   PetscFunctionReturn(0);
5302 }
5303 
5304 /*@
5305    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5306 
5307    Collective on Mat
5308 
5309    Input Parameter:
5310 +  A - the matrix to test
5311 -  B - the matrix to test against, this can equal the first parameter
5312 
5313    Output Parameters:
5314 .  flg - the result
5315 
5316    Notes:
5317    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5318    has a running time of the order of the number of nonzeros; the parallel
5319    test involves parallel copies of the block-offdiagonal parts of the matrix.
5320 
5321    Level: intermediate
5322 
5323 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5324 @*/
5325 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5326 {
5327   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5328 
5329   PetscFunctionBegin;
5330   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5331   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5332   PetscValidBoolPointer(flg,4);
5333   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5334   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5335   if (f && g) {
5336     if (f==g) {
5337       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5338     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5339   }
5340   PetscFunctionReturn(0);
5341 }
5342 
5343 /*@
5344    MatPermute - Creates a new matrix with rows and columns permuted from the
5345    original.
5346 
5347    Collective on Mat
5348 
5349    Input Parameters:
5350 +  mat - the matrix to permute
5351 .  row - row permutation, each processor supplies only the permutation for its rows
5352 -  col - column permutation, each processor supplies only the permutation for its columns
5353 
5354    Output Parameters:
5355 .  B - the permuted matrix
5356 
5357    Level: advanced
5358 
5359    Note:
5360    The index sets map from row/col of permuted matrix to row/col of original matrix.
5361    The index sets should be on the same communicator as Mat and have the same local sizes.
5362 
5363    Developer Note:
5364      If you want to implement MatPermute for a matrix type, and your approach doesn't
5365      exploit the fact that row and col are permutations, consider implementing the
5366      more general MatCreateSubMatrix() instead.
5367 
5368 .seealso: MatGetOrdering(), ISAllGather()
5369 
5370 @*/
5371 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5372 {
5373   PetscErrorCode ierr;
5374 
5375   PetscFunctionBegin;
5376   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5377   PetscValidType(mat,1);
5378   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5379   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5380   PetscValidPointer(B,4);
5381   PetscCheckSameComm(mat,1,row,2);
5382   if (row != col) PetscCheckSameComm(row,2,col,3);
5383   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5384   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5385   if (!mat->ops->permute && !mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5386   MatCheckPreallocated(mat,1);
5387 
5388   if (mat->ops->permute) {
5389     ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5390     ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5391   } else {
5392     ierr = MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B);CHKERRQ(ierr);
5393   }
5394   PetscFunctionReturn(0);
5395 }
5396 
5397 /*@
5398    MatEqual - Compares two matrices.
5399 
5400    Collective on Mat
5401 
5402    Input Parameters:
5403 +  A - the first matrix
5404 -  B - the second matrix
5405 
5406    Output Parameter:
5407 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5408 
5409    Level: intermediate
5410 
5411 @*/
5412 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5413 {
5414   PetscErrorCode ierr;
5415 
5416   PetscFunctionBegin;
5417   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5418   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5419   PetscValidType(A,1);
5420   PetscValidType(B,2);
5421   PetscValidBoolPointer(flg,3);
5422   PetscCheckSameComm(A,1,B,2);
5423   MatCheckPreallocated(B,2);
5424   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5425   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5426   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
5427   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5428   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5429   if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
5430   MatCheckPreallocated(A,1);
5431 
5432   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5433   PetscFunctionReturn(0);
5434 }
5435 
5436 /*@
5437    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5438    matrices that are stored as vectors.  Either of the two scaling
5439    matrices can be NULL.
5440 
5441    Collective on Mat
5442 
5443    Input Parameters:
5444 +  mat - the matrix to be scaled
5445 .  l - the left scaling vector (or NULL)
5446 -  r - the right scaling vector (or NULL)
5447 
5448    Notes:
5449    MatDiagonalScale() computes A = LAR, where
5450    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5451    The L scales the rows of the matrix, the R scales the columns of the matrix.
5452 
5453    Level: intermediate
5454 
5455 
5456 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5457 @*/
5458 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5459 {
5460   PetscErrorCode ierr;
5461 
5462   PetscFunctionBegin;
5463   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5464   PetscValidType(mat,1);
5465   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5466   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5467   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5468   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5469   MatCheckPreallocated(mat,1);
5470   if (!l && !r) PetscFunctionReturn(0);
5471 
5472   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5473   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5474   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5475   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5476   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5477   PetscFunctionReturn(0);
5478 }
5479 
5480 /*@
5481     MatScale - Scales all elements of a matrix by a given number.
5482 
5483     Logically Collective on Mat
5484 
5485     Input Parameters:
5486 +   mat - the matrix to be scaled
5487 -   a  - the scaling value
5488 
5489     Output Parameter:
5490 .   mat - the scaled matrix
5491 
5492     Level: intermediate
5493 
5494 .seealso: MatDiagonalScale()
5495 @*/
5496 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5497 {
5498   PetscErrorCode ierr;
5499 
5500   PetscFunctionBegin;
5501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5502   PetscValidType(mat,1);
5503   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5504   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5505   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5506   PetscValidLogicalCollectiveScalar(mat,a,2);
5507   MatCheckPreallocated(mat,1);
5508 
5509   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5510   if (a != (PetscScalar)1.0) {
5511     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5512     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5513   }
5514   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5515   PetscFunctionReturn(0);
5516 }
5517 
5518 /*@
5519    MatNorm - Calculates various norms of a matrix.
5520 
5521    Collective on Mat
5522 
5523    Input Parameters:
5524 +  mat - the matrix
5525 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5526 
5527    Output Parameters:
5528 .  nrm - the resulting norm
5529 
5530    Level: intermediate
5531 
5532 @*/
5533 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5534 {
5535   PetscErrorCode ierr;
5536 
5537   PetscFunctionBegin;
5538   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5539   PetscValidType(mat,1);
5540   PetscValidRealPointer(nrm,3);
5541 
5542   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5543   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5544   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5545   MatCheckPreallocated(mat,1);
5546 
5547   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5548   PetscFunctionReturn(0);
5549 }
5550 
5551 /*
5552      This variable is used to prevent counting of MatAssemblyBegin() that
5553    are called from within a MatAssemblyEnd().
5554 */
5555 static PetscInt MatAssemblyEnd_InUse = 0;
5556 /*@
5557    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5558    be called after completing all calls to MatSetValues().
5559 
5560    Collective on Mat
5561 
5562    Input Parameters:
5563 +  mat - the matrix
5564 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5565 
5566    Notes:
5567    MatSetValues() generally caches the values.  The matrix is ready to
5568    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5569    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5570    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5571    using the matrix.
5572 
5573    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5574    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
5575    a global collective operation requring all processes that share the matrix.
5576 
5577    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5578    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5579    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5580 
5581    Level: beginner
5582 
5583 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5584 @*/
5585 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5586 {
5587   PetscErrorCode ierr;
5588 
5589   PetscFunctionBegin;
5590   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5591   PetscValidType(mat,1);
5592   MatCheckPreallocated(mat,1);
5593   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5594   if (mat->assembled) {
5595     mat->was_assembled = PETSC_TRUE;
5596     mat->assembled     = PETSC_FALSE;
5597   }
5598 
5599   if (!MatAssemblyEnd_InUse) {
5600     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5601     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5602     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5603   } else if (mat->ops->assemblybegin) {
5604     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5605   }
5606   PetscFunctionReturn(0);
5607 }
5608 
5609 /*@
5610    MatAssembled - Indicates if a matrix has been assembled and is ready for
5611      use; for example, in matrix-vector product.
5612 
5613    Not Collective
5614 
5615    Input Parameter:
5616 .  mat - the matrix
5617 
5618    Output Parameter:
5619 .  assembled - PETSC_TRUE or PETSC_FALSE
5620 
5621    Level: advanced
5622 
5623 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5624 @*/
5625 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5626 {
5627   PetscFunctionBegin;
5628   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5629   PetscValidPointer(assembled,2);
5630   *assembled = mat->assembled;
5631   PetscFunctionReturn(0);
5632 }
5633 
5634 /*@
5635    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5636    be called after MatAssemblyBegin().
5637 
5638    Collective on Mat
5639 
5640    Input Parameters:
5641 +  mat - the matrix
5642 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5643 
5644    Options Database Keys:
5645 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5646 .  -mat_view ::ascii_info_detail - Prints more detailed info
5647 .  -mat_view - Prints matrix in ASCII format
5648 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5649 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5650 .  -display <name> - Sets display name (default is host)
5651 .  -draw_pause <sec> - Sets number of seconds to pause after display
5652 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab)
5653 .  -viewer_socket_machine <machine> - Machine to use for socket
5654 .  -viewer_socket_port <port> - Port number to use for socket
5655 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5656 
5657    Notes:
5658    MatSetValues() generally caches the values.  The matrix is ready to
5659    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5660    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5661    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5662    using the matrix.
5663 
5664    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5665    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5666    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5667 
5668    Level: beginner
5669 
5670 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5671 @*/
5672 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5673 {
5674   PetscErrorCode  ierr;
5675   static PetscInt inassm = 0;
5676   PetscBool       flg    = PETSC_FALSE;
5677 
5678   PetscFunctionBegin;
5679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5680   PetscValidType(mat,1);
5681 
5682   inassm++;
5683   MatAssemblyEnd_InUse++;
5684   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5685     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5686     if (mat->ops->assemblyend) {
5687       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5688     }
5689     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5690   } else if (mat->ops->assemblyend) {
5691     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5692   }
5693 
5694   /* Flush assembly is not a true assembly */
5695   if (type != MAT_FLUSH_ASSEMBLY) {
5696     mat->num_ass++;
5697     mat->assembled        = PETSC_TRUE;
5698     mat->ass_nonzerostate = mat->nonzerostate;
5699   }
5700 
5701   mat->insertmode = NOT_SET_VALUES;
5702   MatAssemblyEnd_InUse--;
5703   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5704   if (!mat->symmetric_eternal) {
5705     mat->symmetric_set              = PETSC_FALSE;
5706     mat->hermitian_set              = PETSC_FALSE;
5707     mat->structurally_symmetric_set = PETSC_FALSE;
5708   }
5709   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5710     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5711 
5712     if (mat->checksymmetryonassembly) {
5713       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5714       if (flg) {
5715         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5716       } else {
5717         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5718       }
5719     }
5720     if (mat->nullsp && mat->checknullspaceonassembly) {
5721       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5722     }
5723   }
5724   inassm--;
5725   PetscFunctionReturn(0);
5726 }
5727 
5728 /*@
5729    MatSetOption - Sets a parameter option for a matrix. Some options
5730    may be specific to certain storage formats.  Some options
5731    determine how values will be inserted (or added). Sorted,
5732    row-oriented input will generally assemble the fastest. The default
5733    is row-oriented.
5734 
5735    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5736 
5737    Input Parameters:
5738 +  mat - the matrix
5739 .  option - the option, one of those listed below (and possibly others),
5740 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5741 
5742   Options Describing Matrix Structure:
5743 +    MAT_SPD - symmetric positive definite
5744 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5745 .    MAT_HERMITIAN - transpose is the complex conjugation
5746 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5747 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5748                             you set to be kept with all future use of the matrix
5749                             including after MatAssemblyBegin/End() which could
5750                             potentially change the symmetry structure, i.e. you
5751                             KNOW the matrix will ALWAYS have the property you set.
5752                             Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian;
5753                             the relevant flags must be set independently.
5754 
5755 
5756    Options For Use with MatSetValues():
5757    Insert a logically dense subblock, which can be
5758 .    MAT_ROW_ORIENTED - row-oriented (default)
5759 
5760    Note these options reflect the data you pass in with MatSetValues(); it has
5761    nothing to do with how the data is stored internally in the matrix
5762    data structure.
5763 
5764    When (re)assembling a matrix, we can restrict the input for
5765    efficiency/debugging purposes.  These options include:
5766 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5767 .    MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated
5768 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5769 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5770 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5771 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5772         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5773         performance for very large process counts.
5774 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5775         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5776         functions, instead sending only neighbor messages.
5777 
5778    Notes:
5779    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5780 
5781    Some options are relevant only for particular matrix types and
5782    are thus ignored by others.  Other options are not supported by
5783    certain matrix types and will generate an error message if set.
5784 
5785    If using a Fortran 77 module to compute a matrix, one may need to
5786    use the column-oriented option (or convert to the row-oriented
5787    format).
5788 
5789    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5790    that would generate a new entry in the nonzero structure is instead
5791    ignored.  Thus, if memory has not alredy been allocated for this particular
5792    data, then the insertion is ignored. For dense matrices, in which
5793    the entire array is allocated, no entries are ever ignored.
5794    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5795 
5796    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5797    that would generate a new entry in the nonzero structure instead produces
5798    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
5799 
5800    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5801    that would generate a new entry that has not been preallocated will
5802    instead produce an error. (Currently supported for AIJ and BAIJ formats
5803    only.) This is a useful flag when debugging matrix memory preallocation.
5804    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5805 
5806    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5807    other processors should be dropped, rather than stashed.
5808    This is useful if you know that the "owning" processor is also
5809    always generating the correct matrix entries, so that PETSc need
5810    not transfer duplicate entries generated on another processor.
5811 
5812    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5813    searches during matrix assembly. When this flag is set, the hash table
5814    is created during the first Matrix Assembly. This hash table is
5815    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5816    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5817    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5818    supported by MATMPIBAIJ format only.
5819 
5820    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5821    are kept in the nonzero structure
5822 
5823    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5824    a zero location in the matrix
5825 
5826    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5827 
5828    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5829         zero row routines and thus improves performance for very large process counts.
5830 
5831    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5832         part of the matrix (since they should match the upper triangular part).
5833 
5834    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5835                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5836                      with finite difference schemes with non-periodic boundary conditions.
5837 
5838    Level: intermediate
5839 
5840 .seealso:  MatOption, Mat
5841 
5842 @*/
5843 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5844 {
5845   PetscErrorCode ierr;
5846 
5847   PetscFunctionBegin;
5848   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5849   if (op > 0) {
5850     PetscValidLogicalCollectiveEnum(mat,op,2);
5851     PetscValidLogicalCollectiveBool(mat,flg,3);
5852   }
5853 
5854   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5855 
5856   switch (op) {
5857   case MAT_FORCE_DIAGONAL_ENTRIES:
5858     mat->force_diagonals = flg;
5859     PetscFunctionReturn(0);
5860   case MAT_NO_OFF_PROC_ENTRIES:
5861     mat->nooffprocentries = flg;
5862     PetscFunctionReturn(0);
5863   case MAT_SUBSET_OFF_PROC_ENTRIES:
5864     mat->assembly_subset = flg;
5865     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5866 #if !defined(PETSC_HAVE_MPIUNI)
5867       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5868 #endif
5869       mat->stash.first_assembly_done = PETSC_FALSE;
5870     }
5871     PetscFunctionReturn(0);
5872   case MAT_NO_OFF_PROC_ZERO_ROWS:
5873     mat->nooffproczerorows = flg;
5874     PetscFunctionReturn(0);
5875   case MAT_SPD:
5876     mat->spd_set = PETSC_TRUE;
5877     mat->spd     = flg;
5878     if (flg) {
5879       mat->symmetric                  = PETSC_TRUE;
5880       mat->structurally_symmetric     = PETSC_TRUE;
5881       mat->symmetric_set              = PETSC_TRUE;
5882       mat->structurally_symmetric_set = PETSC_TRUE;
5883     }
5884     break;
5885   case MAT_SYMMETRIC:
5886     mat->symmetric = flg;
5887     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5888     mat->symmetric_set              = PETSC_TRUE;
5889     mat->structurally_symmetric_set = flg;
5890 #if !defined(PETSC_USE_COMPLEX)
5891     mat->hermitian     = flg;
5892     mat->hermitian_set = PETSC_TRUE;
5893 #endif
5894     break;
5895   case MAT_HERMITIAN:
5896     mat->hermitian = flg;
5897     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5898     mat->hermitian_set              = PETSC_TRUE;
5899     mat->structurally_symmetric_set = flg;
5900 #if !defined(PETSC_USE_COMPLEX)
5901     mat->symmetric     = flg;
5902     mat->symmetric_set = PETSC_TRUE;
5903 #endif
5904     break;
5905   case MAT_STRUCTURALLY_SYMMETRIC:
5906     mat->structurally_symmetric     = flg;
5907     mat->structurally_symmetric_set = PETSC_TRUE;
5908     break;
5909   case MAT_SYMMETRY_ETERNAL:
5910     mat->symmetric_eternal = flg;
5911     break;
5912   case MAT_STRUCTURE_ONLY:
5913     mat->structure_only = flg;
5914     break;
5915   case MAT_SORTED_FULL:
5916     mat->sortedfull = flg;
5917     break;
5918   default:
5919     break;
5920   }
5921   if (mat->ops->setoption) {
5922     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5923   }
5924   PetscFunctionReturn(0);
5925 }
5926 
5927 /*@
5928    MatGetOption - Gets a parameter option that has been set for a matrix.
5929 
5930    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5931 
5932    Input Parameters:
5933 +  mat - the matrix
5934 -  option - the option, this only responds to certain options, check the code for which ones
5935 
5936    Output Parameter:
5937 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5938 
5939     Notes:
5940     Can only be called after MatSetSizes() and MatSetType() have been set.
5941 
5942    Level: intermediate
5943 
5944 .seealso:  MatOption, MatSetOption()
5945 
5946 @*/
5947 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5948 {
5949   PetscFunctionBegin;
5950   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5951   PetscValidType(mat,1);
5952 
5953   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5954   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5955 
5956   switch (op) {
5957   case MAT_NO_OFF_PROC_ENTRIES:
5958     *flg = mat->nooffprocentries;
5959     break;
5960   case MAT_NO_OFF_PROC_ZERO_ROWS:
5961     *flg = mat->nooffproczerorows;
5962     break;
5963   case MAT_SYMMETRIC:
5964     *flg = mat->symmetric;
5965     break;
5966   case MAT_HERMITIAN:
5967     *flg = mat->hermitian;
5968     break;
5969   case MAT_STRUCTURALLY_SYMMETRIC:
5970     *flg = mat->structurally_symmetric;
5971     break;
5972   case MAT_SYMMETRY_ETERNAL:
5973     *flg = mat->symmetric_eternal;
5974     break;
5975   case MAT_SPD:
5976     *flg = mat->spd;
5977     break;
5978   default:
5979     break;
5980   }
5981   PetscFunctionReturn(0);
5982 }
5983 
5984 /*@
5985    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5986    this routine retains the old nonzero structure.
5987 
5988    Logically Collective on Mat
5989 
5990    Input Parameters:
5991 .  mat - the matrix
5992 
5993    Level: intermediate
5994 
5995    Notes:
5996     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.
5997    See the Performance chapter of the users manual for information on preallocating matrices.
5998 
5999 .seealso: MatZeroRows()
6000 @*/
6001 PetscErrorCode MatZeroEntries(Mat mat)
6002 {
6003   PetscErrorCode ierr;
6004 
6005   PetscFunctionBegin;
6006   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6007   PetscValidType(mat,1);
6008   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6009   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
6010   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6011   MatCheckPreallocated(mat,1);
6012 
6013   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
6014   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
6015   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
6016   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6017   PetscFunctionReturn(0);
6018 }
6019 
6020 /*@
6021    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
6022    of a set of rows and columns of a matrix.
6023 
6024    Collective on Mat
6025 
6026    Input Parameters:
6027 +  mat - the matrix
6028 .  numRows - the number of rows to remove
6029 .  rows - the global row indices
6030 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6031 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6032 -  b - optional vector of right hand side, that will be adjusted by provided solution
6033 
6034    Notes:
6035    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
6036 
6037    The user can set a value in the diagonal entry (or for the AIJ and
6038    row formats can optionally remove the main diagonal entry from the
6039    nonzero structure as well, by passing 0.0 as the final argument).
6040 
6041    For the parallel case, all processes that share the matrix (i.e.,
6042    those in the communicator used for matrix creation) MUST call this
6043    routine, regardless of whether any rows being zeroed are owned by
6044    them.
6045 
6046    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6047    list only rows local to itself).
6048 
6049    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
6050 
6051    Level: intermediate
6052 
6053 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6054           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6055 @*/
6056 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6057 {
6058   PetscErrorCode ierr;
6059 
6060   PetscFunctionBegin;
6061   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6062   PetscValidType(mat,1);
6063   if (numRows) PetscValidIntPointer(rows,3);
6064   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6065   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6066   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6067   MatCheckPreallocated(mat,1);
6068 
6069   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6070   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
6071   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6072   PetscFunctionReturn(0);
6073 }
6074 
6075 /*@
6076    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
6077    of a set of rows and columns of a matrix.
6078 
6079    Collective on Mat
6080 
6081    Input Parameters:
6082 +  mat - the matrix
6083 .  is - the rows to zero
6084 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6085 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6086 -  b - optional vector of right hand side, that will be adjusted by provided solution
6087 
6088    Notes:
6089    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
6090 
6091    The user can set a value in the diagonal entry (or for the AIJ and
6092    row formats can optionally remove the main diagonal entry from the
6093    nonzero structure as well, by passing 0.0 as the final argument).
6094 
6095    For the parallel case, all processes that share the matrix (i.e.,
6096    those in the communicator used for matrix creation) MUST call this
6097    routine, regardless of whether any rows being zeroed are owned by
6098    them.
6099 
6100    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6101    list only rows local to itself).
6102 
6103    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
6104 
6105    Level: intermediate
6106 
6107 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6108           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
6109 @*/
6110 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6111 {
6112   PetscErrorCode ierr;
6113   PetscInt       numRows;
6114   const PetscInt *rows;
6115 
6116   PetscFunctionBegin;
6117   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6118   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6119   PetscValidType(mat,1);
6120   PetscValidType(is,2);
6121   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6122   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6123   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6124   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6125   PetscFunctionReturn(0);
6126 }
6127 
6128 /*@
6129    MatZeroRows - Zeros all entries (except possibly the main diagonal)
6130    of a set of rows of a matrix.
6131 
6132    Collective on Mat
6133 
6134    Input Parameters:
6135 +  mat - the matrix
6136 .  numRows - the number of rows to remove
6137 .  rows - the global row indices
6138 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6139 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6140 -  b - optional vector of right hand side, that will be adjusted by provided solution
6141 
6142    Notes:
6143    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6144    but does not release memory.  For the dense and block diagonal
6145    formats this does not alter the nonzero structure.
6146 
6147    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6148    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6149    merely zeroed.
6150 
6151    The user can set a value in the diagonal entry (or for the AIJ and
6152    row formats can optionally remove the main diagonal entry from the
6153    nonzero structure as well, by passing 0.0 as the final argument).
6154 
6155    For the parallel case, all processes that share the matrix (i.e.,
6156    those in the communicator used for matrix creation) MUST call this
6157    routine, regardless of whether any rows being zeroed are owned by
6158    them.
6159 
6160    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6161    list only rows local to itself).
6162 
6163    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6164    owns that are to be zeroed. This saves a global synchronization in the implementation.
6165 
6166    Level: intermediate
6167 
6168 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6169           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6170 @*/
6171 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6172 {
6173   PetscErrorCode ierr;
6174 
6175   PetscFunctionBegin;
6176   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6177   PetscValidType(mat,1);
6178   if (numRows) PetscValidIntPointer(rows,3);
6179   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6180   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6181   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6182   MatCheckPreallocated(mat,1);
6183 
6184   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6185   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
6186   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6187   PetscFunctionReturn(0);
6188 }
6189 
6190 /*@
6191    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
6192    of a set of rows of a matrix.
6193 
6194    Collective on Mat
6195 
6196    Input Parameters:
6197 +  mat - the matrix
6198 .  is - index set of rows to remove
6199 .  diag - value put in all diagonals of eliminated rows
6200 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6201 -  b - optional vector of right hand side, that will be adjusted by provided solution
6202 
6203    Notes:
6204    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6205    but does not release memory.  For the dense and block diagonal
6206    formats this does not alter the nonzero structure.
6207 
6208    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6209    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6210    merely zeroed.
6211 
6212    The user can set a value in the diagonal entry (or for the AIJ and
6213    row formats can optionally remove the main diagonal entry from the
6214    nonzero structure as well, by passing 0.0 as the final argument).
6215 
6216    For the parallel case, all processes that share the matrix (i.e.,
6217    those in the communicator used for matrix creation) MUST call this
6218    routine, regardless of whether any rows being zeroed are owned by
6219    them.
6220 
6221    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6222    list only rows local to itself).
6223 
6224    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6225    owns that are to be zeroed. This saves a global synchronization in the implementation.
6226 
6227    Level: intermediate
6228 
6229 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6230           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6231 @*/
6232 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6233 {
6234   PetscInt       numRows;
6235   const PetscInt *rows;
6236   PetscErrorCode ierr;
6237 
6238   PetscFunctionBegin;
6239   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6240   PetscValidType(mat,1);
6241   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6242   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6243   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6244   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6245   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6246   PetscFunctionReturn(0);
6247 }
6248 
6249 /*@
6250    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6251    of a set of rows of a matrix. These rows must be local to the process.
6252 
6253    Collective on Mat
6254 
6255    Input Parameters:
6256 +  mat - the matrix
6257 .  numRows - the number of rows to remove
6258 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6259 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6260 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6261 -  b - optional vector of right hand side, that will be adjusted by provided solution
6262 
6263    Notes:
6264    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6265    but does not release memory.  For the dense and block diagonal
6266    formats this does not alter the nonzero structure.
6267 
6268    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6269    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6270    merely zeroed.
6271 
6272    The user can set a value in the diagonal entry (or for the AIJ and
6273    row formats can optionally remove the main diagonal entry from the
6274    nonzero structure as well, by passing 0.0 as the final argument).
6275 
6276    For the parallel case, all processes that share the matrix (i.e.,
6277    those in the communicator used for matrix creation) MUST call this
6278    routine, regardless of whether any rows being zeroed are owned by
6279    them.
6280 
6281    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6282    list only rows local to itself).
6283 
6284    The grid coordinates are across the entire grid, not just the local portion
6285 
6286    In Fortran idxm and idxn should be declared as
6287 $     MatStencil idxm(4,m)
6288    and the values inserted using
6289 $    idxm(MatStencil_i,1) = i
6290 $    idxm(MatStencil_j,1) = j
6291 $    idxm(MatStencil_k,1) = k
6292 $    idxm(MatStencil_c,1) = c
6293    etc
6294 
6295    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6296    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6297    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6298    DM_BOUNDARY_PERIODIC boundary type.
6299 
6300    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
6301    a single value per point) you can skip filling those indices.
6302 
6303    Level: intermediate
6304 
6305 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6306           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6307 @*/
6308 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6309 {
6310   PetscInt       dim     = mat->stencil.dim;
6311   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6312   PetscInt       *dims   = mat->stencil.dims+1;
6313   PetscInt       *starts = mat->stencil.starts;
6314   PetscInt       *dxm    = (PetscInt*) rows;
6315   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6316   PetscErrorCode ierr;
6317 
6318   PetscFunctionBegin;
6319   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6320   PetscValidType(mat,1);
6321   if (numRows) PetscValidPointer(rows,3);
6322 
6323   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6324   for (i = 0; i < numRows; ++i) {
6325     /* Skip unused dimensions (they are ordered k, j, i, c) */
6326     for (j = 0; j < 3-sdim; ++j) dxm++;
6327     /* Local index in X dir */
6328     tmp = *dxm++ - starts[0];
6329     /* Loop over remaining dimensions */
6330     for (j = 0; j < dim-1; ++j) {
6331       /* If nonlocal, set index to be negative */
6332       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6333       /* Update local index */
6334       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6335     }
6336     /* Skip component slot if necessary */
6337     if (mat->stencil.noc) dxm++;
6338     /* Local row number */
6339     if (tmp >= 0) {
6340       jdxm[numNewRows++] = tmp;
6341     }
6342   }
6343   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6344   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6345   PetscFunctionReturn(0);
6346 }
6347 
6348 /*@
6349    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6350    of a set of rows and columns of a matrix.
6351 
6352    Collective on Mat
6353 
6354    Input Parameters:
6355 +  mat - the matrix
6356 .  numRows - the number of rows/columns to remove
6357 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6358 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6359 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6360 -  b - optional vector of right hand side, that will be adjusted by provided solution
6361 
6362    Notes:
6363    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6364    but does not release memory.  For the dense and block diagonal
6365    formats this does not alter the nonzero structure.
6366 
6367    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6368    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6369    merely zeroed.
6370 
6371    The user can set a value in the diagonal entry (or for the AIJ and
6372    row formats can optionally remove the main diagonal entry from the
6373    nonzero structure as well, by passing 0.0 as the final argument).
6374 
6375    For the parallel case, all processes that share the matrix (i.e.,
6376    those in the communicator used for matrix creation) MUST call this
6377    routine, regardless of whether any rows being zeroed are owned by
6378    them.
6379 
6380    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6381    list only rows local to itself, but the row/column numbers are given in local numbering).
6382 
6383    The grid coordinates are across the entire grid, not just the local portion
6384 
6385    In Fortran idxm and idxn should be declared as
6386 $     MatStencil idxm(4,m)
6387    and the values inserted using
6388 $    idxm(MatStencil_i,1) = i
6389 $    idxm(MatStencil_j,1) = j
6390 $    idxm(MatStencil_k,1) = k
6391 $    idxm(MatStencil_c,1) = c
6392    etc
6393 
6394    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6395    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6396    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6397    DM_BOUNDARY_PERIODIC boundary type.
6398 
6399    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
6400    a single value per point) you can skip filling those indices.
6401 
6402    Level: intermediate
6403 
6404 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6405           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6406 @*/
6407 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6408 {
6409   PetscInt       dim     = mat->stencil.dim;
6410   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6411   PetscInt       *dims   = mat->stencil.dims+1;
6412   PetscInt       *starts = mat->stencil.starts;
6413   PetscInt       *dxm    = (PetscInt*) rows;
6414   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6415   PetscErrorCode ierr;
6416 
6417   PetscFunctionBegin;
6418   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6419   PetscValidType(mat,1);
6420   if (numRows) PetscValidPointer(rows,3);
6421 
6422   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6423   for (i = 0; i < numRows; ++i) {
6424     /* Skip unused dimensions (they are ordered k, j, i, c) */
6425     for (j = 0; j < 3-sdim; ++j) dxm++;
6426     /* Local index in X dir */
6427     tmp = *dxm++ - starts[0];
6428     /* Loop over remaining dimensions */
6429     for (j = 0; j < dim-1; ++j) {
6430       /* If nonlocal, set index to be negative */
6431       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6432       /* Update local index */
6433       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6434     }
6435     /* Skip component slot if necessary */
6436     if (mat->stencil.noc) dxm++;
6437     /* Local row number */
6438     if (tmp >= 0) {
6439       jdxm[numNewRows++] = tmp;
6440     }
6441   }
6442   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6443   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6444   PetscFunctionReturn(0);
6445 }
6446 
6447 /*@C
6448    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6449    of a set of rows of a matrix; using local numbering of rows.
6450 
6451    Collective on Mat
6452 
6453    Input Parameters:
6454 +  mat - the matrix
6455 .  numRows - the number of rows to remove
6456 .  rows - the global row indices
6457 .  diag - value put in all diagonals of eliminated rows
6458 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6459 -  b - optional vector of right hand side, that will be adjusted by provided solution
6460 
6461    Notes:
6462    Before calling MatZeroRowsLocal(), the user must first set the
6463    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6464 
6465    For the AIJ matrix formats this removes the old nonzero structure,
6466    but does not release memory.  For the dense and block diagonal
6467    formats this does not alter the nonzero structure.
6468 
6469    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6470    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6471    merely zeroed.
6472 
6473    The user can set a value in the diagonal entry (or for the AIJ and
6474    row formats can optionally remove the main diagonal entry from the
6475    nonzero structure as well, by passing 0.0 as the final argument).
6476 
6477    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6478    owns that are to be zeroed. This saves a global synchronization in the implementation.
6479 
6480    Level: intermediate
6481 
6482 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6483           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6484 @*/
6485 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6486 {
6487   PetscErrorCode ierr;
6488 
6489   PetscFunctionBegin;
6490   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6491   PetscValidType(mat,1);
6492   if (numRows) PetscValidIntPointer(rows,3);
6493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6495   MatCheckPreallocated(mat,1);
6496 
6497   if (mat->ops->zerorowslocal) {
6498     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6499   } else {
6500     IS             is, newis;
6501     const PetscInt *newRows;
6502 
6503     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6504     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6505     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6506     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6507     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6508     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6509     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6510     ierr = ISDestroy(&is);CHKERRQ(ierr);
6511   }
6512   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6513   PetscFunctionReturn(0);
6514 }
6515 
6516 /*@
6517    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6518    of a set of rows of a matrix; using local numbering of rows.
6519 
6520    Collective on Mat
6521 
6522    Input Parameters:
6523 +  mat - the matrix
6524 .  is - index set of rows to remove
6525 .  diag - value put in all diagonals of eliminated rows
6526 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6527 -  b - optional vector of right hand side, that will be adjusted by provided solution
6528 
6529    Notes:
6530    Before calling MatZeroRowsLocalIS(), the user must first set the
6531    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6532 
6533    For the AIJ matrix formats this removes the old nonzero structure,
6534    but does not release memory.  For the dense and block diagonal
6535    formats this does not alter the nonzero structure.
6536 
6537    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6538    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6539    merely zeroed.
6540 
6541    The user can set a value in the diagonal entry (or for the AIJ and
6542    row formats can optionally remove the main diagonal entry from the
6543    nonzero structure as well, by passing 0.0 as the final argument).
6544 
6545    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6546    owns that are to be zeroed. This saves a global synchronization in the implementation.
6547 
6548    Level: intermediate
6549 
6550 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6551           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6552 @*/
6553 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6554 {
6555   PetscErrorCode ierr;
6556   PetscInt       numRows;
6557   const PetscInt *rows;
6558 
6559   PetscFunctionBegin;
6560   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6561   PetscValidType(mat,1);
6562   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6563   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6564   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6565   MatCheckPreallocated(mat,1);
6566 
6567   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6568   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6569   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6570   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6571   PetscFunctionReturn(0);
6572 }
6573 
6574 /*@
6575    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6576    of a set of rows and columns of a matrix; using local numbering of rows.
6577 
6578    Collective on Mat
6579 
6580    Input Parameters:
6581 +  mat - the matrix
6582 .  numRows - the number of rows to remove
6583 .  rows - the global row indices
6584 .  diag - value put in all diagonals of eliminated rows
6585 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6586 -  b - optional vector of right hand side, that will be adjusted by provided solution
6587 
6588    Notes:
6589    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6590    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6591 
6592    The user can set a value in the diagonal entry (or for the AIJ and
6593    row formats can optionally remove the main diagonal entry from the
6594    nonzero structure as well, by passing 0.0 as the final argument).
6595 
6596    Level: intermediate
6597 
6598 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6599           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6600 @*/
6601 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6602 {
6603   PetscErrorCode ierr;
6604   IS             is, newis;
6605   const PetscInt *newRows;
6606 
6607   PetscFunctionBegin;
6608   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6609   PetscValidType(mat,1);
6610   if (numRows) PetscValidIntPointer(rows,3);
6611   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6612   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6613   MatCheckPreallocated(mat,1);
6614 
6615   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6616   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6617   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6618   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6619   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6620   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6621   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6622   ierr = ISDestroy(&is);CHKERRQ(ierr);
6623   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6624   PetscFunctionReturn(0);
6625 }
6626 
6627 /*@
6628    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6629    of a set of rows and columns of a matrix; using local numbering of rows.
6630 
6631    Collective on Mat
6632 
6633    Input Parameters:
6634 +  mat - the matrix
6635 .  is - index set of rows to remove
6636 .  diag - value put in all diagonals of eliminated rows
6637 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6638 -  b - optional vector of right hand side, that will be adjusted by provided solution
6639 
6640    Notes:
6641    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6642    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6643 
6644    The user can set a value in the diagonal entry (or for the AIJ and
6645    row formats can optionally remove the main diagonal entry from the
6646    nonzero structure as well, by passing 0.0 as the final argument).
6647 
6648    Level: intermediate
6649 
6650 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6651           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6652 @*/
6653 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6654 {
6655   PetscErrorCode ierr;
6656   PetscInt       numRows;
6657   const PetscInt *rows;
6658 
6659   PetscFunctionBegin;
6660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6661   PetscValidType(mat,1);
6662   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6663   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6664   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6665   MatCheckPreallocated(mat,1);
6666 
6667   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6668   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6669   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6670   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6671   PetscFunctionReturn(0);
6672 }
6673 
6674 /*@C
6675    MatGetSize - Returns the numbers of rows and columns in a matrix.
6676 
6677    Not Collective
6678 
6679    Input Parameter:
6680 .  mat - the matrix
6681 
6682    Output Parameters:
6683 +  m - the number of global rows
6684 -  n - the number of global columns
6685 
6686    Note: both output parameters can be NULL on input.
6687 
6688    Level: beginner
6689 
6690 .seealso: MatGetLocalSize()
6691 @*/
6692 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6693 {
6694   PetscFunctionBegin;
6695   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6696   if (m) *m = mat->rmap->N;
6697   if (n) *n = mat->cmap->N;
6698   PetscFunctionReturn(0);
6699 }
6700 
6701 /*@C
6702    MatGetLocalSize - Returns the number of local rows and local columns
6703    of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs().
6704 
6705    Not Collective
6706 
6707    Input Parameters:
6708 .  mat - the matrix
6709 
6710    Output Parameters:
6711 +  m - the number of local rows
6712 -  n - the number of local columns
6713 
6714    Note: both output parameters can be NULL on input.
6715 
6716    Level: beginner
6717 
6718 .seealso: MatGetSize()
6719 @*/
6720 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6721 {
6722   PetscFunctionBegin;
6723   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6724   if (m) PetscValidIntPointer(m,2);
6725   if (n) PetscValidIntPointer(n,3);
6726   if (m) *m = mat->rmap->n;
6727   if (n) *n = mat->cmap->n;
6728   PetscFunctionReturn(0);
6729 }
6730 
6731 /*@C
6732    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6733    this processor. (The columns of the "diagonal block")
6734 
6735    Not Collective, unless matrix has not been allocated, then collective on Mat
6736 
6737    Input Parameters:
6738 .  mat - the matrix
6739 
6740    Output Parameters:
6741 +  m - the global index of the first local column
6742 -  n - one more than the global index of the last local column
6743 
6744    Notes:
6745     both output parameters can be NULL on input.
6746 
6747    Level: developer
6748 
6749 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6750 
6751 @*/
6752 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6753 {
6754   PetscFunctionBegin;
6755   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6756   PetscValidType(mat,1);
6757   if (m) PetscValidIntPointer(m,2);
6758   if (n) PetscValidIntPointer(n,3);
6759   MatCheckPreallocated(mat,1);
6760   if (m) *m = mat->cmap->rstart;
6761   if (n) *n = mat->cmap->rend;
6762   PetscFunctionReturn(0);
6763 }
6764 
6765 /*@C
6766    MatGetOwnershipRange - Returns the range of matrix rows owned by
6767    this processor, assuming that the matrix is laid out with the first
6768    n1 rows on the first processor, the next n2 rows on the second, etc.
6769    For certain parallel layouts this range may not be well defined.
6770 
6771    Not Collective
6772 
6773    Input Parameters:
6774 .  mat - the matrix
6775 
6776    Output Parameters:
6777 +  m - the global index of the first local row
6778 -  n - one more than the global index of the last local row
6779 
6780    Note: Both output parameters can be NULL on input.
6781 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6782 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6783 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6784 
6785    Level: beginner
6786 
6787 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6788 
6789 @*/
6790 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6791 {
6792   PetscFunctionBegin;
6793   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6794   PetscValidType(mat,1);
6795   if (m) PetscValidIntPointer(m,2);
6796   if (n) PetscValidIntPointer(n,3);
6797   MatCheckPreallocated(mat,1);
6798   if (m) *m = mat->rmap->rstart;
6799   if (n) *n = mat->rmap->rend;
6800   PetscFunctionReturn(0);
6801 }
6802 
6803 /*@C
6804    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6805    each process
6806 
6807    Not Collective, unless matrix has not been allocated, then collective on Mat
6808 
6809    Input Parameters:
6810 .  mat - the matrix
6811 
6812    Output Parameters:
6813 .  ranges - start of each processors portion plus one more than the total length at the end
6814 
6815    Level: beginner
6816 
6817 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6818 
6819 @*/
6820 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6821 {
6822   PetscErrorCode ierr;
6823 
6824   PetscFunctionBegin;
6825   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6826   PetscValidType(mat,1);
6827   MatCheckPreallocated(mat,1);
6828   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6829   PetscFunctionReturn(0);
6830 }
6831 
6832 /*@C
6833    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6834    this processor. (The columns of the "diagonal blocks" for each process)
6835 
6836    Not Collective, unless matrix has not been allocated, then collective on Mat
6837 
6838    Input Parameters:
6839 .  mat - the matrix
6840 
6841    Output Parameters:
6842 .  ranges - start of each processors portion plus one more then the total length at the end
6843 
6844    Level: beginner
6845 
6846 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6847 
6848 @*/
6849 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6850 {
6851   PetscErrorCode ierr;
6852 
6853   PetscFunctionBegin;
6854   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6855   PetscValidType(mat,1);
6856   MatCheckPreallocated(mat,1);
6857   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6858   PetscFunctionReturn(0);
6859 }
6860 
6861 /*@C
6862    MatGetOwnershipIS - Get row and column ownership as index sets
6863 
6864    Not Collective
6865 
6866    Input Arguments:
6867 .  A - matrix of type Elemental or ScaLAPACK
6868 
6869    Output Arguments:
6870 +  rows - rows in which this process owns elements
6871 -  cols - columns in which this process owns elements
6872 
6873    Level: intermediate
6874 
6875 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6876 @*/
6877 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6878 {
6879   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6880 
6881   PetscFunctionBegin;
6882   MatCheckPreallocated(A,1);
6883   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6884   if (f) {
6885     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6886   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6887     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6888     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6889   }
6890   PetscFunctionReturn(0);
6891 }
6892 
6893 /*@C
6894    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6895    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6896    to complete the factorization.
6897 
6898    Collective on Mat
6899 
6900    Input Parameters:
6901 +  mat - the matrix
6902 .  row - row permutation
6903 .  column - column permutation
6904 -  info - structure containing
6905 $      levels - number of levels of fill.
6906 $      expected fill - as ratio of original fill.
6907 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6908                 missing diagonal entries)
6909 
6910    Output Parameters:
6911 .  fact - new matrix that has been symbolically factored
6912 
6913    Notes:
6914     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6915 
6916    Most users should employ the simplified KSP interface for linear solvers
6917    instead of working directly with matrix algebra routines such as this.
6918    See, e.g., KSPCreate().
6919 
6920    Level: developer
6921 
6922 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6923           MatGetOrdering(), MatFactorInfo
6924 
6925     Note: this uses the definition of level of fill as in Y. Saad, 2003
6926 
6927     Developer Note: fortran interface is not autogenerated as the f90
6928     interface defintion cannot be generated correctly [due to MatFactorInfo]
6929 
6930    References:
6931      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6932 @*/
6933 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6934 {
6935   PetscErrorCode ierr;
6936 
6937   PetscFunctionBegin;
6938   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
6939   PetscValidType(mat,2);
6940   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3);
6941   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4);
6942   PetscValidPointer(info,5);
6943   PetscValidPointer(fact,1);
6944   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6945   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6946   if (!fact->ops->ilufactorsymbolic) {
6947     MatSolverType stype;
6948     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
6949     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype);
6950   }
6951   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6952   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6953   MatCheckPreallocated(mat,2);
6954 
6955   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6956   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6957   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6958   PetscFunctionReturn(0);
6959 }
6960 
6961 /*@C
6962    MatICCFactorSymbolic - Performs symbolic incomplete
6963    Cholesky factorization for a symmetric matrix.  Use
6964    MatCholeskyFactorNumeric() to complete the factorization.
6965 
6966    Collective on Mat
6967 
6968    Input Parameters:
6969 +  mat - the matrix
6970 .  perm - row and column permutation
6971 -  info - structure containing
6972 $      levels - number of levels of fill.
6973 $      expected fill - as ratio of original fill.
6974 
6975    Output Parameter:
6976 .  fact - the factored matrix
6977 
6978    Notes:
6979    Most users should employ the KSP interface for linear solvers
6980    instead of working directly with matrix algebra routines such as this.
6981    See, e.g., KSPCreate().
6982 
6983    Level: developer
6984 
6985 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6986 
6987     Note: this uses the definition of level of fill as in Y. Saad, 2003
6988 
6989     Developer Note: fortran interface is not autogenerated as the f90
6990     interface defintion cannot be generated correctly [due to MatFactorInfo]
6991 
6992    References:
6993      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6994 @*/
6995 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6996 {
6997   PetscErrorCode ierr;
6998 
6999   PetscFunctionBegin;
7000   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
7001   PetscValidType(mat,2);
7002   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3);
7003   PetscValidPointer(info,4);
7004   PetscValidPointer(fact,1);
7005   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7006   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
7007   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
7008   if (!(fact)->ops->iccfactorsymbolic) {
7009     MatSolverType stype;
7010     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
7011     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype);
7012   }
7013   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7014   MatCheckPreallocated(mat,2);
7015 
7016   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
7017   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
7018   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
7019   PetscFunctionReturn(0);
7020 }
7021 
7022 /*@C
7023    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
7024    points to an array of valid matrices, they may be reused to store the new
7025    submatrices.
7026 
7027    Collective on Mat
7028 
7029    Input Parameters:
7030 +  mat - the matrix
7031 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
7032 .  irow, icol - index sets of rows and columns to extract
7033 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7034 
7035    Output Parameter:
7036 .  submat - the array of submatrices
7037 
7038    Notes:
7039    MatCreateSubMatrices() can extract ONLY sequential submatrices
7040    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
7041    to extract a parallel submatrix.
7042 
7043    Some matrix types place restrictions on the row and column
7044    indices, such as that they be sorted or that they be equal to each other.
7045 
7046    The index sets may not have duplicate entries.
7047 
7048    When extracting submatrices from a parallel matrix, each processor can
7049    form a different submatrix by setting the rows and columns of its
7050    individual index sets according to the local submatrix desired.
7051 
7052    When finished using the submatrices, the user should destroy
7053    them with MatDestroySubMatrices().
7054 
7055    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7056    original matrix has not changed from that last call to MatCreateSubMatrices().
7057 
7058    This routine creates the matrices in submat; you should NOT create them before
7059    calling it. It also allocates the array of matrix pointers submat.
7060 
7061    For BAIJ matrices the index sets must respect the block structure, that is if they
7062    request one row/column in a block, they must request all rows/columns that are in
7063    that block. For example, if the block size is 2 you cannot request just row 0 and
7064    column 0.
7065 
7066    Fortran Note:
7067    The Fortran interface is slightly different from that given below; it
7068    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
7069 
7070    Level: advanced
7071 
7072 
7073 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
7074 @*/
7075 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
7076 {
7077   PetscErrorCode ierr;
7078   PetscInt       i;
7079   PetscBool      eq;
7080 
7081   PetscFunctionBegin;
7082   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7083   PetscValidType(mat,1);
7084   if (n) {
7085     PetscValidPointer(irow,3);
7086     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
7087     PetscValidPointer(icol,4);
7088     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
7089   }
7090   PetscValidPointer(submat,6);
7091   if (n && scall == MAT_REUSE_MATRIX) {
7092     PetscValidPointer(*submat,6);
7093     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
7094   }
7095   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7096   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7097   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7098   MatCheckPreallocated(mat,1);
7099 
7100   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7101   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
7102   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7103   for (i=0; i<n; i++) {
7104     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
7105     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
7106     if (eq) {
7107       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
7108     }
7109   }
7110   PetscFunctionReturn(0);
7111 }
7112 
7113 /*@C
7114    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
7115 
7116    Collective on Mat
7117 
7118    Input Parameters:
7119 +  mat - the matrix
7120 .  n   - the number of submatrixes to be extracted
7121 .  irow, icol - index sets of rows and columns to extract
7122 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7123 
7124    Output Parameter:
7125 .  submat - the array of submatrices
7126 
7127    Level: advanced
7128 
7129 
7130 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
7131 @*/
7132 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
7133 {
7134   PetscErrorCode ierr;
7135   PetscInt       i;
7136   PetscBool      eq;
7137 
7138   PetscFunctionBegin;
7139   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7140   PetscValidType(mat,1);
7141   if (n) {
7142     PetscValidPointer(irow,3);
7143     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
7144     PetscValidPointer(icol,4);
7145     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
7146   }
7147   PetscValidPointer(submat,6);
7148   if (n && scall == MAT_REUSE_MATRIX) {
7149     PetscValidPointer(*submat,6);
7150     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
7151   }
7152   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7153   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7154   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7155   MatCheckPreallocated(mat,1);
7156 
7157   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7158   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
7159   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7160   for (i=0; i<n; i++) {
7161     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
7162     if (eq) {
7163       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
7164     }
7165   }
7166   PetscFunctionReturn(0);
7167 }
7168 
7169 /*@C
7170    MatDestroyMatrices - Destroys an array of matrices.
7171 
7172    Collective on Mat
7173 
7174    Input Parameters:
7175 +  n - the number of local matrices
7176 -  mat - the matrices (note that this is a pointer to the array of matrices)
7177 
7178    Level: advanced
7179 
7180     Notes:
7181     Frees not only the matrices, but also the array that contains the matrices
7182            In Fortran will not free the array.
7183 
7184 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7185 @*/
7186 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7187 {
7188   PetscErrorCode ierr;
7189   PetscInt       i;
7190 
7191   PetscFunctionBegin;
7192   if (!*mat) PetscFunctionReturn(0);
7193   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7194   PetscValidPointer(mat,2);
7195 
7196   for (i=0; i<n; i++) {
7197     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7198   }
7199 
7200   /* memory is allocated even if n = 0 */
7201   ierr = PetscFree(*mat);CHKERRQ(ierr);
7202   PetscFunctionReturn(0);
7203 }
7204 
7205 /*@C
7206    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7207 
7208    Collective on Mat
7209 
7210    Input Parameters:
7211 +  n - the number of local matrices
7212 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7213                        sequence of MatCreateSubMatrices())
7214 
7215    Level: advanced
7216 
7217     Notes:
7218     Frees not only the matrices, but also the array that contains the matrices
7219            In Fortran will not free the array.
7220 
7221 .seealso: MatCreateSubMatrices()
7222 @*/
7223 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7224 {
7225   PetscErrorCode ierr;
7226   Mat            mat0;
7227 
7228   PetscFunctionBegin;
7229   if (!*mat) PetscFunctionReturn(0);
7230   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7231   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7232   PetscValidPointer(mat,2);
7233 
7234   mat0 = (*mat)[0];
7235   if (mat0 && mat0->ops->destroysubmatrices) {
7236     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7237   } else {
7238     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7239   }
7240   PetscFunctionReturn(0);
7241 }
7242 
7243 /*@C
7244    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7245 
7246    Collective on Mat
7247 
7248    Input Parameters:
7249 .  mat - the matrix
7250 
7251    Output Parameter:
7252 .  matstruct - the sequential matrix with the nonzero structure of mat
7253 
7254   Level: intermediate
7255 
7256 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7257 @*/
7258 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7259 {
7260   PetscErrorCode ierr;
7261 
7262   PetscFunctionBegin;
7263   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7264   PetscValidPointer(matstruct,2);
7265 
7266   PetscValidType(mat,1);
7267   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7268   MatCheckPreallocated(mat,1);
7269 
7270   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7271   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7272   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7273   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7274   PetscFunctionReturn(0);
7275 }
7276 
7277 /*@C
7278    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7279 
7280    Collective on Mat
7281 
7282    Input Parameters:
7283 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7284                        sequence of MatGetSequentialNonzeroStructure())
7285 
7286    Level: advanced
7287 
7288     Notes:
7289     Frees not only the matrices, but also the array that contains the matrices
7290 
7291 .seealso: MatGetSeqNonzeroStructure()
7292 @*/
7293 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7294 {
7295   PetscErrorCode ierr;
7296 
7297   PetscFunctionBegin;
7298   PetscValidPointer(mat,1);
7299   ierr = MatDestroy(mat);CHKERRQ(ierr);
7300   PetscFunctionReturn(0);
7301 }
7302 
7303 /*@
7304    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7305    replaces the index sets by larger ones that represent submatrices with
7306    additional overlap.
7307 
7308    Collective on Mat
7309 
7310    Input Parameters:
7311 +  mat - the matrix
7312 .  n   - the number of index sets
7313 .  is  - the array of index sets (these index sets will changed during the call)
7314 -  ov  - the additional overlap requested
7315 
7316    Options Database:
7317 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7318 
7319    Level: developer
7320 
7321 
7322 .seealso: MatCreateSubMatrices()
7323 @*/
7324 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7325 {
7326   PetscErrorCode ierr;
7327 
7328   PetscFunctionBegin;
7329   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7330   PetscValidType(mat,1);
7331   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7332   if (n) {
7333     PetscValidPointer(is,3);
7334     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7335   }
7336   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7337   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7338   MatCheckPreallocated(mat,1);
7339 
7340   if (!ov) PetscFunctionReturn(0);
7341   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7342   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7343   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7344   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7345   PetscFunctionReturn(0);
7346 }
7347 
7348 
7349 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7350 
7351 /*@
7352    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7353    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7354    additional overlap.
7355 
7356    Collective on Mat
7357 
7358    Input Parameters:
7359 +  mat - the matrix
7360 .  n   - the number of index sets
7361 .  is  - the array of index sets (these index sets will changed during the call)
7362 -  ov  - the additional overlap requested
7363 
7364    Options Database:
7365 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7366 
7367    Level: developer
7368 
7369 
7370 .seealso: MatCreateSubMatrices()
7371 @*/
7372 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7373 {
7374   PetscInt       i;
7375   PetscErrorCode ierr;
7376 
7377   PetscFunctionBegin;
7378   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7379   PetscValidType(mat,1);
7380   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7381   if (n) {
7382     PetscValidPointer(is,3);
7383     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7384   }
7385   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7386   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7387   MatCheckPreallocated(mat,1);
7388   if (!ov) PetscFunctionReturn(0);
7389   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7390   for (i=0; i<n; i++){
7391         ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7392   }
7393   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7394   PetscFunctionReturn(0);
7395 }
7396 
7397 
7398 
7399 
7400 /*@
7401    MatGetBlockSize - Returns the matrix block size.
7402 
7403    Not Collective
7404 
7405    Input Parameter:
7406 .  mat - the matrix
7407 
7408    Output Parameter:
7409 .  bs - block size
7410 
7411    Notes:
7412     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7413 
7414    If the block size has not been set yet this routine returns 1.
7415 
7416    Level: intermediate
7417 
7418 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7419 @*/
7420 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7421 {
7422   PetscFunctionBegin;
7423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7424   PetscValidIntPointer(bs,2);
7425   *bs = PetscAbs(mat->rmap->bs);
7426   PetscFunctionReturn(0);
7427 }
7428 
7429 /*@
7430    MatGetBlockSizes - Returns the matrix block row and column sizes.
7431 
7432    Not Collective
7433 
7434    Input Parameter:
7435 .  mat - the matrix
7436 
7437    Output Parameter:
7438 +  rbs - row block size
7439 -  cbs - column 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     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7444 
7445    If a block size has not been set yet this routine returns 1.
7446 
7447    Level: intermediate
7448 
7449 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7450 @*/
7451 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7452 {
7453   PetscFunctionBegin;
7454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7455   if (rbs) PetscValidIntPointer(rbs,2);
7456   if (cbs) PetscValidIntPointer(cbs,3);
7457   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7458   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7459   PetscFunctionReturn(0);
7460 }
7461 
7462 /*@
7463    MatSetBlockSize - Sets the matrix block size.
7464 
7465    Logically Collective on Mat
7466 
7467    Input Parameters:
7468 +  mat - the matrix
7469 -  bs - 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     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7474 
7475     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7476     is compatible with the matrix local sizes.
7477 
7478    Level: intermediate
7479 
7480 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7481 @*/
7482 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7483 {
7484   PetscErrorCode ierr;
7485 
7486   PetscFunctionBegin;
7487   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7488   PetscValidLogicalCollectiveInt(mat,bs,2);
7489   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7490   PetscFunctionReturn(0);
7491 }
7492 
7493 /*@
7494    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7495 
7496    Logically Collective on Mat
7497 
7498    Input Parameters:
7499 +  mat - the matrix
7500 .  nblocks - the number of blocks on this process
7501 -  bsizes - the block sizes
7502 
7503    Notes:
7504     Currently used by PCVPBJACOBI for SeqAIJ matrices
7505 
7506    Level: intermediate
7507 
7508 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7509 @*/
7510 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7511 {
7512   PetscErrorCode ierr;
7513   PetscInt       i,ncnt = 0, nlocal;
7514 
7515   PetscFunctionBegin;
7516   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7517   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7518   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7519   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7520   if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal);
7521   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7522   mat->nblocks = nblocks;
7523   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7524   ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7525   PetscFunctionReturn(0);
7526 }
7527 
7528 /*@C
7529    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7530 
7531    Logically Collective on Mat
7532 
7533    Input Parameters:
7534 .  mat - the matrix
7535 
7536    Output Parameters:
7537 +  nblocks - the number of blocks on this process
7538 -  bsizes - the block sizes
7539 
7540    Notes: Currently not supported from Fortran
7541 
7542    Level: intermediate
7543 
7544 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7545 @*/
7546 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7547 {
7548   PetscFunctionBegin;
7549   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7550   *nblocks = mat->nblocks;
7551   *bsizes  = mat->bsizes;
7552   PetscFunctionReturn(0);
7553 }
7554 
7555 /*@
7556    MatSetBlockSizes - Sets the matrix block row and column sizes.
7557 
7558    Logically Collective on Mat
7559 
7560    Input Parameters:
7561 +  mat - the matrix
7562 .  rbs - row block size
7563 -  cbs - column block size
7564 
7565    Notes:
7566     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7567     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7568     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7569 
7570     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7571     are compatible with the matrix local sizes.
7572 
7573     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7574 
7575    Level: intermediate
7576 
7577 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7578 @*/
7579 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7580 {
7581   PetscErrorCode ierr;
7582 
7583   PetscFunctionBegin;
7584   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7585   PetscValidLogicalCollectiveInt(mat,rbs,2);
7586   PetscValidLogicalCollectiveInt(mat,cbs,3);
7587   if (mat->ops->setblocksizes) {
7588     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7589   }
7590   if (mat->rmap->refcnt) {
7591     ISLocalToGlobalMapping l2g = NULL;
7592     PetscLayout            nmap = NULL;
7593 
7594     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7595     if (mat->rmap->mapping) {
7596       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7597     }
7598     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7599     mat->rmap = nmap;
7600     mat->rmap->mapping = l2g;
7601   }
7602   if (mat->cmap->refcnt) {
7603     ISLocalToGlobalMapping l2g = NULL;
7604     PetscLayout            nmap = NULL;
7605 
7606     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7607     if (mat->cmap->mapping) {
7608       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7609     }
7610     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7611     mat->cmap = nmap;
7612     mat->cmap->mapping = l2g;
7613   }
7614   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7615   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7616   PetscFunctionReturn(0);
7617 }
7618 
7619 /*@
7620    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7621 
7622    Logically Collective on Mat
7623 
7624    Input Parameters:
7625 +  mat - the matrix
7626 .  fromRow - matrix from which to copy row block size
7627 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7628 
7629    Level: developer
7630 
7631 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7632 @*/
7633 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7634 {
7635   PetscErrorCode ierr;
7636 
7637   PetscFunctionBegin;
7638   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7639   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7640   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7641   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7642   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7643   PetscFunctionReturn(0);
7644 }
7645 
7646 /*@
7647    MatResidual - Default routine to calculate the residual.
7648 
7649    Collective on Mat
7650 
7651    Input Parameters:
7652 +  mat - the matrix
7653 .  b   - the right-hand-side
7654 -  x   - the approximate solution
7655 
7656    Output Parameter:
7657 .  r - location to store the residual
7658 
7659    Level: developer
7660 
7661 .seealso: PCMGSetResidual()
7662 @*/
7663 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7664 {
7665   PetscErrorCode ierr;
7666 
7667   PetscFunctionBegin;
7668   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7669   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7670   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7671   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7672   PetscValidType(mat,1);
7673   MatCheckPreallocated(mat,1);
7674   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7675   if (!mat->ops->residual) {
7676     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7677     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7678   } else {
7679     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7680   }
7681   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7682   PetscFunctionReturn(0);
7683 }
7684 
7685 /*@C
7686     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7687 
7688    Collective on Mat
7689 
7690     Input Parameters:
7691 +   mat - the matrix
7692 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7693 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7694 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7695                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7696                  always used.
7697 
7698     Output Parameters:
7699 +   n - number of rows in the (possibly compressed) matrix
7700 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7701 .   ja - the column indices
7702 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7703            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7704 
7705     Level: developer
7706 
7707     Notes:
7708     You CANNOT change any of the ia[] or ja[] values.
7709 
7710     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7711 
7712     Fortran Notes:
7713     In Fortran use
7714 $
7715 $      PetscInt ia(1), ja(1)
7716 $      PetscOffset iia, jja
7717 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7718 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7719 
7720      or
7721 $
7722 $    PetscInt, pointer :: ia(:),ja(:)
7723 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7724 $    ! Access the ith and jth entries via ia(i) and ja(j)
7725 
7726 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7727 @*/
7728 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7729 {
7730   PetscErrorCode ierr;
7731 
7732   PetscFunctionBegin;
7733   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7734   PetscValidType(mat,1);
7735   PetscValidIntPointer(n,5);
7736   if (ia) PetscValidIntPointer(ia,6);
7737   if (ja) PetscValidIntPointer(ja,7);
7738   PetscValidBoolPointer(done,8);
7739   MatCheckPreallocated(mat,1);
7740   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7741   else {
7742     *done = PETSC_TRUE;
7743     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7744     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7745     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7746   }
7747   PetscFunctionReturn(0);
7748 }
7749 
7750 /*@C
7751     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7752 
7753     Collective on Mat
7754 
7755     Input Parameters:
7756 +   mat - the matrix
7757 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7758 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7759                 symmetrized
7760 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7761                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7762                  always used.
7763 .   n - number of columns in the (possibly compressed) matrix
7764 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7765 -   ja - the row indices
7766 
7767     Output Parameters:
7768 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7769 
7770     Level: developer
7771 
7772 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7773 @*/
7774 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7775 {
7776   PetscErrorCode ierr;
7777 
7778   PetscFunctionBegin;
7779   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7780   PetscValidType(mat,1);
7781   PetscValidIntPointer(n,5);
7782   if (ia) PetscValidIntPointer(ia,6);
7783   if (ja) PetscValidIntPointer(ja,7);
7784   PetscValidBoolPointer(done,8);
7785   MatCheckPreallocated(mat,1);
7786   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7787   else {
7788     *done = PETSC_TRUE;
7789     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7790   }
7791   PetscFunctionReturn(0);
7792 }
7793 
7794 /*@C
7795     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7796     MatGetRowIJ().
7797 
7798     Collective on Mat
7799 
7800     Input Parameters:
7801 +   mat - the matrix
7802 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7803 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7804                 symmetrized
7805 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7806                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7807                  always used.
7808 .   n - size of (possibly compressed) matrix
7809 .   ia - the row pointers
7810 -   ja - the column indices
7811 
7812     Output Parameters:
7813 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7814 
7815     Note:
7816     This routine zeros out n, ia, and ja. This is to prevent accidental
7817     us of the array after it has been restored. If you pass NULL, it will
7818     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7819 
7820     Level: developer
7821 
7822 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7823 @*/
7824 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7825 {
7826   PetscErrorCode ierr;
7827 
7828   PetscFunctionBegin;
7829   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7830   PetscValidType(mat,1);
7831   if (ia) PetscValidIntPointer(ia,6);
7832   if (ja) PetscValidIntPointer(ja,7);
7833   PetscValidBoolPointer(done,8);
7834   MatCheckPreallocated(mat,1);
7835 
7836   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7837   else {
7838     *done = PETSC_TRUE;
7839     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7840     if (n)  *n = 0;
7841     if (ia) *ia = NULL;
7842     if (ja) *ja = NULL;
7843   }
7844   PetscFunctionReturn(0);
7845 }
7846 
7847 /*@C
7848     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7849     MatGetColumnIJ().
7850 
7851     Collective on Mat
7852 
7853     Input Parameters:
7854 +   mat - the matrix
7855 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7856 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7857                 symmetrized
7858 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7859                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7860                  always used.
7861 
7862     Output Parameters:
7863 +   n - size of (possibly compressed) matrix
7864 .   ia - the column pointers
7865 .   ja - the row indices
7866 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7867 
7868     Level: developer
7869 
7870 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7871 @*/
7872 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7873 {
7874   PetscErrorCode ierr;
7875 
7876   PetscFunctionBegin;
7877   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7878   PetscValidType(mat,1);
7879   if (ia) PetscValidIntPointer(ia,6);
7880   if (ja) PetscValidIntPointer(ja,7);
7881   PetscValidBoolPointer(done,8);
7882   MatCheckPreallocated(mat,1);
7883 
7884   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7885   else {
7886     *done = PETSC_TRUE;
7887     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7888     if (n)  *n = 0;
7889     if (ia) *ia = NULL;
7890     if (ja) *ja = NULL;
7891   }
7892   PetscFunctionReturn(0);
7893 }
7894 
7895 /*@C
7896     MatColoringPatch -Used inside matrix coloring routines that
7897     use MatGetRowIJ() and/or MatGetColumnIJ().
7898 
7899     Collective on Mat
7900 
7901     Input Parameters:
7902 +   mat - the matrix
7903 .   ncolors - max color value
7904 .   n   - number of entries in colorarray
7905 -   colorarray - array indicating color for each column
7906 
7907     Output Parameters:
7908 .   iscoloring - coloring generated using colorarray information
7909 
7910     Level: developer
7911 
7912 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7913 
7914 @*/
7915 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7916 {
7917   PetscErrorCode ierr;
7918 
7919   PetscFunctionBegin;
7920   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7921   PetscValidType(mat,1);
7922   PetscValidIntPointer(colorarray,4);
7923   PetscValidPointer(iscoloring,5);
7924   MatCheckPreallocated(mat,1);
7925 
7926   if (!mat->ops->coloringpatch) {
7927     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7928   } else {
7929     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7930   }
7931   PetscFunctionReturn(0);
7932 }
7933 
7934 
7935 /*@
7936    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7937 
7938    Logically Collective on Mat
7939 
7940    Input Parameter:
7941 .  mat - the factored matrix to be reset
7942 
7943    Notes:
7944    This routine should be used only with factored matrices formed by in-place
7945    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7946    format).  This option can save memory, for example, when solving nonlinear
7947    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7948    ILU(0) preconditioner.
7949 
7950    Note that one can specify in-place ILU(0) factorization by calling
7951 .vb
7952      PCType(pc,PCILU);
7953      PCFactorSeUseInPlace(pc);
7954 .ve
7955    or by using the options -pc_type ilu -pc_factor_in_place
7956 
7957    In-place factorization ILU(0) can also be used as a local
7958    solver for the blocks within the block Jacobi or additive Schwarz
7959    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7960    for details on setting local solver options.
7961 
7962    Most users should employ the simplified KSP interface for linear solvers
7963    instead of working directly with matrix algebra routines such as this.
7964    See, e.g., KSPCreate().
7965 
7966    Level: developer
7967 
7968 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7969 
7970 @*/
7971 PetscErrorCode MatSetUnfactored(Mat mat)
7972 {
7973   PetscErrorCode ierr;
7974 
7975   PetscFunctionBegin;
7976   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7977   PetscValidType(mat,1);
7978   MatCheckPreallocated(mat,1);
7979   mat->factortype = MAT_FACTOR_NONE;
7980   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7981   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7982   PetscFunctionReturn(0);
7983 }
7984 
7985 /*MC
7986     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7987 
7988     Synopsis:
7989     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7990 
7991     Not collective
7992 
7993     Input Parameter:
7994 .   x - matrix
7995 
7996     Output Parameters:
7997 +   xx_v - the Fortran90 pointer to the array
7998 -   ierr - error code
7999 
8000     Example of Usage:
8001 .vb
8002       PetscScalar, pointer xx_v(:,:)
8003       ....
8004       call MatDenseGetArrayF90(x,xx_v,ierr)
8005       a = xx_v(3)
8006       call MatDenseRestoreArrayF90(x,xx_v,ierr)
8007 .ve
8008 
8009     Level: advanced
8010 
8011 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
8012 
8013 M*/
8014 
8015 /*MC
8016     MatDenseRestoreArrayF90 - Restores a matrix array that has been
8017     accessed with MatDenseGetArrayF90().
8018 
8019     Synopsis:
8020     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
8021 
8022     Not collective
8023 
8024     Input Parameters:
8025 +   x - matrix
8026 -   xx_v - the Fortran90 pointer to the array
8027 
8028     Output Parameter:
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:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
8043 
8044 M*/
8045 
8046 
8047 /*MC
8048     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
8049 
8050     Synopsis:
8051     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
8052 
8053     Not collective
8054 
8055     Input Parameter:
8056 .   x - matrix
8057 
8058     Output Parameters:
8059 +   xx_v - the Fortran90 pointer to the array
8060 -   ierr - error code
8061 
8062     Example of Usage:
8063 .vb
8064       PetscScalar, pointer xx_v(:)
8065       ....
8066       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
8067       a = xx_v(3)
8068       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
8069 .ve
8070 
8071     Level: advanced
8072 
8073 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
8074 
8075 M*/
8076 
8077 /*MC
8078     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
8079     accessed with MatSeqAIJGetArrayF90().
8080 
8081     Synopsis:
8082     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
8083 
8084     Not collective
8085 
8086     Input Parameters:
8087 +   x - matrix
8088 -   xx_v - the Fortran90 pointer to the array
8089 
8090     Output Parameter:
8091 .   ierr - error code
8092 
8093     Example of Usage:
8094 .vb
8095        PetscScalar, pointer xx_v(:)
8096        ....
8097        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
8098        a = xx_v(3)
8099        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
8100 .ve
8101 
8102     Level: advanced
8103 
8104 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
8105 
8106 M*/
8107 
8108 
8109 /*@
8110     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
8111                       as the original matrix.
8112 
8113     Collective on Mat
8114 
8115     Input Parameters:
8116 +   mat - the original matrix
8117 .   isrow - parallel IS containing the rows this processor should obtain
8118 .   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.
8119 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8120 
8121     Output Parameter:
8122 .   newmat - the new submatrix, of the same type as the old
8123 
8124     Level: advanced
8125 
8126     Notes:
8127     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
8128 
8129     Some matrix types place restrictions on the row and column indices, such
8130     as that they be sorted or that they be equal to each other.
8131 
8132     The index sets may not have duplicate entries.
8133 
8134       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
8135    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
8136    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
8137    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
8138    you are finished using it.
8139 
8140     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
8141     the input matrix.
8142 
8143     If iscol is NULL then all columns are obtained (not supported in Fortran).
8144 
8145    Example usage:
8146    Consider the following 8x8 matrix with 34 non-zero values, that is
8147    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8148    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8149    as follows:
8150 
8151 .vb
8152             1  2  0  |  0  3  0  |  0  4
8153     Proc0   0  5  6  |  7  0  0  |  8  0
8154             9  0 10  | 11  0  0  | 12  0
8155     -------------------------------------
8156            13  0 14  | 15 16 17  |  0  0
8157     Proc1   0 18  0  | 19 20 21  |  0  0
8158             0  0  0  | 22 23  0  | 24  0
8159     -------------------------------------
8160     Proc2  25 26 27  |  0  0 28  | 29  0
8161            30  0  0  | 31 32 33  |  0 34
8162 .ve
8163 
8164     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8165 
8166 .vb
8167             2  0  |  0  3  0  |  0
8168     Proc0   5  6  |  7  0  0  |  8
8169     -------------------------------
8170     Proc1  18  0  | 19 20 21  |  0
8171     -------------------------------
8172     Proc2  26 27  |  0  0 28  | 29
8173             0  0  | 31 32 33  |  0
8174 .ve
8175 
8176 
8177 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate()
8178 @*/
8179 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8180 {
8181   PetscErrorCode ierr;
8182   PetscMPIInt    size;
8183   Mat            *local;
8184   IS             iscoltmp;
8185   PetscBool      flg;
8186 
8187   PetscFunctionBegin;
8188   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8189   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8190   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8191   PetscValidPointer(newmat,5);
8192   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8193   PetscValidType(mat,1);
8194   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8195   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8196 
8197   MatCheckPreallocated(mat,1);
8198   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
8199 
8200   if (!iscol || isrow == iscol) {
8201     PetscBool   stride;
8202     PetscMPIInt grabentirematrix = 0,grab;
8203     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8204     if (stride) {
8205       PetscInt first,step,n,rstart,rend;
8206       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8207       if (step == 1) {
8208         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8209         if (rstart == first) {
8210           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8211           if (n == rend-rstart) {
8212             grabentirematrix = 1;
8213           }
8214         }
8215       }
8216     }
8217     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRMPI(ierr);
8218     if (grab) {
8219       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8220       if (cll == MAT_INITIAL_MATRIX) {
8221         *newmat = mat;
8222         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8223       }
8224       PetscFunctionReturn(0);
8225     }
8226   }
8227 
8228   if (!iscol) {
8229     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8230   } else {
8231     iscoltmp = iscol;
8232   }
8233 
8234   /* if original matrix is on just one processor then use submatrix generated */
8235   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8236     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8237     goto setproperties;
8238   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8239     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8240     *newmat = *local;
8241     ierr    = PetscFree(local);CHKERRQ(ierr);
8242     goto setproperties;
8243   } else if (!mat->ops->createsubmatrix) {
8244     /* Create a new matrix type that implements the operation using the full matrix */
8245     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8246     switch (cll) {
8247     case MAT_INITIAL_MATRIX:
8248       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8249       break;
8250     case MAT_REUSE_MATRIX:
8251       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8252       break;
8253     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8254     }
8255     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8256     goto setproperties;
8257   }
8258 
8259   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8260   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8261   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8262   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8263 
8264 setproperties:
8265   ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr);
8266   if (flg) {
8267     ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr);
8268   }
8269   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8270   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8271   PetscFunctionReturn(0);
8272 }
8273 
8274 /*@
8275    MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix
8276 
8277    Not Collective
8278 
8279    Input Parameters:
8280 +  A - the matrix we wish to propagate options from
8281 -  B - the matrix we wish to propagate options to
8282 
8283    Level: beginner
8284 
8285    Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC
8286 
8287 .seealso: MatSetOption()
8288 @*/
8289 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B)
8290 {
8291   PetscErrorCode ierr;
8292 
8293   PetscFunctionBegin;
8294   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8295   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8296   if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */
8297     ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr);
8298   }
8299   if (A->structurally_symmetric_set) {
8300     ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr);
8301   }
8302   if (A->hermitian_set) {
8303     ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr);
8304   }
8305   if (A->spd_set) {
8306     ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr);
8307   }
8308   if (A->symmetric_set) {
8309     ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr);
8310   }
8311   PetscFunctionReturn(0);
8312 }
8313 
8314 /*@
8315    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8316    used during the assembly process to store values that belong to
8317    other processors.
8318 
8319    Not Collective
8320 
8321    Input Parameters:
8322 +  mat   - the matrix
8323 .  size  - the initial size of the stash.
8324 -  bsize - the initial size of the block-stash(if used).
8325 
8326    Options Database Keys:
8327 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8328 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8329 
8330    Level: intermediate
8331 
8332    Notes:
8333      The block-stash is used for values set with MatSetValuesBlocked() while
8334      the stash is used for values set with MatSetValues()
8335 
8336      Run with the option -info and look for output of the form
8337      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8338      to determine the appropriate value, MM, to use for size and
8339      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8340      to determine the value, BMM to use for bsize
8341 
8342 
8343 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8344 
8345 @*/
8346 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8347 {
8348   PetscErrorCode ierr;
8349 
8350   PetscFunctionBegin;
8351   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8352   PetscValidType(mat,1);
8353   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8354   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8355   PetscFunctionReturn(0);
8356 }
8357 
8358 /*@
8359    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8360      the matrix
8361 
8362    Neighbor-wise Collective on Mat
8363 
8364    Input Parameters:
8365 +  mat   - the matrix
8366 .  x,y - the vectors
8367 -  w - where the result is stored
8368 
8369    Level: intermediate
8370 
8371    Notes:
8372     w may be the same vector as y.
8373 
8374     This allows one to use either the restriction or interpolation (its transpose)
8375     matrix to do the interpolation
8376 
8377 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8378 
8379 @*/
8380 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8381 {
8382   PetscErrorCode ierr;
8383   PetscInt       M,N,Ny;
8384 
8385   PetscFunctionBegin;
8386   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8387   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8388   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8389   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8390   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8391   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8392   if (M == Ny) {
8393     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8394   } else {
8395     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8396   }
8397   PetscFunctionReturn(0);
8398 }
8399 
8400 /*@
8401    MatInterpolate - y = A*x or A'*x depending on the shape of
8402      the matrix
8403 
8404    Neighbor-wise Collective on Mat
8405 
8406    Input Parameters:
8407 +  mat   - the matrix
8408 -  x,y - the vectors
8409 
8410    Level: intermediate
8411 
8412    Notes:
8413     This allows one to use either the restriction or interpolation (its transpose)
8414     matrix to do the interpolation
8415 
8416 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8417 
8418 @*/
8419 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8420 {
8421   PetscErrorCode ierr;
8422   PetscInt       M,N,Ny;
8423 
8424   PetscFunctionBegin;
8425   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8426   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8427   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8428   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8429   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8430   if (M == Ny) {
8431     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8432   } else {
8433     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8434   }
8435   PetscFunctionReturn(0);
8436 }
8437 
8438 /*@
8439    MatRestrict - y = A*x or A'*x
8440 
8441    Neighbor-wise Collective on Mat
8442 
8443    Input Parameters:
8444 +  mat   - the matrix
8445 -  x,y - the vectors
8446 
8447    Level: intermediate
8448 
8449    Notes:
8450     This allows one to use either the restriction or interpolation (its transpose)
8451     matrix to do the restriction
8452 
8453 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8454 
8455 @*/
8456 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8457 {
8458   PetscErrorCode ierr;
8459   PetscInt       M,N,Ny;
8460 
8461   PetscFunctionBegin;
8462   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8463   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8464   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8465   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8466   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8467   if (M == Ny) {
8468     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8469   } else {
8470     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8471   }
8472   PetscFunctionReturn(0);
8473 }
8474 
8475 /*@
8476    MatMatInterpolateAdd - Y = W + A*X or W + A'*X
8477 
8478    Neighbor-wise Collective on Mat
8479 
8480    Input Parameters:
8481 +  mat   - the matrix
8482 -  w, x - the input dense matrices
8483 
8484    Output Parameters:
8485 .  y - the output dense matrix
8486 
8487    Level: intermediate
8488 
8489    Notes:
8490     This allows one to use either the restriction or interpolation (its transpose)
8491     matrix to do the interpolation. y matrix can be reused if already created with the proper sizes,
8492     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8493 
8494 .seealso: MatInterpolateAdd(), MatMatInterpolate(), MatMatRestrict()
8495 
8496 @*/
8497 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y)
8498 {
8499   PetscErrorCode ierr;
8500   PetscInt       M,N,Mx,Nx,Mo,My = 0,Ny = 0;
8501   PetscBool      trans = PETSC_TRUE;
8502   MatReuse       reuse = MAT_INITIAL_MATRIX;
8503 
8504   PetscFunctionBegin;
8505   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8506   PetscValidHeaderSpecific(x,MAT_CLASSID,2);
8507   PetscValidType(x,2);
8508   if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3);
8509   if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4);
8510   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8511   ierr = MatGetSize(x,&Mx,&Nx);CHKERRQ(ierr);
8512   if (N == Mx) trans = PETSC_FALSE;
8513   else if (M != Mx) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Size mismatch: A %Dx%D, X %Dx%D",M,N,Mx,Nx);
8514   Mo = trans ? N : M;
8515   if (*y) {
8516     ierr = MatGetSize(*y,&My,&Ny);CHKERRQ(ierr);
8517     if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; }
8518     else {
8519       if (w && *y == w) SETERRQ6(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot reuse y and w, size mismatch: A %Dx%D, X %Dx%D, Y %Dx%D",M,N,Mx,Nx,My,Ny);
8520       ierr = MatDestroy(y);CHKERRQ(ierr);
8521     }
8522   }
8523 
8524   if (w && *y == w) { /* this is to minimize changes in PCMG */
8525     PetscBool flg;
8526 
8527     ierr = PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w);CHKERRQ(ierr);
8528     if (w) {
8529       PetscInt My,Ny,Mw,Nw;
8530 
8531       ierr = PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg);CHKERRQ(ierr);
8532       ierr = MatGetSize(*y,&My,&Ny);CHKERRQ(ierr);
8533       ierr = MatGetSize(w,&Mw,&Nw);CHKERRQ(ierr);
8534       if (!flg || My != Mw || Ny != Nw) w = NULL;
8535     }
8536     if (!w) {
8537       ierr = MatDuplicate(*y,MAT_COPY_VALUES,&w);CHKERRQ(ierr);
8538       ierr = PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w);CHKERRQ(ierr);
8539       ierr = PetscLogObjectParent((PetscObject)*y,(PetscObject)w);CHKERRQ(ierr);
8540       ierr = PetscObjectDereference((PetscObject)w);CHKERRQ(ierr);
8541     } else {
8542       ierr = MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr);
8543     }
8544   }
8545   if (!trans) {
8546     ierr = MatMatMult(A,x,reuse,PETSC_DEFAULT,y);CHKERRQ(ierr);
8547   } else {
8548     ierr = MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y);CHKERRQ(ierr);
8549   }
8550   if (w) {
8551     ierr = MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr);
8552   }
8553   PetscFunctionReturn(0);
8554 }
8555 
8556 /*@
8557    MatMatInterpolate - Y = A*X or A'*X
8558 
8559    Neighbor-wise Collective on Mat
8560 
8561    Input Parameters:
8562 +  mat   - the matrix
8563 -  x - the input dense matrix
8564 
8565    Output Parameters:
8566 .  y - the output dense matrix
8567 
8568 
8569    Level: intermediate
8570 
8571    Notes:
8572     This allows one to use either the restriction or interpolation (its transpose)
8573     matrix to do the interpolation. y matrix can be reused if already created with the proper sizes,
8574     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8575 
8576 .seealso: MatInterpolate(), MatRestrict(), MatMatRestrict()
8577 
8578 @*/
8579 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y)
8580 {
8581   PetscErrorCode ierr;
8582 
8583   PetscFunctionBegin;
8584   ierr = MatMatInterpolateAdd(A,x,NULL,y);CHKERRQ(ierr);
8585   PetscFunctionReturn(0);
8586 }
8587 
8588 /*@
8589    MatMatRestrict - Y = A*X or A'*X
8590 
8591    Neighbor-wise Collective on Mat
8592 
8593    Input Parameters:
8594 +  mat   - the matrix
8595 -  x - the input dense matrix
8596 
8597    Output Parameters:
8598 .  y - the output dense matrix
8599 
8600 
8601    Level: intermediate
8602 
8603    Notes:
8604     This allows one to use either the restriction or interpolation (its transpose)
8605     matrix to do the restriction. y matrix can be reused if already created with the proper sizes,
8606     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8607 
8608 .seealso: MatRestrict(), MatInterpolate(), MatMatInterpolate()
8609 @*/
8610 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y)
8611 {
8612   PetscErrorCode ierr;
8613 
8614   PetscFunctionBegin;
8615   ierr = MatMatInterpolateAdd(A,x,NULL,y);CHKERRQ(ierr);
8616   PetscFunctionReturn(0);
8617 }
8618 
8619 /*@
8620    MatGetNullSpace - retrieves the null space of a matrix.
8621 
8622    Logically Collective on Mat
8623 
8624    Input Parameters:
8625 +  mat - the matrix
8626 -  nullsp - the null space object
8627 
8628    Level: developer
8629 
8630 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8631 @*/
8632 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8633 {
8634   PetscFunctionBegin;
8635   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8636   PetscValidPointer(nullsp,2);
8637   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8638   PetscFunctionReturn(0);
8639 }
8640 
8641 /*@
8642    MatSetNullSpace - attaches a null space to a matrix.
8643 
8644    Logically Collective on Mat
8645 
8646    Input Parameters:
8647 +  mat - the matrix
8648 -  nullsp - the null space object
8649 
8650    Level: advanced
8651 
8652    Notes:
8653       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8654 
8655       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8656       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8657 
8658       You can remove the null space by calling this routine with an nullsp of NULL
8659 
8660 
8661       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8662    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).
8663    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
8664    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
8665    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).
8666 
8667       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8668 
8669     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
8670     routine also automatically calls MatSetTransposeNullSpace().
8671 
8672 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8673 @*/
8674 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8675 {
8676   PetscErrorCode ierr;
8677 
8678   PetscFunctionBegin;
8679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8680   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8681   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8682   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8683   mat->nullsp = nullsp;
8684   if (mat->symmetric_set && mat->symmetric) {
8685     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8686   }
8687   PetscFunctionReturn(0);
8688 }
8689 
8690 /*@
8691    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8692 
8693    Logically Collective on Mat
8694 
8695    Input Parameters:
8696 +  mat - the matrix
8697 -  nullsp - the null space object
8698 
8699    Level: developer
8700 
8701 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8702 @*/
8703 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8704 {
8705   PetscFunctionBegin;
8706   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8707   PetscValidType(mat,1);
8708   PetscValidPointer(nullsp,2);
8709   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8710   PetscFunctionReturn(0);
8711 }
8712 
8713 /*@
8714    MatSetTransposeNullSpace - attaches a null space to a matrix.
8715 
8716    Logically Collective on Mat
8717 
8718    Input Parameters:
8719 +  mat - the matrix
8720 -  nullsp - the null space object
8721 
8722    Level: advanced
8723 
8724    Notes:
8725       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.
8726       You must also call MatSetNullSpace()
8727 
8728 
8729       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8730    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).
8731    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
8732    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
8733    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).
8734 
8735       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8736 
8737 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8738 @*/
8739 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8740 {
8741   PetscErrorCode ierr;
8742 
8743   PetscFunctionBegin;
8744   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8745   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8746   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8747   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8748   mat->transnullsp = nullsp;
8749   PetscFunctionReturn(0);
8750 }
8751 
8752 /*@
8753    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8754         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8755 
8756    Logically Collective on Mat
8757 
8758    Input Parameters:
8759 +  mat - the matrix
8760 -  nullsp - the null space object
8761 
8762    Level: advanced
8763 
8764    Notes:
8765       Overwrites any previous near null space that may have been attached
8766 
8767       You can remove the null space by calling this routine with an nullsp of NULL
8768 
8769 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8770 @*/
8771 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8772 {
8773   PetscErrorCode ierr;
8774 
8775   PetscFunctionBegin;
8776   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8777   PetscValidType(mat,1);
8778   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8779   MatCheckPreallocated(mat,1);
8780   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8781   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8782   mat->nearnullsp = nullsp;
8783   PetscFunctionReturn(0);
8784 }
8785 
8786 /*@
8787    MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace()
8788 
8789    Not Collective
8790 
8791    Input Parameter:
8792 .  mat - the matrix
8793 
8794    Output Parameter:
8795 .  nullsp - the null space object, NULL if not set
8796 
8797    Level: developer
8798 
8799 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8800 @*/
8801 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8802 {
8803   PetscFunctionBegin;
8804   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8805   PetscValidType(mat,1);
8806   PetscValidPointer(nullsp,2);
8807   MatCheckPreallocated(mat,1);
8808   *nullsp = mat->nearnullsp;
8809   PetscFunctionReturn(0);
8810 }
8811 
8812 /*@C
8813    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8814 
8815    Collective on Mat
8816 
8817    Input Parameters:
8818 +  mat - the matrix
8819 .  row - row/column permutation
8820 .  fill - expected fill factor >= 1.0
8821 -  level - level of fill, for ICC(k)
8822 
8823    Notes:
8824    Probably really in-place only when level of fill is zero, otherwise allocates
8825    new space to store factored matrix and deletes previous memory.
8826 
8827    Most users should employ the simplified KSP interface for linear solvers
8828    instead of working directly with matrix algebra routines such as this.
8829    See, e.g., KSPCreate().
8830 
8831    Level: developer
8832 
8833 
8834 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8835 
8836     Developer Note: fortran interface is not autogenerated as the f90
8837     interface defintion cannot be generated correctly [due to MatFactorInfo]
8838 
8839 @*/
8840 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8841 {
8842   PetscErrorCode ierr;
8843 
8844   PetscFunctionBegin;
8845   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8846   PetscValidType(mat,1);
8847   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8848   PetscValidPointer(info,3);
8849   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8850   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8851   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8852   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8853   MatCheckPreallocated(mat,1);
8854   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8855   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8856   PetscFunctionReturn(0);
8857 }
8858 
8859 /*@
8860    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8861          ghosted ones.
8862 
8863    Not Collective
8864 
8865    Input Parameters:
8866 +  mat - the matrix
8867 -  diag = the diagonal values, including ghost ones
8868 
8869    Level: developer
8870 
8871    Notes:
8872     Works only for MPIAIJ and MPIBAIJ matrices
8873 
8874 .seealso: MatDiagonalScale()
8875 @*/
8876 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8877 {
8878   PetscErrorCode ierr;
8879   PetscMPIInt    size;
8880 
8881   PetscFunctionBegin;
8882   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8883   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8884   PetscValidType(mat,1);
8885 
8886   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8887   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8888   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
8889   if (size == 1) {
8890     PetscInt n,m;
8891     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8892     ierr = MatGetSize(mat,NULL,&m);CHKERRQ(ierr);
8893     if (m == n) {
8894       ierr = MatDiagonalScale(mat,NULL,diag);CHKERRQ(ierr);
8895     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8896   } else {
8897     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8898   }
8899   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8900   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8901   PetscFunctionReturn(0);
8902 }
8903 
8904 /*@
8905    MatGetInertia - Gets the inertia from a factored matrix
8906 
8907    Collective on Mat
8908 
8909    Input Parameter:
8910 .  mat - the matrix
8911 
8912    Output Parameters:
8913 +   nneg - number of negative eigenvalues
8914 .   nzero - number of zero eigenvalues
8915 -   npos - number of positive eigenvalues
8916 
8917    Level: advanced
8918 
8919    Notes:
8920     Matrix must have been factored by MatCholeskyFactor()
8921 
8922 
8923 @*/
8924 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8925 {
8926   PetscErrorCode ierr;
8927 
8928   PetscFunctionBegin;
8929   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8930   PetscValidType(mat,1);
8931   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8932   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8933   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8934   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8935   PetscFunctionReturn(0);
8936 }
8937 
8938 /* ----------------------------------------------------------------*/
8939 /*@C
8940    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8941 
8942    Neighbor-wise Collective on Mats
8943 
8944    Input Parameters:
8945 +  mat - the factored matrix
8946 -  b - the right-hand-side vectors
8947 
8948    Output Parameter:
8949 .  x - the result vectors
8950 
8951    Notes:
8952    The vectors b and x cannot be the same.  I.e., one cannot
8953    call MatSolves(A,x,x).
8954 
8955    Notes:
8956    Most users should employ the simplified KSP interface for linear solvers
8957    instead of working directly with matrix algebra routines such as this.
8958    See, e.g., KSPCreate().
8959 
8960    Level: developer
8961 
8962 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8963 @*/
8964 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8965 {
8966   PetscErrorCode ierr;
8967 
8968   PetscFunctionBegin;
8969   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8970   PetscValidType(mat,1);
8971   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8972   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8973   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8974 
8975   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8976   MatCheckPreallocated(mat,1);
8977   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8978   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8979   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8980   PetscFunctionReturn(0);
8981 }
8982 
8983 /*@
8984    MatIsSymmetric - Test whether a matrix is symmetric
8985 
8986    Collective on Mat
8987 
8988    Input Parameter:
8989 +  A - the matrix to test
8990 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8991 
8992    Output Parameters:
8993 .  flg - the result
8994 
8995    Notes:
8996     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8997 
8998    Level: intermediate
8999 
9000 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
9001 @*/
9002 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
9003 {
9004   PetscErrorCode ierr;
9005 
9006   PetscFunctionBegin;
9007   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9008   PetscValidBoolPointer(flg,3);
9009 
9010   if (!A->symmetric_set) {
9011     if (!A->ops->issymmetric) {
9012       MatType mattype;
9013       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9014       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
9015     }
9016     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
9017     if (!tol) {
9018       ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr);
9019     }
9020   } else if (A->symmetric) {
9021     *flg = PETSC_TRUE;
9022   } else if (!tol) {
9023     *flg = PETSC_FALSE;
9024   } else {
9025     if (!A->ops->issymmetric) {
9026       MatType mattype;
9027       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9028       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
9029     }
9030     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
9031   }
9032   PetscFunctionReturn(0);
9033 }
9034 
9035 /*@
9036    MatIsHermitian - Test whether a matrix is Hermitian
9037 
9038    Collective on Mat
9039 
9040    Input Parameter:
9041 +  A - the matrix to test
9042 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
9043 
9044    Output Parameters:
9045 .  flg - the result
9046 
9047    Level: intermediate
9048 
9049 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
9050           MatIsSymmetricKnown(), MatIsSymmetric()
9051 @*/
9052 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
9053 {
9054   PetscErrorCode ierr;
9055 
9056   PetscFunctionBegin;
9057   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9058   PetscValidBoolPointer(flg,3);
9059 
9060   if (!A->hermitian_set) {
9061     if (!A->ops->ishermitian) {
9062       MatType mattype;
9063       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9064       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
9065     }
9066     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
9067     if (!tol) {
9068       ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr);
9069     }
9070   } else if (A->hermitian) {
9071     *flg = PETSC_TRUE;
9072   } else if (!tol) {
9073     *flg = PETSC_FALSE;
9074   } else {
9075     if (!A->ops->ishermitian) {
9076       MatType mattype;
9077       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9078       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
9079     }
9080     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
9081   }
9082   PetscFunctionReturn(0);
9083 }
9084 
9085 /*@
9086    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
9087 
9088    Not Collective
9089 
9090    Input Parameter:
9091 .  A - the matrix to check
9092 
9093    Output Parameters:
9094 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
9095 -  flg - the result
9096 
9097    Level: advanced
9098 
9099    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
9100          if you want it explicitly checked
9101 
9102 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
9103 @*/
9104 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
9105 {
9106   PetscFunctionBegin;
9107   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9108   PetscValidPointer(set,2);
9109   PetscValidBoolPointer(flg,3);
9110   if (A->symmetric_set) {
9111     *set = PETSC_TRUE;
9112     *flg = A->symmetric;
9113   } else {
9114     *set = PETSC_FALSE;
9115   }
9116   PetscFunctionReturn(0);
9117 }
9118 
9119 /*@
9120    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
9121 
9122    Not Collective
9123 
9124    Input Parameter:
9125 .  A - the matrix to check
9126 
9127    Output Parameters:
9128 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
9129 -  flg - the result
9130 
9131    Level: advanced
9132 
9133    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
9134          if you want it explicitly checked
9135 
9136 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
9137 @*/
9138 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
9139 {
9140   PetscFunctionBegin;
9141   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9142   PetscValidPointer(set,2);
9143   PetscValidBoolPointer(flg,3);
9144   if (A->hermitian_set) {
9145     *set = PETSC_TRUE;
9146     *flg = A->hermitian;
9147   } else {
9148     *set = PETSC_FALSE;
9149   }
9150   PetscFunctionReturn(0);
9151 }
9152 
9153 /*@
9154    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
9155 
9156    Collective on Mat
9157 
9158    Input Parameter:
9159 .  A - the matrix to test
9160 
9161    Output Parameters:
9162 .  flg - the result
9163 
9164    Level: intermediate
9165 
9166 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
9167 @*/
9168 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
9169 {
9170   PetscErrorCode ierr;
9171 
9172   PetscFunctionBegin;
9173   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9174   PetscValidBoolPointer(flg,2);
9175   if (!A->structurally_symmetric_set) {
9176     if (!A->ops->isstructurallysymmetric) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetric",((PetscObject)A)->type_name);
9177     ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr);
9178     ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr);
9179   } else *flg = A->structurally_symmetric;
9180   PetscFunctionReturn(0);
9181 }
9182 
9183 /*@
9184    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
9185        to be communicated to other processors during the MatAssemblyBegin/End() process
9186 
9187     Not collective
9188 
9189    Input Parameter:
9190 .   vec - the vector
9191 
9192    Output Parameters:
9193 +   nstash   - the size of the stash
9194 .   reallocs - the number of additional mallocs incurred.
9195 .   bnstash   - the size of the block stash
9196 -   breallocs - the number of additional mallocs incurred.in the block stash
9197 
9198    Level: advanced
9199 
9200 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
9201 
9202 @*/
9203 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
9204 {
9205   PetscErrorCode ierr;
9206 
9207   PetscFunctionBegin;
9208   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
9209   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
9210   PetscFunctionReturn(0);
9211 }
9212 
9213 /*@C
9214    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
9215      parallel layout
9216 
9217    Collective on Mat
9218 
9219    Input Parameter:
9220 .  mat - the matrix
9221 
9222    Output Parameter:
9223 +   right - (optional) vector that the matrix can be multiplied against
9224 -   left - (optional) vector that the matrix vector product can be stored in
9225 
9226    Notes:
9227     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().
9228 
9229   Notes:
9230     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
9231 
9232   Level: advanced
9233 
9234 .seealso: MatCreate(), VecDestroy()
9235 @*/
9236 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
9237 {
9238   PetscErrorCode ierr;
9239 
9240   PetscFunctionBegin;
9241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9242   PetscValidType(mat,1);
9243   if (mat->ops->getvecs) {
9244     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
9245   } else {
9246     PetscInt rbs,cbs;
9247     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
9248     if (right) {
9249       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
9250       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
9251       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9252       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
9253       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
9254       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
9255     }
9256     if (left) {
9257       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9258       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
9259       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9260       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9261       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9262       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9263     }
9264   }
9265   PetscFunctionReturn(0);
9266 }
9267 
9268 /*@C
9269    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9270      with default values.
9271 
9272    Not Collective
9273 
9274    Input Parameters:
9275 .    info - the MatFactorInfo data structure
9276 
9277 
9278    Notes:
9279     The solvers are generally used through the KSP and PC objects, for example
9280           PCLU, PCILU, PCCHOLESKY, PCICC
9281 
9282    Level: developer
9283 
9284 .seealso: MatFactorInfo
9285 
9286     Developer Note: fortran interface is not autogenerated as the f90
9287     interface defintion cannot be generated correctly [due to MatFactorInfo]
9288 
9289 @*/
9290 
9291 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9292 {
9293   PetscErrorCode ierr;
9294 
9295   PetscFunctionBegin;
9296   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9297   PetscFunctionReturn(0);
9298 }
9299 
9300 /*@
9301    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9302 
9303    Collective on Mat
9304 
9305    Input Parameters:
9306 +  mat - the factored matrix
9307 -  is - the index set defining the Schur indices (0-based)
9308 
9309    Notes:
9310     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9311 
9312    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9313 
9314    Level: developer
9315 
9316 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9317           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9318 
9319 @*/
9320 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9321 {
9322   PetscErrorCode ierr,(*f)(Mat,IS);
9323 
9324   PetscFunctionBegin;
9325   PetscValidType(mat,1);
9326   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9327   PetscValidType(is,2);
9328   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9329   PetscCheckSameComm(mat,1,is,2);
9330   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9331   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9332   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
9333   ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9334   ierr = (*f)(mat,is);CHKERRQ(ierr);
9335   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9336   PetscFunctionReturn(0);
9337 }
9338 
9339 /*@
9340   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9341 
9342    Logically Collective on Mat
9343 
9344    Input Parameters:
9345 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9346 .  S - location where to return the Schur complement, can be NULL
9347 -  status - the status of the Schur complement matrix, can be NULL
9348 
9349    Notes:
9350    You must call MatFactorSetSchurIS() before calling this routine.
9351 
9352    The routine provides a copy of the Schur matrix stored within the solver data structures.
9353    The caller must destroy the object when it is no longer needed.
9354    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9355 
9356    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)
9357 
9358    Developer Notes:
9359     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9360    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9361 
9362    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9363 
9364    Level: advanced
9365 
9366    References:
9367 
9368 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9369 @*/
9370 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9371 {
9372   PetscErrorCode ierr;
9373 
9374   PetscFunctionBegin;
9375   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9376   if (S) PetscValidPointer(S,2);
9377   if (status) PetscValidPointer(status,3);
9378   if (S) {
9379     PetscErrorCode (*f)(Mat,Mat*);
9380 
9381     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9382     if (f) {
9383       ierr = (*f)(F,S);CHKERRQ(ierr);
9384     } else {
9385       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9386     }
9387   }
9388   if (status) *status = F->schur_status;
9389   PetscFunctionReturn(0);
9390 }
9391 
9392 /*@
9393   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9394 
9395    Logically Collective on Mat
9396 
9397    Input Parameters:
9398 +  F - the factored matrix obtained by calling MatGetFactor()
9399 .  *S - location where to return the Schur complement, can be NULL
9400 -  status - the status of the Schur complement matrix, can be NULL
9401 
9402    Notes:
9403    You must call MatFactorSetSchurIS() before calling this routine.
9404 
9405    Schur complement mode is currently implemented for sequential matrices.
9406    The routine returns a the Schur Complement stored within the data strutures of the solver.
9407    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9408    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9409 
9410    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9411 
9412    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9413 
9414    Level: advanced
9415 
9416    References:
9417 
9418 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9419 @*/
9420 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9421 {
9422   PetscFunctionBegin;
9423   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9424   if (S) PetscValidPointer(S,2);
9425   if (status) PetscValidPointer(status,3);
9426   if (S) *S = F->schur;
9427   if (status) *status = F->schur_status;
9428   PetscFunctionReturn(0);
9429 }
9430 
9431 /*@
9432   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9433 
9434    Logically Collective on Mat
9435 
9436    Input Parameters:
9437 +  F - the factored matrix obtained by calling MatGetFactor()
9438 .  *S - location where the Schur complement is stored
9439 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9440 
9441    Notes:
9442 
9443    Level: advanced
9444 
9445    References:
9446 
9447 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9448 @*/
9449 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9450 {
9451   PetscErrorCode ierr;
9452 
9453   PetscFunctionBegin;
9454   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9455   if (S) {
9456     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9457     *S = NULL;
9458   }
9459   F->schur_status = status;
9460   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9461   PetscFunctionReturn(0);
9462 }
9463 
9464 /*@
9465   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9466 
9467    Logically Collective on Mat
9468 
9469    Input Parameters:
9470 +  F - the factored matrix obtained by calling MatGetFactor()
9471 .  rhs - location where the right hand side of the Schur complement system is stored
9472 -  sol - location where the solution of the Schur complement system has to be returned
9473 
9474    Notes:
9475    The sizes of the vectors should match the size of the Schur complement
9476 
9477    Must be called after MatFactorSetSchurIS()
9478 
9479    Level: advanced
9480 
9481    References:
9482 
9483 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9484 @*/
9485 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9486 {
9487   PetscErrorCode ierr;
9488 
9489   PetscFunctionBegin;
9490   PetscValidType(F,1);
9491   PetscValidType(rhs,2);
9492   PetscValidType(sol,3);
9493   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9494   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9495   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9496   PetscCheckSameComm(F,1,rhs,2);
9497   PetscCheckSameComm(F,1,sol,3);
9498   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9499   switch (F->schur_status) {
9500   case MAT_FACTOR_SCHUR_FACTORED:
9501     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9502     break;
9503   case MAT_FACTOR_SCHUR_INVERTED:
9504     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9505     break;
9506   default:
9507     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9508   }
9509   PetscFunctionReturn(0);
9510 }
9511 
9512 /*@
9513   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9514 
9515    Logically Collective on Mat
9516 
9517    Input Parameters:
9518 +  F - the factored matrix obtained by calling MatGetFactor()
9519 .  rhs - location where the right hand side of the Schur complement system is stored
9520 -  sol - location where the solution of the Schur complement system has to be returned
9521 
9522    Notes:
9523    The sizes of the vectors should match the size of the Schur complement
9524 
9525    Must be called after MatFactorSetSchurIS()
9526 
9527    Level: advanced
9528 
9529    References:
9530 
9531 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9532 @*/
9533 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9534 {
9535   PetscErrorCode ierr;
9536 
9537   PetscFunctionBegin;
9538   PetscValidType(F,1);
9539   PetscValidType(rhs,2);
9540   PetscValidType(sol,3);
9541   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9542   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9543   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9544   PetscCheckSameComm(F,1,rhs,2);
9545   PetscCheckSameComm(F,1,sol,3);
9546   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9547   switch (F->schur_status) {
9548   case MAT_FACTOR_SCHUR_FACTORED:
9549     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9550     break;
9551   case MAT_FACTOR_SCHUR_INVERTED:
9552     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9553     break;
9554   default:
9555     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9556   }
9557   PetscFunctionReturn(0);
9558 }
9559 
9560 /*@
9561   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9562 
9563    Logically Collective on Mat
9564 
9565    Input Parameters:
9566 .  F - the factored matrix obtained by calling MatGetFactor()
9567 
9568    Notes:
9569     Must be called after MatFactorSetSchurIS().
9570 
9571    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9572 
9573    Level: advanced
9574 
9575    References:
9576 
9577 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9578 @*/
9579 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9580 {
9581   PetscErrorCode ierr;
9582 
9583   PetscFunctionBegin;
9584   PetscValidType(F,1);
9585   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9586   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9587   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9588   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9589   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9590   PetscFunctionReturn(0);
9591 }
9592 
9593 /*@
9594   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9595 
9596    Logically Collective on Mat
9597 
9598    Input Parameters:
9599 .  F - the factored matrix obtained by calling MatGetFactor()
9600 
9601    Notes:
9602     Must be called after MatFactorSetSchurIS().
9603 
9604    Level: advanced
9605 
9606    References:
9607 
9608 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9609 @*/
9610 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9611 {
9612   PetscErrorCode ierr;
9613 
9614   PetscFunctionBegin;
9615   PetscValidType(F,1);
9616   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9617   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9618   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9619   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9620   PetscFunctionReturn(0);
9621 }
9622 
9623 /*@
9624    MatPtAP - Creates the matrix product C = P^T * A * P
9625 
9626    Neighbor-wise Collective on Mat
9627 
9628    Input Parameters:
9629 +  A - the matrix
9630 .  P - the projection matrix
9631 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9632 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9633           if the result is a dense matrix this is irrelevent
9634 
9635    Output Parameters:
9636 .  C - the product matrix
9637 
9638    Notes:
9639    C will be created and must be destroyed by the user with MatDestroy().
9640 
9641    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9642 
9643    Level: intermediate
9644 
9645 .seealso: MatMatMult(), MatRARt()
9646 @*/
9647 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9648 {
9649   PetscErrorCode ierr;
9650 
9651   PetscFunctionBegin;
9652   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9653   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9654 
9655   if (scall == MAT_INITIAL_MATRIX) {
9656     ierr = MatProductCreate(A,P,NULL,C);CHKERRQ(ierr);
9657     ierr = MatProductSetType(*C,MATPRODUCT_PtAP);CHKERRQ(ierr);
9658     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9659     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9660 
9661     (*C)->product->api_user = PETSC_TRUE;
9662     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9663     if (!(*C)->ops->productsymbolic) SETERRQ3(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and P %s",MatProductTypes[MATPRODUCT_PtAP],((PetscObject)A)->type_name,((PetscObject)P)->type_name);
9664     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9665   } else { /* scall == MAT_REUSE_MATRIX */
9666     ierr = MatProductReplaceMats(A,P,NULL,*C);CHKERRQ(ierr);
9667   }
9668 
9669   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9670   if (A->symmetric_set && A->symmetric) {
9671     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9672   }
9673   PetscFunctionReturn(0);
9674 }
9675 
9676 /*@
9677    MatRARt - Creates the matrix product C = R * A * R^T
9678 
9679    Neighbor-wise Collective on Mat
9680 
9681    Input Parameters:
9682 +  A - the matrix
9683 .  R - the projection matrix
9684 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9685 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9686           if the result is a dense matrix this is irrelevent
9687 
9688    Output Parameters:
9689 .  C - the product matrix
9690 
9691    Notes:
9692    C will be created and must be destroyed by the user with MatDestroy().
9693 
9694    This routine is currently only implemented for pairs of AIJ matrices and classes
9695    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9696    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9697    We recommend using MatPtAP().
9698 
9699    Level: intermediate
9700 
9701 .seealso: MatMatMult(), MatPtAP()
9702 @*/
9703 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9704 {
9705   PetscErrorCode ierr;
9706 
9707   PetscFunctionBegin;
9708   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9709   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9710 
9711   if (scall == MAT_INITIAL_MATRIX) {
9712     ierr = MatProductCreate(A,R,NULL,C);CHKERRQ(ierr);
9713     ierr = MatProductSetType(*C,MATPRODUCT_RARt);CHKERRQ(ierr);
9714     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9715     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9716 
9717     (*C)->product->api_user = PETSC_TRUE;
9718     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9719     if (!(*C)->ops->productsymbolic) SETERRQ3(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and R %s",MatProductTypes[MATPRODUCT_RARt],((PetscObject)A)->type_name,((PetscObject)R)->type_name);
9720     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9721   } else { /* scall == MAT_REUSE_MATRIX */
9722     ierr = MatProductReplaceMats(A,R,NULL,*C);CHKERRQ(ierr);
9723   }
9724 
9725   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9726   if (A->symmetric_set && A->symmetric) {
9727     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9728   }
9729   PetscFunctionReturn(0);
9730 }
9731 
9732 
9733 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C)
9734 {
9735   PetscErrorCode ierr;
9736 
9737   PetscFunctionBegin;
9738   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9739 
9740   if (scall == MAT_INITIAL_MATRIX) {
9741     ierr = PetscInfo1(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype]);CHKERRQ(ierr);
9742     ierr = MatProductCreate(A,B,NULL,C);CHKERRQ(ierr);
9743     ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9744     ierr = MatProductSetAlgorithm(*C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
9745     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9746 
9747     (*C)->product->api_user = PETSC_TRUE;
9748     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9749     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9750   } else { /* scall == MAT_REUSE_MATRIX */
9751     Mat_Product *product = (*C)->product;
9752 
9753     ierr = PetscInfo2(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype]);CHKERRQ(ierr);
9754     if (!product) {
9755       /* user provide the dense matrix *C without calling MatProductCreate() */
9756       PetscBool isdense;
9757 
9758       ierr = PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr);
9759       if (isdense) {
9760         /* user wants to reuse an assembled dense matrix */
9761         /* Create product -- see MatCreateProduct() */
9762         ierr = MatProductCreate_Private(A,B,NULL,*C);CHKERRQ(ierr);
9763         product = (*C)->product;
9764         product->fill     = fill;
9765         product->api_user = PETSC_TRUE;
9766         product->clear    = PETSC_TRUE;
9767 
9768         ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9769         ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9770         if (!(*C)->ops->productsymbolic) SETERRQ3(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for %s and %s",MatProductTypes[ptype],((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9771         ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9772       } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first");
9773     } else { /* user may change input matrices A or B when REUSE */
9774       ierr = MatProductReplaceMats(A,B,NULL,*C);CHKERRQ(ierr);
9775     }
9776   }
9777   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9778   PetscFunctionReturn(0);
9779 }
9780 
9781 /*@
9782    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9783 
9784    Neighbor-wise Collective on Mat
9785 
9786    Input Parameters:
9787 +  A - the left matrix
9788 .  B - the right matrix
9789 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9790 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9791           if the result is a dense matrix this is irrelevent
9792 
9793    Output Parameters:
9794 .  C - the product matrix
9795 
9796    Notes:
9797    Unless scall is MAT_REUSE_MATRIX C will be created.
9798 
9799    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
9800    call to this function with MAT_INITIAL_MATRIX.
9801 
9802    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed.
9803 
9804    If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic(C)/ReplaceMats(), and call MatProductNumeric() repeatedly.
9805 
9806    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.
9807 
9808    Level: intermediate
9809 
9810 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9811 @*/
9812 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9813 {
9814   PetscErrorCode ierr;
9815 
9816   PetscFunctionBegin;
9817   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C);CHKERRQ(ierr);
9818   PetscFunctionReturn(0);
9819 }
9820 
9821 /*@
9822    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9823 
9824    Neighbor-wise Collective on Mat
9825 
9826    Input Parameters:
9827 +  A - the left matrix
9828 .  B - the right matrix
9829 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9830 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9831 
9832    Output Parameters:
9833 .  C - the product matrix
9834 
9835    Notes:
9836    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9837 
9838    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9839 
9840   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9841    actually needed.
9842 
9843    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9844    and for pairs of MPIDense matrices.
9845 
9846    Options Database Keys:
9847 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9848                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9849                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9850 
9851    Level: intermediate
9852 
9853 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP()
9854 @*/
9855 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9856 {
9857   PetscErrorCode ierr;
9858 
9859   PetscFunctionBegin;
9860   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C);CHKERRQ(ierr);
9861   PetscFunctionReturn(0);
9862 }
9863 
9864 /*@
9865    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9866 
9867    Neighbor-wise Collective on Mat
9868 
9869    Input Parameters:
9870 +  A - the left matrix
9871 .  B - the right matrix
9872 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9873 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9874 
9875    Output Parameters:
9876 .  C - the product matrix
9877 
9878    Notes:
9879    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9880 
9881    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call.
9882 
9883   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9884    actually needed.
9885 
9886    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9887    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9888 
9889    Level: intermediate
9890 
9891 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP()
9892 @*/
9893 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9894 {
9895   PetscErrorCode ierr;
9896 
9897   PetscFunctionBegin;
9898   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C);CHKERRQ(ierr);
9899   PetscFunctionReturn(0);
9900 }
9901 
9902 /*@
9903    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9904 
9905    Neighbor-wise Collective on Mat
9906 
9907    Input Parameters:
9908 +  A - the left matrix
9909 .  B - the middle matrix
9910 .  C - the right matrix
9911 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9912 -  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
9913           if the result is a dense matrix this is irrelevent
9914 
9915    Output Parameters:
9916 .  D - the product matrix
9917 
9918    Notes:
9919    Unless scall is MAT_REUSE_MATRIX D will be created.
9920 
9921    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9922 
9923    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9924    actually needed.
9925 
9926    If you have many matrices with the same non-zero structure to multiply, you
9927    should use MAT_REUSE_MATRIX in all calls but the first or
9928 
9929    Level: intermediate
9930 
9931 .seealso: MatMatMult, MatPtAP()
9932 @*/
9933 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9934 {
9935   PetscErrorCode ierr;
9936 
9937   PetscFunctionBegin;
9938   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6);
9939   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9940 
9941   if (scall == MAT_INITIAL_MATRIX) {
9942     ierr = MatProductCreate(A,B,C,D);CHKERRQ(ierr);
9943     ierr = MatProductSetType(*D,MATPRODUCT_ABC);CHKERRQ(ierr);
9944     ierr = MatProductSetAlgorithm(*D,"default");CHKERRQ(ierr);
9945     ierr = MatProductSetFill(*D,fill);CHKERRQ(ierr);
9946 
9947     (*D)->product->api_user = PETSC_TRUE;
9948     ierr = MatProductSetFromOptions(*D);CHKERRQ(ierr);
9949     if (!(*D)->ops->productsymbolic) SETERRQ4(PetscObjectComm((PetscObject)(*D)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s, B %s and C %s",MatProductTypes[MATPRODUCT_ABC],((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9950     ierr = MatProductSymbolic(*D);CHKERRQ(ierr);
9951   } else { /* user may change input matrices when REUSE */
9952     ierr = MatProductReplaceMats(A,B,C,*D);CHKERRQ(ierr);
9953   }
9954   ierr = MatProductNumeric(*D);CHKERRQ(ierr);
9955   PetscFunctionReturn(0);
9956 }
9957 
9958 /*@
9959    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9960 
9961    Collective on Mat
9962 
9963    Input Parameters:
9964 +  mat - the matrix
9965 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9966 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9967 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9968 
9969    Output Parameter:
9970 .  matredundant - redundant matrix
9971 
9972    Notes:
9973    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9974    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9975 
9976    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9977    calling it.
9978 
9979    Level: advanced
9980 
9981 
9982 .seealso: MatDestroy()
9983 @*/
9984 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9985 {
9986   PetscErrorCode ierr;
9987   MPI_Comm       comm;
9988   PetscMPIInt    size;
9989   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9990   Mat_Redundant  *redund=NULL;
9991   PetscSubcomm   psubcomm=NULL;
9992   MPI_Comm       subcomm_in=subcomm;
9993   Mat            *matseq;
9994   IS             isrow,iscol;
9995   PetscBool      newsubcomm=PETSC_FALSE;
9996 
9997   PetscFunctionBegin;
9998   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9999   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10000     PetscValidPointer(*matredundant,5);
10001     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10002   }
10003 
10004   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
10005   if (size == 1 || nsubcomm == 1) {
10006     if (reuse == MAT_INITIAL_MATRIX) {
10007       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10008     } else {
10009       if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10010       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10011     }
10012     PetscFunctionReturn(0);
10013   }
10014 
10015   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10016   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10017   MatCheckPreallocated(mat,1);
10018 
10019   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10020   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10021     /* create psubcomm, then get subcomm */
10022     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10023     ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
10024     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10025 
10026     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10027     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10028     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10029     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10030     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10031     newsubcomm = PETSC_TRUE;
10032     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10033   }
10034 
10035   /* get isrow, iscol and a local sequential matrix matseq[0] */
10036   if (reuse == MAT_INITIAL_MATRIX) {
10037     mloc_sub = PETSC_DECIDE;
10038     nloc_sub = PETSC_DECIDE;
10039     if (bs < 1) {
10040       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10041       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10042     } else {
10043       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10044       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10045     }
10046     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRMPI(ierr);
10047     rstart = rend - mloc_sub;
10048     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10049     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10050   } else { /* reuse == MAT_REUSE_MATRIX */
10051     if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10052     /* retrieve subcomm */
10053     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10054     redund = (*matredundant)->redundant;
10055     isrow  = redund->isrow;
10056     iscol  = redund->iscol;
10057     matseq = redund->matseq;
10058   }
10059   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10060 
10061   /* get matredundant over subcomm */
10062   if (reuse == MAT_INITIAL_MATRIX) {
10063     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10064 
10065     /* create a supporting struct and attach it to C for reuse */
10066     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10067     (*matredundant)->redundant = redund;
10068     redund->isrow              = isrow;
10069     redund->iscol              = iscol;
10070     redund->matseq             = matseq;
10071     if (newsubcomm) {
10072       redund->subcomm          = subcomm;
10073     } else {
10074       redund->subcomm          = MPI_COMM_NULL;
10075     }
10076   } else {
10077     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10078   }
10079   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10080   PetscFunctionReturn(0);
10081 }
10082 
10083 /*@C
10084    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10085    a given 'mat' object. Each submatrix can span multiple procs.
10086 
10087    Collective on Mat
10088 
10089    Input Parameters:
10090 +  mat - the matrix
10091 .  subcomm - the subcommunicator obtained by com_split(comm)
10092 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10093 
10094    Output Parameter:
10095 .  subMat - 'parallel submatrices each spans a given subcomm
10096 
10097   Notes:
10098   The submatrix partition across processors is dictated by 'subComm' a
10099   communicator obtained by com_split(comm). The comm_split
10100   is not restriced to be grouped with consecutive original ranks.
10101 
10102   Due the comm_split() usage, the parallel layout of the submatrices
10103   map directly to the layout of the original matrix [wrt the local
10104   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10105   into the 'DiagonalMat' of the subMat, hence it is used directly from
10106   the subMat. However the offDiagMat looses some columns - and this is
10107   reconstructed with MatSetValues()
10108 
10109   Level: advanced
10110 
10111 
10112 .seealso: MatCreateSubMatrices()
10113 @*/
10114 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10115 {
10116   PetscErrorCode ierr;
10117   PetscMPIInt    commsize,subCommSize;
10118 
10119   PetscFunctionBegin;
10120   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRMPI(ierr);
10121   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRMPI(ierr);
10122   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10123 
10124   if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10125   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10126   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10127   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10128   PetscFunctionReturn(0);
10129 }
10130 
10131 /*@
10132    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10133 
10134    Not Collective
10135 
10136    Input Arguments:
10137 +  mat - matrix to extract local submatrix from
10138 .  isrow - local row indices for submatrix
10139 -  iscol - local column indices for submatrix
10140 
10141    Output Arguments:
10142 .  submat - the submatrix
10143 
10144    Level: intermediate
10145 
10146    Notes:
10147    The submat should be returned with MatRestoreLocalSubMatrix().
10148 
10149    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10150    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10151 
10152    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10153    MatSetValuesBlockedLocal() will also be implemented.
10154 
10155    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10156    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10157 
10158 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10159 @*/
10160 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10161 {
10162   PetscErrorCode ierr;
10163 
10164   PetscFunctionBegin;
10165   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10166   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10167   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10168   PetscCheckSameComm(isrow,2,iscol,3);
10169   PetscValidPointer(submat,4);
10170   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10171 
10172   if (mat->ops->getlocalsubmatrix) {
10173     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10174   } else {
10175     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10176   }
10177   PetscFunctionReturn(0);
10178 }
10179 
10180 /*@
10181    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10182 
10183    Not Collective
10184 
10185    Input Arguments:
10186    mat - matrix to extract local submatrix from
10187    isrow - local row indices for submatrix
10188    iscol - local column indices for submatrix
10189    submat - the submatrix
10190 
10191    Level: intermediate
10192 
10193 .seealso: MatGetLocalSubMatrix()
10194 @*/
10195 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10196 {
10197   PetscErrorCode ierr;
10198 
10199   PetscFunctionBegin;
10200   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10201   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10202   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10203   PetscCheckSameComm(isrow,2,iscol,3);
10204   PetscValidPointer(submat,4);
10205   if (*submat) {
10206     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10207   }
10208 
10209   if (mat->ops->restorelocalsubmatrix) {
10210     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10211   } else {
10212     ierr = MatDestroy(submat);CHKERRQ(ierr);
10213   }
10214   *submat = NULL;
10215   PetscFunctionReturn(0);
10216 }
10217 
10218 /* --------------------------------------------------------*/
10219 /*@
10220    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10221 
10222    Collective on Mat
10223 
10224    Input Parameter:
10225 .  mat - the matrix
10226 
10227    Output Parameter:
10228 .  is - if any rows have zero diagonals this contains the list of them
10229 
10230    Level: developer
10231 
10232 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10233 @*/
10234 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10235 {
10236   PetscErrorCode ierr;
10237 
10238   PetscFunctionBegin;
10239   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10240   PetscValidType(mat,1);
10241   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10242   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10243 
10244   if (!mat->ops->findzerodiagonals) {
10245     Vec                diag;
10246     const PetscScalar *a;
10247     PetscInt          *rows;
10248     PetscInt           rStart, rEnd, r, nrow = 0;
10249 
10250     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10251     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10252     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10253     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10254     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10255     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10256     nrow = 0;
10257     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10258     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10259     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10260     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10261   } else {
10262     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10263   }
10264   PetscFunctionReturn(0);
10265 }
10266 
10267 /*@
10268    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10269 
10270    Collective on Mat
10271 
10272    Input Parameter:
10273 .  mat - the matrix
10274 
10275    Output Parameter:
10276 .  is - contains the list of rows with off block diagonal entries
10277 
10278    Level: developer
10279 
10280 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10281 @*/
10282 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10283 {
10284   PetscErrorCode ierr;
10285 
10286   PetscFunctionBegin;
10287   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10288   PetscValidType(mat,1);
10289   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10290   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10291 
10292   if (!mat->ops->findoffblockdiagonalentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name);
10293   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10294   PetscFunctionReturn(0);
10295 }
10296 
10297 /*@C
10298   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10299 
10300   Collective on Mat
10301 
10302   Input Parameters:
10303 . mat - the matrix
10304 
10305   Output Parameters:
10306 . values - the block inverses in column major order (FORTRAN-like)
10307 
10308    Note:
10309    This routine is not available from Fortran.
10310 
10311   Level: advanced
10312 
10313 .seealso: MatInvertBockDiagonalMat
10314 @*/
10315 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10316 {
10317   PetscErrorCode ierr;
10318 
10319   PetscFunctionBegin;
10320   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10321   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10322   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10323   if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
10324   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10325   PetscFunctionReturn(0);
10326 }
10327 
10328 /*@C
10329   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10330 
10331   Collective on Mat
10332 
10333   Input Parameters:
10334 + mat - the matrix
10335 . nblocks - the number of blocks
10336 - bsizes - the size of each block
10337 
10338   Output Parameters:
10339 . values - the block inverses in column major order (FORTRAN-like)
10340 
10341    Note:
10342    This routine is not available from Fortran.
10343 
10344   Level: advanced
10345 
10346 .seealso: MatInvertBockDiagonal()
10347 @*/
10348 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10349 {
10350   PetscErrorCode ierr;
10351 
10352   PetscFunctionBegin;
10353   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10354   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10355   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10356   if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name);
10357   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10358   PetscFunctionReturn(0);
10359 }
10360 
10361 /*@
10362   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10363 
10364   Collective on Mat
10365 
10366   Input Parameters:
10367 . A - the matrix
10368 
10369   Output Parameters:
10370 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10371 
10372   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10373 
10374   Level: advanced
10375 
10376 .seealso: MatInvertBockDiagonal()
10377 @*/
10378 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10379 {
10380   PetscErrorCode     ierr;
10381   const PetscScalar *vals;
10382   PetscInt          *dnnz;
10383   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10384 
10385   PetscFunctionBegin;
10386   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10387   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10388   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10389   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10390   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10391   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10392   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10393   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10394   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10395   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10396   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10397   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10398   for (i = rstart/bs; i < rend/bs; i++) {
10399     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10400   }
10401   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10402   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10403   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10404   PetscFunctionReturn(0);
10405 }
10406 
10407 /*@C
10408     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10409     via MatTransposeColoringCreate().
10410 
10411     Collective on MatTransposeColoring
10412 
10413     Input Parameter:
10414 .   c - coloring context
10415 
10416     Level: intermediate
10417 
10418 .seealso: MatTransposeColoringCreate()
10419 @*/
10420 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10421 {
10422   PetscErrorCode       ierr;
10423   MatTransposeColoring matcolor=*c;
10424 
10425   PetscFunctionBegin;
10426   if (!matcolor) PetscFunctionReturn(0);
10427   if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);}
10428 
10429   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10430   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10431   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10432   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10433   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10434   if (matcolor->brows>0) {
10435     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10436   }
10437   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10438   PetscFunctionReturn(0);
10439 }
10440 
10441 /*@C
10442     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10443     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10444     MatTransposeColoring to sparse B.
10445 
10446     Collective on MatTransposeColoring
10447 
10448     Input Parameters:
10449 +   B - sparse matrix B
10450 .   Btdense - symbolic dense matrix B^T
10451 -   coloring - coloring context created with MatTransposeColoringCreate()
10452 
10453     Output Parameter:
10454 .   Btdense - dense matrix B^T
10455 
10456     Level: advanced
10457 
10458      Notes:
10459     These are used internally for some implementations of MatRARt()
10460 
10461 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10462 
10463 @*/
10464 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10465 {
10466   PetscErrorCode ierr;
10467 
10468   PetscFunctionBegin;
10469   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10470   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3);
10471   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10472 
10473   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10474   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10475   PetscFunctionReturn(0);
10476 }
10477 
10478 /*@C
10479     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10480     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10481     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10482     Csp from Cden.
10483 
10484     Collective on MatTransposeColoring
10485 
10486     Input Parameters:
10487 +   coloring - coloring context created with MatTransposeColoringCreate()
10488 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10489 
10490     Output Parameter:
10491 .   Csp - sparse matrix
10492 
10493     Level: advanced
10494 
10495      Notes:
10496     These are used internally for some implementations of MatRARt()
10497 
10498 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10499 
10500 @*/
10501 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10502 {
10503   PetscErrorCode ierr;
10504 
10505   PetscFunctionBegin;
10506   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10507   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10508   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10509 
10510   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10511   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10512   ierr = MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10513   ierr = MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10514   PetscFunctionReturn(0);
10515 }
10516 
10517 /*@C
10518    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10519 
10520    Collective on Mat
10521 
10522    Input Parameters:
10523 +  mat - the matrix product C
10524 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10525 
10526     Output Parameter:
10527 .   color - the new coloring context
10528 
10529     Level: intermediate
10530 
10531 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10532            MatTransColoringApplyDenToSp()
10533 @*/
10534 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10535 {
10536   MatTransposeColoring c;
10537   MPI_Comm             comm;
10538   PetscErrorCode       ierr;
10539 
10540   PetscFunctionBegin;
10541   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10542   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10543   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10544 
10545   c->ctype = iscoloring->ctype;
10546   if (mat->ops->transposecoloringcreate) {
10547     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10548   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10549 
10550   *color = c;
10551   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10552   PetscFunctionReturn(0);
10553 }
10554 
10555 /*@
10556       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10557         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10558         same, otherwise it will be larger
10559 
10560      Not Collective
10561 
10562   Input Parameter:
10563 .    A  - the matrix
10564 
10565   Output Parameter:
10566 .    state - the current state
10567 
10568   Notes:
10569     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10570          different matrices
10571 
10572   Level: intermediate
10573 
10574 @*/
10575 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10576 {
10577   PetscFunctionBegin;
10578   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10579   *state = mat->nonzerostate;
10580   PetscFunctionReturn(0);
10581 }
10582 
10583 /*@
10584       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10585                  matrices from each processor
10586 
10587     Collective
10588 
10589    Input Parameters:
10590 +    comm - the communicators the parallel matrix will live on
10591 .    seqmat - the input sequential matrices
10592 .    n - number of local columns (or PETSC_DECIDE)
10593 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10594 
10595    Output Parameter:
10596 .    mpimat - the parallel matrix generated
10597 
10598     Level: advanced
10599 
10600    Notes:
10601     The number of columns of the matrix in EACH processor MUST be the same.
10602 
10603 @*/
10604 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10605 {
10606   PetscErrorCode ierr;
10607 
10608   PetscFunctionBegin;
10609   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10610   if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10611 
10612   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10613   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10614   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10615   PetscFunctionReturn(0);
10616 }
10617 
10618 /*@
10619      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10620                  ranks' ownership ranges.
10621 
10622     Collective on A
10623 
10624    Input Parameters:
10625 +    A   - the matrix to create subdomains from
10626 -    N   - requested number of subdomains
10627 
10628 
10629    Output Parameters:
10630 +    n   - number of subdomains resulting on this rank
10631 -    iss - IS list with indices of subdomains on this rank
10632 
10633     Level: advanced
10634 
10635     Notes:
10636     number of subdomains must be smaller than the communicator size
10637 @*/
10638 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10639 {
10640   MPI_Comm        comm,subcomm;
10641   PetscMPIInt     size,rank,color;
10642   PetscInt        rstart,rend,k;
10643   PetscErrorCode  ierr;
10644 
10645   PetscFunctionBegin;
10646   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10647   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
10648   ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr);
10649   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10650   *n = 1;
10651   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10652   color = rank/k;
10653   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRMPI(ierr);
10654   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10655   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10656   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10657   ierr = MPI_Comm_free(&subcomm);CHKERRMPI(ierr);
10658   PetscFunctionReturn(0);
10659 }
10660 
10661 /*@
10662    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10663 
10664    If the interpolation and restriction operators are the same, uses MatPtAP.
10665    If they are not the same, use MatMatMatMult.
10666 
10667    Once the coarse grid problem is constructed, correct for interpolation operators
10668    that are not of full rank, which can legitimately happen in the case of non-nested
10669    geometric multigrid.
10670 
10671    Input Parameters:
10672 +  restrct - restriction operator
10673 .  dA - fine grid matrix
10674 .  interpolate - interpolation operator
10675 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10676 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10677 
10678    Output Parameters:
10679 .  A - the Galerkin coarse matrix
10680 
10681    Options Database Key:
10682 .  -pc_mg_galerkin <both,pmat,mat,none>
10683 
10684    Level: developer
10685 
10686 .seealso: MatPtAP(), MatMatMatMult()
10687 @*/
10688 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10689 {
10690   PetscErrorCode ierr;
10691   IS             zerorows;
10692   Vec            diag;
10693 
10694   PetscFunctionBegin;
10695   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10696   /* Construct the coarse grid matrix */
10697   if (interpolate == restrct) {
10698     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10699   } else {
10700     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10701   }
10702 
10703   /* If the interpolation matrix is not of full rank, A will have zero rows.
10704      This can legitimately happen in the case of non-nested geometric multigrid.
10705      In that event, we set the rows of the matrix to the rows of the identity,
10706      ignoring the equations (as the RHS will also be zero). */
10707 
10708   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10709 
10710   if (zerorows != NULL) { /* if there are any zero rows */
10711     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10712     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10713     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10714     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10715     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10716     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10717   }
10718   PetscFunctionReturn(0);
10719 }
10720 
10721 /*@C
10722     MatSetOperation - Allows user to set a matrix operation for any matrix type
10723 
10724    Logically Collective on Mat
10725 
10726     Input Parameters:
10727 +   mat - the matrix
10728 .   op - the name of the operation
10729 -   f - the function that provides the operation
10730 
10731    Level: developer
10732 
10733     Usage:
10734 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10735 $      ierr = MatCreateXXX(comm,...&A);
10736 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10737 
10738     Notes:
10739     See the file include/petscmat.h for a complete list of matrix
10740     operations, which all have the form MATOP_<OPERATION>, where
10741     <OPERATION> is the name (in all capital letters) of the
10742     user interface routine (e.g., MatMult() -> MATOP_MULT).
10743 
10744     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10745     sequence as the usual matrix interface routines, since they
10746     are intended to be accessed via the usual matrix interface
10747     routines, e.g.,
10748 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10749 
10750     In particular each function MUST return an error code of 0 on success and
10751     nonzero on failure.
10752 
10753     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10754 
10755 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10756 @*/
10757 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10758 {
10759   PetscFunctionBegin;
10760   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10761   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10762     mat->ops->viewnative = mat->ops->view;
10763   }
10764   (((void(**)(void))mat->ops)[op]) = f;
10765   PetscFunctionReturn(0);
10766 }
10767 
10768 /*@C
10769     MatGetOperation - Gets a matrix operation for any matrix type.
10770 
10771     Not Collective
10772 
10773     Input Parameters:
10774 +   mat - the matrix
10775 -   op - the name of the operation
10776 
10777     Output Parameter:
10778 .   f - the function that provides the operation
10779 
10780     Level: developer
10781 
10782     Usage:
10783 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10784 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10785 
10786     Notes:
10787     See the file include/petscmat.h for a complete list of matrix
10788     operations, which all have the form MATOP_<OPERATION>, where
10789     <OPERATION> is the name (in all capital letters) of the
10790     user interface routine (e.g., MatMult() -> MATOP_MULT).
10791 
10792     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10793 
10794 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10795 @*/
10796 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10797 {
10798   PetscFunctionBegin;
10799   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10800   *f = (((void (**)(void))mat->ops)[op]);
10801   PetscFunctionReturn(0);
10802 }
10803 
10804 /*@
10805     MatHasOperation - Determines whether the given matrix supports the particular
10806     operation.
10807 
10808    Not Collective
10809 
10810    Input Parameters:
10811 +  mat - the matrix
10812 -  op - the operation, for example, MATOP_GET_DIAGONAL
10813 
10814    Output Parameter:
10815 .  has - either PETSC_TRUE or PETSC_FALSE
10816 
10817    Level: advanced
10818 
10819    Notes:
10820    See the file include/petscmat.h for a complete list of matrix
10821    operations, which all have the form MATOP_<OPERATION>, where
10822    <OPERATION> is the name (in all capital letters) of the
10823    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10824 
10825 .seealso: MatCreateShell()
10826 @*/
10827 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10828 {
10829   PetscErrorCode ierr;
10830 
10831   PetscFunctionBegin;
10832   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10833   /* symbolic product can be set before matrix type */
10834   if (op != MATOP_PRODUCTSYMBOLIC) PetscValidType(mat,1);
10835   PetscValidPointer(has,3);
10836   if (mat->ops->hasoperation) {
10837     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10838   } else {
10839     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10840     else {
10841       *has = PETSC_FALSE;
10842       if (op == MATOP_CREATE_SUBMATRIX) {
10843         PetscMPIInt size;
10844 
10845         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
10846         if (size == 1) {
10847           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10848         }
10849       }
10850     }
10851   }
10852   PetscFunctionReturn(0);
10853 }
10854 
10855 /*@
10856     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10857     of the matrix are congruent
10858 
10859    Collective on mat
10860 
10861    Input Parameters:
10862 .  mat - the matrix
10863 
10864    Output Parameter:
10865 .  cong - either PETSC_TRUE or PETSC_FALSE
10866 
10867    Level: beginner
10868 
10869    Notes:
10870 
10871 .seealso: MatCreate(), MatSetSizes()
10872 @*/
10873 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10874 {
10875   PetscErrorCode ierr;
10876 
10877   PetscFunctionBegin;
10878   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10879   PetscValidType(mat,1);
10880   PetscValidPointer(cong,2);
10881   if (!mat->rmap || !mat->cmap) {
10882     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10883     PetscFunctionReturn(0);
10884   }
10885   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10886     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10887     if (*cong) mat->congruentlayouts = 1;
10888     else       mat->congruentlayouts = 0;
10889   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10890   PetscFunctionReturn(0);
10891 }
10892 
10893 PetscErrorCode MatSetInf(Mat A)
10894 {
10895   PetscErrorCode ierr;
10896 
10897   PetscFunctionBegin;
10898   if (!A->ops->setinf) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type");
10899   ierr = (*A->ops->setinf)(A);CHKERRQ(ierr);
10900   PetscFunctionReturn(0);
10901 }
10902