xref: /petsc/src/mat/interface/matrix.c (revision 45480ffeba491aca5d3f3b8c78679069fb317d32) !
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,3);
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,2);
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,2);
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   PetscValidIntPointer(idxm,3);
1579   PetscValidIntPointer(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   PetscValidIntPointer(idxm,3);
1687   PetscValidIntPointer(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   PetscValidScalarPointer(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,1);
3125   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3126   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3127   if (info) PetscValidPointer(info,4);
3128   PetscValidType(mat,1);
3129   PetscValidPointer(fact,5);
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 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3178 {
3179   MatFactorInfo  tinfo;
3180   PetscErrorCode ierr;
3181 
3182   PetscFunctionBegin;
3183   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3184   PetscValidType(mat,1);
3185   PetscValidPointer(fact,2);
3186   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3187   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3188   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);
3189 
3190   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3191   MatCheckPreallocated(mat,2);
3192   if (!info) {
3193     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3194     info = &tinfo;
3195   }
3196 
3197   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3198   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3199   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3200   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3201   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3202   PetscFunctionReturn(0);
3203 }
3204 
3205 /*@C
3206    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3207    symmetric matrix.
3208 
3209    Collective on Mat
3210 
3211    Input Parameters:
3212 +  mat - the matrix
3213 .  perm - row and column permutations
3214 -  f - expected fill as ratio of original fill
3215 
3216    Notes:
3217    See MatLUFactor() for the nonsymmetric case.  See also
3218    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3219 
3220    Most users should employ the simplified KSP interface for linear solvers
3221    instead of working directly with matrix algebra routines such as this.
3222    See, e.g., KSPCreate().
3223 
3224    Level: developer
3225 
3226 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3227           MatGetOrdering()
3228 
3229     Developer Note: fortran interface is not autogenerated as the f90
3230     interface defintion cannot be generated correctly [due to MatFactorInfo]
3231 
3232 @*/
3233 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3234 {
3235   PetscErrorCode ierr;
3236   MatFactorInfo  tinfo;
3237 
3238   PetscFunctionBegin;
3239   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3240   PetscValidType(mat,1);
3241   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3242   if (info) PetscValidPointer(info,3);
3243   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3244   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3245   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3246   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);
3247   MatCheckPreallocated(mat,1);
3248   if (!info) {
3249     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3250     info = &tinfo;
3251   }
3252 
3253   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3254   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3255   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3256   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3257   PetscFunctionReturn(0);
3258 }
3259 
3260 /*@C
3261    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3262    of a symmetric matrix.
3263 
3264    Collective on Mat
3265 
3266    Input Parameters:
3267 +  fact - the factor matrix obtained with MatGetFactor()
3268 .  mat - the matrix
3269 .  perm - row and column permutations
3270 -  info - options for factorization, includes
3271 $          fill - expected fill as ratio of original fill.
3272 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3273 $                   Run with the option -info to determine an optimal value to use
3274 
3275    Notes:
3276    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3277    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3278 
3279    Most users should employ the simplified KSP interface for linear solvers
3280    instead of working directly with matrix algebra routines such as this.
3281    See, e.g., KSPCreate().
3282 
3283    Level: developer
3284 
3285 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3286           MatGetOrdering()
3287 
3288     Developer Note: fortran interface is not autogenerated as the f90
3289     interface defintion cannot be generated correctly [due to MatFactorInfo]
3290 
3291 @*/
3292 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3293 {
3294   PetscErrorCode ierr;
3295   MatFactorInfo  tinfo;
3296 
3297   PetscFunctionBegin;
3298   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3299   PetscValidType(mat,1);
3300   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3301   if (info) PetscValidPointer(info,3);
3302   PetscValidPointer(fact,4);
3303   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3304   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3305   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3306   if (!(fact)->ops->choleskyfactorsymbolic) {
3307     MatSolverType stype;
3308     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
3309     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype);
3310   }
3311   MatCheckPreallocated(mat,2);
3312   if (!info) {
3313     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3314     info = &tinfo;
3315   }
3316 
3317   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3318   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3319   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3320   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3321   PetscFunctionReturn(0);
3322 }
3323 
3324 /*@C
3325    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3326    of a symmetric matrix. Call this routine after first calling
3327    MatCholeskyFactorSymbolic().
3328 
3329    Collective on Mat
3330 
3331    Input Parameters:
3332 +  fact - the factor matrix obtained with MatGetFactor()
3333 .  mat - the initial matrix
3334 .  info - options for factorization
3335 -  fact - the symbolic factor of mat
3336 
3337 
3338    Notes:
3339    Most users should employ the simplified KSP interface for linear solvers
3340    instead of working directly with matrix algebra routines such as this.
3341    See, e.g., KSPCreate().
3342 
3343    Level: developer
3344 
3345 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3346 
3347     Developer Note: fortran interface is not autogenerated as the f90
3348     interface defintion cannot be generated correctly [due to MatFactorInfo]
3349 
3350 @*/
3351 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3352 {
3353   MatFactorInfo  tinfo;
3354   PetscErrorCode ierr;
3355 
3356   PetscFunctionBegin;
3357   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3358   PetscValidType(mat,1);
3359   PetscValidPointer(fact,2);
3360   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3361   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3362   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3363   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);
3364   MatCheckPreallocated(mat,2);
3365   if (!info) {
3366     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3367     info = &tinfo;
3368   }
3369 
3370   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3371   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3372   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3373   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3374   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3375   PetscFunctionReturn(0);
3376 }
3377 
3378 /*@C
3379    MatQRFactor - Performs in-place QR factorization of matrix.
3380 
3381    Collective on Mat
3382 
3383    Input Parameters:
3384 +  mat - the matrix
3385 .  col - column permutation
3386 -  info - options for factorization, includes
3387 $          fill - expected fill as ratio of original fill.
3388 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3389 $                   Run with the option -info to determine an optimal value to use
3390 
3391    Notes:
3392    Most users should employ the simplified KSP interface for linear solvers
3393    instead of working directly with matrix algebra routines such as this.
3394    See, e.g., KSPCreate().
3395 
3396    This changes the state of the matrix to a factored matrix; it cannot be used
3397    for example with MatSetValues() unless one first calls MatSetUnfactored().
3398 
3399    Level: developer
3400 
3401 .seealso: MatQRFactorSymbolic(), MatQRFactorNumeric(), MatLUFactor(),
3402           MatSetUnfactored(), MatFactorInfo, MatGetFactor()
3403 
3404     Developer Note: fortran interface is not autogenerated as the f90
3405     interface defintion cannot be generated correctly [due to MatFactorInfo]
3406 
3407 @*/
3408 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info)
3409 {
3410   PetscErrorCode ierr;
3411 
3412   PetscFunctionBegin;
3413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3414   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2);
3415   if (info) PetscValidPointer(info,3);
3416   PetscValidType(mat,1);
3417   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3418   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3419   MatCheckPreallocated(mat,1);
3420   ierr = PetscLogEventBegin(MAT_QRFactor,mat,col,0,0);CHKERRQ(ierr);
3421   ierr = PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info));CHKERRQ(ierr);
3422   ierr = PetscLogEventEnd(MAT_QRFactor,mat,col,0,0);CHKERRQ(ierr);
3423   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3424   PetscFunctionReturn(0);
3425 }
3426 
3427 /*@C
3428    MatQRFactorSymbolic - Performs symbolic QR factorization of matrix.
3429    Call this routine before calling MatQRFactorNumeric().
3430 
3431    Collective on Mat
3432 
3433    Input Parameters:
3434 +  fact - the factor matrix obtained with MatGetFactor()
3435 .  mat - the matrix
3436 .  col - column permutation
3437 -  info - options for factorization, includes
3438 $          fill - expected fill as ratio of original fill.
3439 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3440 $                   Run with the option -info to determine an optimal value to use
3441 
3442    Most users should employ the simplified KSP interface for linear solvers
3443    instead of working directly with matrix algebra routines such as this.
3444    See, e.g., KSPCreate().
3445 
3446    Level: developer
3447 
3448 .seealso: MatQRFactor(), MatQRFactorNumeric(), MatLUFactor(), MatFactorInfo, MatFactorInfoInitialize()
3449 
3450     Developer Note: fortran interface is not autogenerated as the f90
3451     interface defintion cannot be generated correctly [due to MatFactorInfo]
3452 
3453 @*/
3454 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info)
3455 {
3456   PetscErrorCode ierr;
3457   MatFactorInfo  tinfo;
3458 
3459   PetscFunctionBegin;
3460   PetscValidHeaderSpecific(mat,MAT_CLASSID,2);
3461   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3462   if (info) PetscValidPointer(info,4);
3463   PetscValidType(mat,2);
3464   PetscValidPointer(fact,1);
3465   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3466   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3467   MatCheckPreallocated(mat,2);
3468   if (!info) {
3469     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3470     info = &tinfo;
3471   }
3472 
3473   ierr = PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0);CHKERRQ(ierr);
3474   ierr = PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info));CHKERRQ(ierr);
3475   ierr = PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0);CHKERRQ(ierr);
3476   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3477   PetscFunctionReturn(0);
3478 }
3479 
3480 /*@C
3481    MatQRFactorNumeric - Performs numeric QR factorization of a matrix.
3482    Call this routine after first calling MatQRFactorSymbolic().
3483 
3484    Collective on Mat
3485 
3486    Input Parameters:
3487 +  fact - the factor matrix obtained with MatGetFactor()
3488 .  mat - the matrix
3489 -  info - options for factorization
3490 
3491    Notes:
3492    See MatQRFactor() for in-place factorization.
3493 
3494    Most users should employ the simplified KSP interface for linear solvers
3495    instead of working directly with matrix algebra routines such as this.
3496    See, e.g., KSPCreate().
3497 
3498    Level: developer
3499 
3500 .seealso: MatQRFactorSymbolic(), MatLUFactor()
3501 
3502     Developer Note: fortran interface is not autogenerated as the f90
3503     interface defintion cannot be generated correctly [due to MatFactorInfo]
3504 
3505 @*/
3506 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3507 {
3508   MatFactorInfo  tinfo;
3509   PetscErrorCode ierr;
3510 
3511   PetscFunctionBegin;
3512   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3513   PetscValidType(mat,1);
3514   PetscValidPointer(fact,2);
3515   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3516   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3517   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);
3518 
3519   MatCheckPreallocated(mat,2);
3520   if (!info) {
3521     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
3522     info = &tinfo;
3523   }
3524 
3525   ierr = PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3526   ierr = PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info));CHKERRQ(ierr);
3527   ierr = PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3528   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3529   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3530   PetscFunctionReturn(0);
3531 }
3532 
3533 /* ----------------------------------------------------------------*/
3534 /*@
3535    MatSolve - Solves A x = b, given a factored matrix.
3536 
3537    Neighbor-wise Collective on Mat
3538 
3539    Input Parameters:
3540 +  mat - the factored matrix
3541 -  b - the right-hand-side vector
3542 
3543    Output Parameter:
3544 .  x - the result vector
3545 
3546    Notes:
3547    The vectors b and x cannot be the same.  I.e., one cannot
3548    call MatSolve(A,x,x).
3549 
3550    Notes:
3551    Most users should employ the simplified KSP interface for linear solvers
3552    instead of working directly with matrix algebra routines such as this.
3553    See, e.g., KSPCreate().
3554 
3555    Level: developer
3556 
3557 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3558 @*/
3559 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3560 {
3561   PetscErrorCode ierr;
3562 
3563   PetscFunctionBegin;
3564   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3565   PetscValidType(mat,1);
3566   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3567   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3568   PetscCheckSameComm(mat,1,b,2);
3569   PetscCheckSameComm(mat,1,x,3);
3570   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3571   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);
3572   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);
3573   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);
3574   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3575   MatCheckPreallocated(mat,1);
3576 
3577   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3578   if (mat->factorerrortype) {
3579     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3580     ierr = VecSetInf(x);CHKERRQ(ierr);
3581   } else {
3582     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3583     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3584   }
3585   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3586   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3587   PetscFunctionReturn(0);
3588 }
3589 
3590 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans)
3591 {
3592   PetscErrorCode ierr;
3593   Vec            b,x;
3594   PetscInt       m,N,i;
3595   PetscScalar    *bb,*xx;
3596   PetscErrorCode (*f)(Mat,Vec,Vec);
3597 
3598   PetscFunctionBegin;
3599   if (A->factorerrortype) {
3600     ierr = PetscInfo1(A,"MatFactorError %D\n",A->factorerrortype);CHKERRQ(ierr);
3601     ierr = MatSetInf(X);CHKERRQ(ierr);
3602     PetscFunctionReturn(0);
3603   }
3604   f = trans ? A->ops->solvetranspose : A->ops->solve;
3605   if (!f) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3606 
3607   ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3608   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3609   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3610   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3611   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3612   for (i=0; i<N; i++) {
3613     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3614     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3615     ierr = (*f)(A,b,x);CHKERRQ(ierr);
3616     ierr = VecResetArray(x);CHKERRQ(ierr);
3617     ierr = VecResetArray(b);CHKERRQ(ierr);
3618   }
3619   ierr = VecDestroy(&b);CHKERRQ(ierr);
3620   ierr = VecDestroy(&x);CHKERRQ(ierr);
3621   ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr);
3622   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3623   PetscFunctionReturn(0);
3624 }
3625 
3626 /*@
3627    MatMatSolve - Solves A X = B, given a factored matrix.
3628 
3629    Neighbor-wise Collective on Mat
3630 
3631    Input Parameters:
3632 +  A - the factored matrix
3633 -  B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS)
3634 
3635    Output Parameter:
3636 .  X - the result matrix (dense matrix)
3637 
3638    Notes:
3639    If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO;
3640    otherwise, B and X cannot be the same.
3641 
3642    Notes:
3643    Most users should usually employ the simplified KSP interface for linear solvers
3644    instead of working directly with matrix algebra routines such as this.
3645    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3646    at a time.
3647 
3648    Level: developer
3649 
3650 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3651 @*/
3652 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3653 {
3654   PetscErrorCode ierr;
3655 
3656   PetscFunctionBegin;
3657   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3658   PetscValidType(A,1);
3659   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3660   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3661   PetscCheckSameComm(A,1,B,2);
3662   PetscCheckSameComm(A,1,X,3);
3663   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);
3664   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);
3665   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");
3666   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3667   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3668   MatCheckPreallocated(A,1);
3669 
3670   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3671   if (!A->ops->matsolve) {
3672     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3673     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3674   } else {
3675     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3676   }
3677   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3678   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3679   PetscFunctionReturn(0);
3680 }
3681 
3682 /*@
3683    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3684 
3685    Neighbor-wise Collective on Mat
3686 
3687    Input Parameters:
3688 +  A - the factored matrix
3689 -  B - the right-hand-side matrix  (dense matrix)
3690 
3691    Output Parameter:
3692 .  X - the result matrix (dense matrix)
3693 
3694    Notes:
3695    The matrices B and X cannot be the same.  I.e., one cannot
3696    call MatMatSolveTranspose(A,X,X).
3697 
3698    Notes:
3699    Most users should usually employ the simplified KSP interface for linear solvers
3700    instead of working directly with matrix algebra routines such as this.
3701    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3702    at a time.
3703 
3704    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3705 
3706    Level: developer
3707 
3708 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3709 @*/
3710 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3711 {
3712   PetscErrorCode ierr;
3713 
3714   PetscFunctionBegin;
3715   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3716   PetscValidType(A,1);
3717   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3718   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3719   PetscCheckSameComm(A,1,B,2);
3720   PetscCheckSameComm(A,1,X,3);
3721   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3722   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);
3723   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);
3724   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);
3725   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");
3726   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3727   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3728   MatCheckPreallocated(A,1);
3729 
3730   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3731   if (!A->ops->matsolvetranspose) {
3732     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3733     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3734   } else {
3735     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3736   }
3737   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3738   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3739   PetscFunctionReturn(0);
3740 }
3741 
3742 /*@
3743    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3744 
3745    Neighbor-wise Collective on Mat
3746 
3747    Input Parameters:
3748 +  A - the factored matrix
3749 -  Bt - the transpose of right-hand-side matrix
3750 
3751    Output Parameter:
3752 .  X - the result matrix (dense matrix)
3753 
3754    Notes:
3755    Most users should usually employ the simplified KSP interface for linear solvers
3756    instead of working directly with matrix algebra routines such as this.
3757    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3758    at a time.
3759 
3760    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().
3761 
3762    Level: developer
3763 
3764 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3765 @*/
3766 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3767 {
3768   PetscErrorCode ierr;
3769 
3770   PetscFunctionBegin;
3771   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3772   PetscValidType(A,1);
3773   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3774   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3775   PetscCheckSameComm(A,1,Bt,2);
3776   PetscCheckSameComm(A,1,X,3);
3777 
3778   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3779   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);
3780   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);
3781   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");
3782   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3783   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3784   MatCheckPreallocated(A,1);
3785 
3786   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3787   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3788   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3789   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3790   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3791   PetscFunctionReturn(0);
3792 }
3793 
3794 /*@
3795    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3796                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3797 
3798    Neighbor-wise Collective on Mat
3799 
3800    Input Parameters:
3801 +  mat - the factored matrix
3802 -  b - the right-hand-side vector
3803 
3804    Output Parameter:
3805 .  x - the result vector
3806 
3807    Notes:
3808    MatSolve() should be used for most applications, as it performs
3809    a forward solve followed by a backward solve.
3810 
3811    The vectors b and x cannot be the same,  i.e., one cannot
3812    call MatForwardSolve(A,x,x).
3813 
3814    For matrix in seqsbaij format with block size larger than 1,
3815    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3816    MatForwardSolve() solves U^T*D y = b, and
3817    MatBackwardSolve() solves U x = y.
3818    Thus they do not provide a symmetric preconditioner.
3819 
3820    Most users should employ the simplified KSP interface for linear solvers
3821    instead of working directly with matrix algebra routines such as this.
3822    See, e.g., KSPCreate().
3823 
3824    Level: developer
3825 
3826 .seealso: MatSolve(), MatBackwardSolve()
3827 @*/
3828 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3829 {
3830   PetscErrorCode ierr;
3831 
3832   PetscFunctionBegin;
3833   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3834   PetscValidType(mat,1);
3835   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3836   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3837   PetscCheckSameComm(mat,1,b,2);
3838   PetscCheckSameComm(mat,1,x,3);
3839   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3840   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);
3841   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);
3842   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);
3843   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3844   MatCheckPreallocated(mat,1);
3845 
3846   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3847   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3848   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3849   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3850   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3851   PetscFunctionReturn(0);
3852 }
3853 
3854 /*@
3855    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3856                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3857 
3858    Neighbor-wise Collective on Mat
3859 
3860    Input Parameters:
3861 +  mat - the factored matrix
3862 -  b - the right-hand-side vector
3863 
3864    Output Parameter:
3865 .  x - the result vector
3866 
3867    Notes:
3868    MatSolve() should be used for most applications, as it performs
3869    a forward solve followed by a backward solve.
3870 
3871    The vectors b and x cannot be the same.  I.e., one cannot
3872    call MatBackwardSolve(A,x,x).
3873 
3874    For matrix in seqsbaij format with block size larger than 1,
3875    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3876    MatForwardSolve() solves U^T*D y = b, and
3877    MatBackwardSolve() solves U x = y.
3878    Thus they do not provide a symmetric preconditioner.
3879 
3880    Most users should employ the simplified KSP interface for linear solvers
3881    instead of working directly with matrix algebra routines such as this.
3882    See, e.g., KSPCreate().
3883 
3884    Level: developer
3885 
3886 .seealso: MatSolve(), MatForwardSolve()
3887 @*/
3888 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3889 {
3890   PetscErrorCode ierr;
3891 
3892   PetscFunctionBegin;
3893   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3894   PetscValidType(mat,1);
3895   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3896   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3897   PetscCheckSameComm(mat,1,b,2);
3898   PetscCheckSameComm(mat,1,x,3);
3899   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3900   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);
3901   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);
3902   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);
3903   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3904   MatCheckPreallocated(mat,1);
3905 
3906   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3907   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3908   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3909   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3910   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3911   PetscFunctionReturn(0);
3912 }
3913 
3914 /*@
3915    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3916 
3917    Neighbor-wise Collective on Mat
3918 
3919    Input Parameters:
3920 +  mat - the factored matrix
3921 .  b - the right-hand-side vector
3922 -  y - the vector to be added to
3923 
3924    Output Parameter:
3925 .  x - the result vector
3926 
3927    Notes:
3928    The vectors b and x cannot be the same.  I.e., one cannot
3929    call MatSolveAdd(A,x,y,x).
3930 
3931    Most users should employ the simplified KSP interface for linear solvers
3932    instead of working directly with matrix algebra routines such as this.
3933    See, e.g., KSPCreate().
3934 
3935    Level: developer
3936 
3937 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3938 @*/
3939 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3940 {
3941   PetscScalar    one = 1.0;
3942   Vec            tmp;
3943   PetscErrorCode ierr;
3944 
3945   PetscFunctionBegin;
3946   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3947   PetscValidType(mat,1);
3948   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3949   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3950   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3951   PetscCheckSameComm(mat,1,b,2);
3952   PetscCheckSameComm(mat,1,y,2);
3953   PetscCheckSameComm(mat,1,x,3);
3954   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3955   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);
3956   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);
3957   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);
3958   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3959   if (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);
3960   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3961    MatCheckPreallocated(mat,1);
3962 
3963   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3964   if (mat->factorerrortype) {
3965     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3966     ierr = VecSetInf(x);CHKERRQ(ierr);
3967   } else if (mat->ops->solveadd) {
3968     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3969   } else {
3970     /* do the solve then the add manually */
3971     if (x != y) {
3972       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3973       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3974     } else {
3975       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3976       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3977       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3978       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3979       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3980       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3981     }
3982   }
3983   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3984   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3985   PetscFunctionReturn(0);
3986 }
3987 
3988 /*@
3989    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3990 
3991    Neighbor-wise Collective on Mat
3992 
3993    Input Parameters:
3994 +  mat - the factored matrix
3995 -  b - the right-hand-side vector
3996 
3997    Output Parameter:
3998 .  x - the result vector
3999 
4000    Notes:
4001    The vectors b and x cannot be the same.  I.e., one cannot
4002    call MatSolveTranspose(A,x,x).
4003 
4004    Most users should employ the simplified KSP interface for linear solvers
4005    instead of working directly with matrix algebra routines such as this.
4006    See, e.g., KSPCreate().
4007 
4008    Level: developer
4009 
4010 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
4011 @*/
4012 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
4013 {
4014   PetscErrorCode ierr;
4015 
4016   PetscFunctionBegin;
4017   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4018   PetscValidType(mat,1);
4019   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4020   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4021   PetscCheckSameComm(mat,1,b,2);
4022   PetscCheckSameComm(mat,1,x,3);
4023   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
4024   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);
4025   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);
4026   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
4027   MatCheckPreallocated(mat,1);
4028   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
4029   if (mat->factorerrortype) {
4030     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
4031     ierr = VecSetInf(x);CHKERRQ(ierr);
4032   } else {
4033     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
4034     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
4035   }
4036   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
4037   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4038   PetscFunctionReturn(0);
4039 }
4040 
4041 /*@
4042    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
4043                       factored matrix.
4044 
4045    Neighbor-wise Collective on Mat
4046 
4047    Input Parameters:
4048 +  mat - the factored matrix
4049 .  b - the right-hand-side vector
4050 -  y - the vector to be added to
4051 
4052    Output Parameter:
4053 .  x - the result vector
4054 
4055    Notes:
4056    The vectors b and x cannot be the same.  I.e., one cannot
4057    call MatSolveTransposeAdd(A,x,y,x).
4058 
4059    Most users should employ the simplified KSP interface for linear solvers
4060    instead of working directly with matrix algebra routines such as this.
4061    See, e.g., KSPCreate().
4062 
4063    Level: developer
4064 
4065 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
4066 @*/
4067 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
4068 {
4069   PetscScalar    one = 1.0;
4070   PetscErrorCode ierr;
4071   Vec            tmp;
4072 
4073   PetscFunctionBegin;
4074   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4075   PetscValidType(mat,1);
4076   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
4077   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
4078   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
4079   PetscCheckSameComm(mat,1,b,2);
4080   PetscCheckSameComm(mat,1,y,3);
4081   PetscCheckSameComm(mat,1,x,4);
4082   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
4083   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);
4084   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);
4085   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);
4086   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);
4087   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
4088    MatCheckPreallocated(mat,1);
4089 
4090   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
4091   if (mat->factorerrortype) {
4092     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
4093     ierr = VecSetInf(x);CHKERRQ(ierr);
4094   } else if (mat->ops->solvetransposeadd){
4095     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
4096   } else {
4097     /* do the solve then the add manually */
4098     if (x != y) {
4099       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
4100       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
4101     } else {
4102       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
4103       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
4104       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
4105       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
4106       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
4107       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
4108     }
4109   }
4110   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
4111   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4112   PetscFunctionReturn(0);
4113 }
4114 /* ----------------------------------------------------------------*/
4115 
4116 /*@
4117    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
4118 
4119    Neighbor-wise Collective on Mat
4120 
4121    Input Parameters:
4122 +  mat - the matrix
4123 .  b - the right hand side
4124 .  omega - the relaxation factor
4125 .  flag - flag indicating the type of SOR (see below)
4126 .  shift -  diagonal shift
4127 .  its - the number of iterations
4128 -  lits - the number of local iterations
4129 
4130    Output Parameters:
4131 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
4132 
4133    SOR Flags:
4134 +     SOR_FORWARD_SWEEP - forward SOR
4135 .     SOR_BACKWARD_SWEEP - backward SOR
4136 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
4137 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
4138 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
4139 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
4140 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
4141          upper/lower triangular part of matrix to
4142          vector (with omega)
4143 -     SOR_ZERO_INITIAL_GUESS - zero initial guess
4144 
4145    Notes:
4146    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
4147    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
4148    on each processor.
4149 
4150    Application programmers will not generally use MatSOR() directly,
4151    but instead will employ the KSP/PC interface.
4152 
4153    Notes:
4154     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
4155 
4156    Notes for Advanced Users:
4157    The flags are implemented as bitwise inclusive or operations.
4158    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
4159    to specify a zero initial guess for SSOR.
4160 
4161    Most users should employ the simplified KSP interface for linear solvers
4162    instead of working directly with matrix algebra routines such as this.
4163    See, e.g., KSPCreate().
4164 
4165    Vectors x and b CANNOT be the same
4166 
4167    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
4168 
4169    Level: developer
4170 
4171 @*/
4172 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4173 {
4174   PetscErrorCode ierr;
4175 
4176   PetscFunctionBegin;
4177   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4178   PetscValidType(mat,1);
4179   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4180   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4181   PetscCheckSameComm(mat,1,b,2);
4182   PetscCheckSameComm(mat,1,x,8);
4183   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4184   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4185   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4186   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);
4187   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);
4188   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);
4189   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4190   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4191   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4192 
4193   MatCheckPreallocated(mat,1);
4194   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4195   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4196   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4197   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4198   PetscFunctionReturn(0);
4199 }
4200 
4201 /*
4202       Default matrix copy routine.
4203 */
4204 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4205 {
4206   PetscErrorCode    ierr;
4207   PetscInt          i,rstart = 0,rend = 0,nz;
4208   const PetscInt    *cwork;
4209   const PetscScalar *vwork;
4210 
4211   PetscFunctionBegin;
4212   if (B->assembled) {
4213     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4214   }
4215   if (str == SAME_NONZERO_PATTERN) {
4216     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4217     for (i=rstart; i<rend; i++) {
4218       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4219       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4220       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4221     }
4222   } else {
4223     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4224   }
4225   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4226   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4227   PetscFunctionReturn(0);
4228 }
4229 
4230 /*@
4231    MatCopy - Copies a matrix to another matrix.
4232 
4233    Collective on Mat
4234 
4235    Input Parameters:
4236 +  A - the matrix
4237 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4238 
4239    Output Parameter:
4240 .  B - where the copy is put
4241 
4242    Notes:
4243    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4244    same nonzero pattern or the routine will crash.
4245 
4246    MatCopy() copies the matrix entries of a matrix to another existing
4247    matrix (after first zeroing the second matrix).  A related routine is
4248    MatConvert(), which first creates a new matrix and then copies the data.
4249 
4250    Level: intermediate
4251 
4252 .seealso: MatConvert(), MatDuplicate()
4253 
4254 @*/
4255 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4256 {
4257   PetscErrorCode ierr;
4258   PetscInt       i;
4259 
4260   PetscFunctionBegin;
4261   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4262   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4263   PetscValidType(A,1);
4264   PetscValidType(B,2);
4265   PetscCheckSameComm(A,1,B,2);
4266   MatCheckPreallocated(B,2);
4267   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4268   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4269   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);
4270   MatCheckPreallocated(A,1);
4271   if (A == B) PetscFunctionReturn(0);
4272 
4273   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4274   if (A->ops->copy) {
4275     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4276   } else { /* generic conversion */
4277     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4278   }
4279 
4280   B->stencil.dim = A->stencil.dim;
4281   B->stencil.noc = A->stencil.noc;
4282   for (i=0; i<=A->stencil.dim; i++) {
4283     B->stencil.dims[i]   = A->stencil.dims[i];
4284     B->stencil.starts[i] = A->stencil.starts[i];
4285   }
4286 
4287   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4288   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4289   PetscFunctionReturn(0);
4290 }
4291 
4292 /*@C
4293    MatConvert - Converts a matrix to another matrix, either of the same
4294    or different type.
4295 
4296    Collective on Mat
4297 
4298    Input Parameters:
4299 +  mat - the matrix
4300 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4301    same type as the original matrix.
4302 -  reuse - denotes if the destination matrix is to be created or reused.
4303    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
4304    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).
4305 
4306    Output Parameter:
4307 .  M - pointer to place new matrix
4308 
4309    Notes:
4310    MatConvert() first creates a new matrix and then copies the data from
4311    the first matrix.  A related routine is MatCopy(), which copies the matrix
4312    entries of one matrix to another already existing matrix context.
4313 
4314    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4315    the MPI communicator of the generated matrix is always the same as the communicator
4316    of the input matrix.
4317 
4318    Level: intermediate
4319 
4320 .seealso: MatCopy(), MatDuplicate()
4321 @*/
4322 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4323 {
4324   PetscErrorCode ierr;
4325   PetscBool      sametype,issame,flg,issymmetric,ishermitian;
4326   char           convname[256],mtype[256];
4327   Mat            B;
4328 
4329   PetscFunctionBegin;
4330   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4331   PetscValidType(mat,1);
4332   PetscValidPointer(M,4);
4333   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4334   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4335   MatCheckPreallocated(mat,1);
4336 
4337   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg);CHKERRQ(ierr);
4338   if (flg) newtype = mtype;
4339 
4340   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4341   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4342   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4343   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");
4344 
4345   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) {
4346     ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4347     PetscFunctionReturn(0);
4348   }
4349 
4350   /* Cache Mat options because some converter use MatHeaderReplace  */
4351   issymmetric = mat->symmetric;
4352   ishermitian = mat->hermitian;
4353 
4354   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4355     ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr);
4356     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4357   } else {
4358     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4359     const char     *prefix[3] = {"seq","mpi",""};
4360     PetscInt       i;
4361     /*
4362        Order of precedence:
4363        0) See if newtype is a superclass of the current matrix.
4364        1) See if a specialized converter is known to the current matrix.
4365        2) See if a specialized converter is known to the desired matrix class.
4366        3) See if a good general converter is registered for the desired class
4367           (as of 6/27/03 only MATMPIADJ falls into this category).
4368        4) See if a good general converter is known for the current matrix.
4369        5) Use a really basic converter.
4370     */
4371 
4372     /* 0) See if newtype is a superclass of the current matrix.
4373           i.e mat is mpiaij and newtype is aij */
4374     for (i=0; i<2; i++) {
4375       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4376       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4377       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4378       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4379       if (flg) {
4380         if (reuse == MAT_INPLACE_MATRIX) {
4381           ierr = PetscInfo(mat,"Early return\n");CHKERRQ(ierr);
4382           PetscFunctionReturn(0);
4383         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4384           ierr = PetscInfo(mat,"Calling MatDuplicate\n");CHKERRQ(ierr);
4385           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4386           PetscFunctionReturn(0);
4387         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4388           ierr = PetscInfo(mat,"Calling MatCopy\n");CHKERRQ(ierr);
4389           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4390           PetscFunctionReturn(0);
4391         }
4392       }
4393     }
4394     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4395     for (i=0; i<3; i++) {
4396       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4397       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4398       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4399       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4400       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4401       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4402       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4403       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4404       if (conv) goto foundconv;
4405     }
4406 
4407     /* 2)  See if a specialized converter is known to the desired matrix class. */
4408     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4409     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4410     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4411     for (i=0; i<3; i++) {
4412       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4413       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4414       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4415       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4416       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4417       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4418       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4419       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4420       if (conv) {
4421         ierr = MatDestroy(&B);CHKERRQ(ierr);
4422         goto foundconv;
4423       }
4424     }
4425 
4426     /* 3) See if a good general converter is registered for the desired class */
4427     conv = B->ops->convertfrom;
4428     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4429     ierr = MatDestroy(&B);CHKERRQ(ierr);
4430     if (conv) goto foundconv;
4431 
4432     /* 4) See if a good general converter is known for the current matrix */
4433     if (mat->ops->convert) conv = mat->ops->convert;
4434 
4435     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4436     if (conv) goto foundconv;
4437 
4438     /* 5) Use a really basic converter. */
4439     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4440     conv = MatConvert_Basic;
4441 
4442 foundconv:
4443     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4444     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4445     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4446       /* the block sizes must be same if the mappings are copied over */
4447       (*M)->rmap->bs = mat->rmap->bs;
4448       (*M)->cmap->bs = mat->cmap->bs;
4449       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4450       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4451       (*M)->rmap->mapping = mat->rmap->mapping;
4452       (*M)->cmap->mapping = mat->cmap->mapping;
4453     }
4454     (*M)->stencil.dim = mat->stencil.dim;
4455     (*M)->stencil.noc = mat->stencil.noc;
4456     for (i=0; i<=mat->stencil.dim; i++) {
4457       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4458       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4459     }
4460     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4461   }
4462   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4463 
4464   /* Copy Mat options */
4465   if (issymmetric) {
4466     ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
4467   }
4468   if (ishermitian) {
4469     ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
4470   }
4471   PetscFunctionReturn(0);
4472 }
4473 
4474 /*@C
4475    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4476 
4477    Not Collective
4478 
4479    Input Parameter:
4480 .  mat - the matrix, must be a factored matrix
4481 
4482    Output Parameter:
4483 .   type - the string name of the package (do not free this string)
4484 
4485    Notes:
4486       In Fortran you pass in a empty string and the package name will be copied into it.
4487     (Make sure the string is long enough)
4488 
4489    Level: intermediate
4490 
4491 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4492 @*/
4493 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4494 {
4495   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4496 
4497   PetscFunctionBegin;
4498   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4499   PetscValidType(mat,1);
4500   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4501   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4502   if (!conv) {
4503     *type = MATSOLVERPETSC;
4504   } else {
4505     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4506   }
4507   PetscFunctionReturn(0);
4508 }
4509 
4510 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4511 struct _MatSolverTypeForSpecifcType {
4512   MatType                        mtype;
4513   PetscErrorCode                 (*createfactor[MAT_FACTOR_NUM_TYPES])(Mat,MatFactorType,Mat*);
4514   MatSolverTypeForSpecifcType next;
4515 };
4516 
4517 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4518 struct _MatSolverTypeHolder {
4519   char                        *name;
4520   MatSolverTypeForSpecifcType handlers;
4521   MatSolverTypeHolder         next;
4522 };
4523 
4524 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4525 
4526 /*@C
4527    MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type
4528 
4529    Input Parameters:
4530 +    package - name of the package, for example petsc or superlu
4531 .    mtype - the matrix type that works with this package
4532 .    ftype - the type of factorization supported by the package
4533 -    createfactor - routine that will create the factored matrix ready to be used
4534 
4535     Level: intermediate
4536 
4537 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4538 @*/
4539 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*))
4540 {
4541   PetscErrorCode              ierr;
4542   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4543   PetscBool                   flg;
4544   MatSolverTypeForSpecifcType inext,iprev = NULL;
4545 
4546   PetscFunctionBegin;
4547   ierr = MatInitializePackage();CHKERRQ(ierr);
4548   if (!next) {
4549     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4550     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4551     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4552     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4553     MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor;
4554     PetscFunctionReturn(0);
4555   }
4556   while (next) {
4557     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4558     if (flg) {
4559       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4560       inext = next->handlers;
4561       while (inext) {
4562         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4563         if (flg) {
4564           inext->createfactor[(int)ftype-1] = createfactor;
4565           PetscFunctionReturn(0);
4566         }
4567         iprev = inext;
4568         inext = inext->next;
4569       }
4570       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4571       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4572       iprev->next->createfactor[(int)ftype-1] = createfactor;
4573       PetscFunctionReturn(0);
4574     }
4575     prev = next;
4576     next = next->next;
4577   }
4578   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4579   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4580   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4581   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4582   prev->next->handlers->createfactor[(int)ftype-1] = createfactor;
4583   PetscFunctionReturn(0);
4584 }
4585 
4586 /*@C
4587    MatSolveTypeGet - Gets the function that creates the factor matrix if it exist
4588 
4589    Input Parameters:
4590 +    type - name of the package, for example petsc or superlu
4591 .    ftype - the type of factorization supported by the type
4592 -    mtype - the matrix type that works with this type
4593 
4594    Output Parameters:
4595 +   foundtype - PETSC_TRUE if the type was registered
4596 .   foundmtype - PETSC_TRUE if the type supports the requested mtype
4597 -   createfactor - routine that will create the factored matrix ready to be used or NULL if not found
4598 
4599     Level: intermediate
4600 
4601 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatSolvePackageRegister), MatGetFactor()
4602 @*/
4603 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*))
4604 {
4605   PetscErrorCode              ierr;
4606   MatSolverTypeHolder         next = MatSolverTypeHolders;
4607   PetscBool                   flg;
4608   MatSolverTypeForSpecifcType inext;
4609 
4610   PetscFunctionBegin;
4611   if (foundtype) *foundtype = PETSC_FALSE;
4612   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4613   if (createfactor) *createfactor    = NULL;
4614 
4615   if (type) {
4616     while (next) {
4617       ierr = PetscStrcasecmp(type,next->name,&flg);CHKERRQ(ierr);
4618       if (flg) {
4619         if (foundtype) *foundtype = PETSC_TRUE;
4620         inext = next->handlers;
4621         while (inext) {
4622           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4623           if (flg) {
4624             if (foundmtype) *foundmtype = PETSC_TRUE;
4625             if (createfactor)  *createfactor  = inext->createfactor[(int)ftype-1];
4626             PetscFunctionReturn(0);
4627           }
4628           inext = inext->next;
4629         }
4630       }
4631       next = next->next;
4632     }
4633   } else {
4634     while (next) {
4635       inext = next->handlers;
4636       while (inext) {
4637         ierr = PetscStrcmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4638         if (flg && inext->createfactor[(int)ftype-1]) {
4639           if (foundtype) *foundtype = PETSC_TRUE;
4640           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4641           if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4642           PetscFunctionReturn(0);
4643         }
4644         inext = inext->next;
4645       }
4646       next = next->next;
4647     }
4648     /* try with base classes inext->mtype */
4649     next = MatSolverTypeHolders;
4650     while (next) {
4651       inext = next->handlers;
4652       while (inext) {
4653         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4654         if (flg && inext->createfactor[(int)ftype-1]) {
4655           if (foundtype) *foundtype = PETSC_TRUE;
4656           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4657           if (createfactor) *createfactor = inext->createfactor[(int)ftype-1];
4658           PetscFunctionReturn(0);
4659         }
4660         inext = inext->next;
4661       }
4662       next = next->next;
4663     }
4664   }
4665   PetscFunctionReturn(0);
4666 }
4667 
4668 PetscErrorCode MatSolverTypeDestroy(void)
4669 {
4670   PetscErrorCode              ierr;
4671   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4672   MatSolverTypeForSpecifcType inext,iprev;
4673 
4674   PetscFunctionBegin;
4675   while (next) {
4676     ierr = PetscFree(next->name);CHKERRQ(ierr);
4677     inext = next->handlers;
4678     while (inext) {
4679       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4680       iprev = inext;
4681       inext = inext->next;
4682       ierr = PetscFree(iprev);CHKERRQ(ierr);
4683     }
4684     prev = next;
4685     next = next->next;
4686     ierr = PetscFree(prev);CHKERRQ(ierr);
4687   }
4688   MatSolverTypeHolders = NULL;
4689   PetscFunctionReturn(0);
4690 }
4691 
4692 /*@C
4693    MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4694 
4695    Logically Collective on Mat
4696 
4697    Input Parameters:
4698 .  mat - the matrix
4699 
4700    Output Parameters:
4701 .  flg - PETSC_TRUE if uses the ordering
4702 
4703    Notes:
4704       Most internal PETSc factorizations use the ordering passed to the factorization routine but external
4705       packages do not, thus we want to skip generating the ordering when it is not needed or used.
4706 
4707    Level: developer
4708 
4709 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4710 @*/
4711 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg)
4712 {
4713   PetscFunctionBegin;
4714   *flg = mat->canuseordering;
4715   PetscFunctionReturn(0);
4716 }
4717 
4718 /*@C
4719    MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object
4720 
4721    Logically Collective on Mat
4722 
4723    Input Parameters:
4724 .  mat - the matrix
4725 
4726    Output Parameters:
4727 .  otype - the preferred type
4728 
4729    Level: developer
4730 
4731 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic()
4732 @*/
4733 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype)
4734 {
4735   PetscFunctionBegin;
4736   *otype = mat->preferredordering[ftype];
4737   if (!*otype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering");
4738   PetscFunctionReturn(0);
4739 }
4740 
4741 /*@C
4742    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4743 
4744    Collective on Mat
4745 
4746    Input Parameters:
4747 +  mat - the matrix
4748 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4749 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4750 
4751    Output Parameters:
4752 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4753 
4754    Notes:
4755       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4756      such as pastix, superlu, mumps etc.
4757 
4758       PETSc must have been ./configure to use the external solver, using the option --download-package
4759 
4760    Developer Notes:
4761       This should actually be called MatCreateFactor() since it creates a new factor object
4762 
4763    Level: intermediate
4764 
4765 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatFactorGetCanUseOrdering(), MatSolverTypeRegister()
4766 @*/
4767 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4768 {
4769   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4770   PetscBool      foundtype,foundmtype;
4771 
4772   PetscFunctionBegin;
4773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4774   PetscValidType(mat,1);
4775 
4776   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4777   MatCheckPreallocated(mat,1);
4778 
4779   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv);CHKERRQ(ierr);
4780   if (!foundtype) {
4781     if (type) {
4782       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);
4783     } else {
4784       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);
4785     }
4786   }
4787   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4788   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);
4789 
4790   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4791   PetscFunctionReturn(0);
4792 }
4793 
4794 /*@C
4795    MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type
4796 
4797    Not Collective
4798 
4799    Input Parameters:
4800 +  mat - the matrix
4801 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4802 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4803 
4804    Output Parameter:
4805 .    flg - PETSC_TRUE if the factorization is available
4806 
4807    Notes:
4808       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4809      such as pastix, superlu, mumps etc.
4810 
4811       PETSc must have been ./configure to use the external solver, using the option --download-package
4812 
4813    Developer Notes:
4814       This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object
4815 
4816    Level: intermediate
4817 
4818 .seealso: MatCopy(), MatDuplicate(), MatGetFactor(), MatSolverTypeRegister()
4819 @*/
4820 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4821 {
4822   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4823 
4824   PetscFunctionBegin;
4825   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4826   PetscValidType(mat,1);
4827 
4828   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4829   MatCheckPreallocated(mat,1);
4830 
4831   *flg = PETSC_FALSE;
4832   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4833   if (gconv) {
4834     *flg = PETSC_TRUE;
4835   }
4836   PetscFunctionReturn(0);
4837 }
4838 
4839 #include <petscdmtypes.h>
4840 
4841 /*@
4842    MatDuplicate - Duplicates a matrix including the non-zero structure.
4843 
4844    Collective on Mat
4845 
4846    Input Parameters:
4847 +  mat - the matrix
4848 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4849         See the manual page for MatDuplicateOption for an explanation of these options.
4850 
4851    Output Parameter:
4852 .  M - pointer to place new matrix
4853 
4854    Level: intermediate
4855 
4856    Notes:
4857     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4858     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.
4859 
4860 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4861 @*/
4862 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4863 {
4864   PetscErrorCode ierr;
4865   Mat            B;
4866   PetscInt       i;
4867   DM             dm;
4868   void           (*viewf)(void);
4869 
4870   PetscFunctionBegin;
4871   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4872   PetscValidType(mat,1);
4873   PetscValidPointer(M,3);
4874   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4875   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4876   MatCheckPreallocated(mat,1);
4877 
4878   *M = NULL;
4879   if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name);
4880   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4881   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4882   B    = *M;
4883 
4884   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4885   if (viewf) {
4886     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4887   }
4888 
4889   B->stencil.dim = mat->stencil.dim;
4890   B->stencil.noc = mat->stencil.noc;
4891   for (i=0; i<=mat->stencil.dim; i++) {
4892     B->stencil.dims[i]   = mat->stencil.dims[i];
4893     B->stencil.starts[i] = mat->stencil.starts[i];
4894   }
4895 
4896   B->nooffproczerorows = mat->nooffproczerorows;
4897   B->nooffprocentries  = mat->nooffprocentries;
4898 
4899   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4900   if (dm) {
4901     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4902   }
4903   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4904   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4905   PetscFunctionReturn(0);
4906 }
4907 
4908 /*@
4909    MatGetDiagonal - Gets the diagonal of a matrix.
4910 
4911    Logically Collective on Mat
4912 
4913    Input Parameters:
4914 +  mat - the matrix
4915 -  v - the vector for storing the diagonal
4916 
4917    Output Parameter:
4918 .  v - the diagonal of the matrix
4919 
4920    Level: intermediate
4921 
4922    Note:
4923    Currently only correct in parallel for square matrices.
4924 
4925 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4926 @*/
4927 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4928 {
4929   PetscErrorCode ierr;
4930 
4931   PetscFunctionBegin;
4932   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4933   PetscValidType(mat,1);
4934   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4935   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4936   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4937   MatCheckPreallocated(mat,1);
4938 
4939   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4940   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4941   PetscFunctionReturn(0);
4942 }
4943 
4944 /*@C
4945    MatGetRowMin - Gets the minimum value (of the real part) of each
4946         row of the matrix
4947 
4948    Logically Collective on Mat
4949 
4950    Input Parameters:
4951 .  mat - the matrix
4952 
4953    Output Parameter:
4954 +  v - the vector for storing the maximums
4955 -  idx - the indices of the column found for each row (optional)
4956 
4957    Level: intermediate
4958 
4959    Notes:
4960     The result of this call are the same as if one converted the matrix to dense format
4961       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4962 
4963     This code is only implemented for a couple of matrix formats.
4964 
4965 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4966           MatGetRowMax()
4967 @*/
4968 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4969 {
4970   PetscErrorCode ierr;
4971 
4972   PetscFunctionBegin;
4973   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4974   PetscValidType(mat,1);
4975   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4976   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4977 
4978   if (!mat->cmap->N) {
4979     ierr = VecSet(v,PETSC_MAX_REAL);CHKERRQ(ierr);
4980     if (idx) {
4981       PetscInt i,m = mat->rmap->n;
4982       for (i=0; i<m; i++) idx[i] = -1;
4983     }
4984   } else {
4985     if (!mat->ops->getrowmin) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4986     MatCheckPreallocated(mat,1);
4987   }
4988   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4989   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4990   PetscFunctionReturn(0);
4991 }
4992 
4993 /*@C
4994    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4995         row of the matrix
4996 
4997    Logically Collective on Mat
4998 
4999    Input Parameters:
5000 .  mat - the matrix
5001 
5002    Output Parameter:
5003 +  v - the vector for storing the minimums
5004 -  idx - the indices of the column found for each row (or NULL if not needed)
5005 
5006    Level: intermediate
5007 
5008    Notes:
5009     if a row is completely empty or has only 0.0 values then the idx[] value for that
5010     row is 0 (the first column).
5011 
5012     This code is only implemented for a couple of matrix formats.
5013 
5014 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
5015 @*/
5016 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
5017 {
5018   PetscErrorCode ierr;
5019 
5020   PetscFunctionBegin;
5021   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5022   PetscValidType(mat,1);
5023   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5024   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5025   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5026 
5027   if (!mat->cmap->N) {
5028     ierr = VecSet(v,0.0);CHKERRQ(ierr);
5029     if (idx) {
5030       PetscInt i,m = mat->rmap->n;
5031       for (i=0; i<m; i++) idx[i] = -1;
5032     }
5033   } else {
5034     if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5035     MatCheckPreallocated(mat,1);
5036     if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
5037     ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
5038   }
5039   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5040   PetscFunctionReturn(0);
5041 }
5042 
5043 /*@C
5044    MatGetRowMax - Gets the maximum value (of the real part) of each
5045         row of the matrix
5046 
5047    Logically Collective on Mat
5048 
5049    Input Parameters:
5050 .  mat - the matrix
5051 
5052    Output Parameter:
5053 +  v - the vector for storing the maximums
5054 -  idx - the indices of the column found for each row (optional)
5055 
5056    Level: intermediate
5057 
5058    Notes:
5059     The result of this call are the same as if one converted the matrix to dense format
5060       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
5061 
5062     This code is only implemented for a couple of matrix formats.
5063 
5064 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
5065 @*/
5066 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
5067 {
5068   PetscErrorCode ierr;
5069 
5070   PetscFunctionBegin;
5071   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5072   PetscValidType(mat,1);
5073   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5074   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5075 
5076   if (!mat->cmap->N) {
5077     ierr = VecSet(v,PETSC_MIN_REAL);CHKERRQ(ierr);
5078     if (idx) {
5079       PetscInt i,m = mat->rmap->n;
5080       for (i=0; i<m; i++) idx[i] = -1;
5081     }
5082   } else {
5083     if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5084     MatCheckPreallocated(mat,1);
5085     ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
5086   }
5087   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5088   PetscFunctionReturn(0);
5089 }
5090 
5091 /*@C
5092    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
5093         row of the matrix
5094 
5095    Logically Collective on Mat
5096 
5097    Input Parameters:
5098 .  mat - the matrix
5099 
5100    Output Parameter:
5101 +  v - the vector for storing the maximums
5102 -  idx - the indices of the column found for each row (or NULL if not needed)
5103 
5104    Level: intermediate
5105 
5106    Notes:
5107     if a row is completely empty or has only 0.0 values then the idx[] value for that
5108     row is 0 (the first column).
5109 
5110     This code is only implemented for a couple of matrix formats.
5111 
5112 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
5113 @*/
5114 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
5115 {
5116   PetscErrorCode ierr;
5117 
5118   PetscFunctionBegin;
5119   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5120   PetscValidType(mat,1);
5121   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5122   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5123 
5124   if (!mat->cmap->N) {
5125     ierr = VecSet(v,0.0);CHKERRQ(ierr);
5126     if (idx) {
5127       PetscInt i,m = mat->rmap->n;
5128       for (i=0; i<m; i++) idx[i] = -1;
5129     }
5130   } else {
5131     if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5132     MatCheckPreallocated(mat,1);
5133     if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);}
5134     ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
5135   }
5136   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
5137   PetscFunctionReturn(0);
5138 }
5139 
5140 /*@
5141    MatGetRowSum - Gets the sum of each row of the matrix
5142 
5143    Logically or Neighborhood Collective on Mat
5144 
5145    Input Parameters:
5146 .  mat - the matrix
5147 
5148    Output Parameter:
5149 .  v - the vector for storing the sum of rows
5150 
5151    Level: intermediate
5152 
5153    Notes:
5154     This code is slow since it is not currently specialized for different formats
5155 
5156 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
5157 @*/
5158 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
5159 {
5160   Vec            ones;
5161   PetscErrorCode ierr;
5162 
5163   PetscFunctionBegin;
5164   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5165   PetscValidType(mat,1);
5166   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
5167   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5168   MatCheckPreallocated(mat,1);
5169   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
5170   ierr = VecSet(ones,1.);CHKERRQ(ierr);
5171   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
5172   ierr = VecDestroy(&ones);CHKERRQ(ierr);
5173   PetscFunctionReturn(0);
5174 }
5175 
5176 /*@
5177    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
5178 
5179    Collective on Mat
5180 
5181    Input Parameters:
5182 +  mat - the matrix to transpose
5183 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5184 
5185    Output Parameter:
5186 .  B - the transpose
5187 
5188    Notes:
5189      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
5190 
5191      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
5192 
5193      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
5194 
5195    Level: intermediate
5196 
5197 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5198 @*/
5199 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
5200 {
5201   PetscErrorCode ierr;
5202 
5203   PetscFunctionBegin;
5204   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5205   PetscValidType(mat,1);
5206   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5207   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5208   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5209   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
5210   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
5211   MatCheckPreallocated(mat,1);
5212 
5213   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
5214   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
5215   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
5216   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
5217   PetscFunctionReturn(0);
5218 }
5219 
5220 /*@
5221    MatIsTranspose - Test whether a matrix is another one's transpose,
5222         or its own, in which case it tests symmetry.
5223 
5224    Collective on Mat
5225 
5226    Input Parameter:
5227 +  A - the matrix to test
5228 -  B - the matrix to test against, this can equal the first parameter
5229 
5230    Output Parameters:
5231 .  flg - the result
5232 
5233    Notes:
5234    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5235    has a running time of the order of the number of nonzeros; the parallel
5236    test involves parallel copies of the block-offdiagonal parts of the matrix.
5237 
5238    Level: intermediate
5239 
5240 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
5241 @*/
5242 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5243 {
5244   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5245 
5246   PetscFunctionBegin;
5247   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5248   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5249   PetscValidBoolPointer(flg,3);
5250   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
5251   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
5252   *flg = PETSC_FALSE;
5253   if (f && g) {
5254     if (f == g) {
5255       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5256     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5257   } else {
5258     MatType mattype;
5259     if (!f) {
5260       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5261     } else {
5262       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5263     }
5264     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype);
5265   }
5266   PetscFunctionReturn(0);
5267 }
5268 
5269 /*@
5270    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5271 
5272    Collective on Mat
5273 
5274    Input Parameters:
5275 +  mat - the matrix to transpose and complex conjugate
5276 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
5277 
5278    Output Parameter:
5279 .  B - the Hermitian
5280 
5281    Level: intermediate
5282 
5283 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5284 @*/
5285 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5286 {
5287   PetscErrorCode ierr;
5288 
5289   PetscFunctionBegin;
5290   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5291 #if defined(PETSC_USE_COMPLEX)
5292   ierr = MatConjugate(*B);CHKERRQ(ierr);
5293 #endif
5294   PetscFunctionReturn(0);
5295 }
5296 
5297 /*@
5298    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5299 
5300    Collective on Mat
5301 
5302    Input Parameter:
5303 +  A - the matrix to test
5304 -  B - the matrix to test against, this can equal the first parameter
5305 
5306    Output Parameters:
5307 .  flg - the result
5308 
5309    Notes:
5310    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5311    has a running time of the order of the number of nonzeros; the parallel
5312    test involves parallel copies of the block-offdiagonal parts of the matrix.
5313 
5314    Level: intermediate
5315 
5316 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5317 @*/
5318 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5319 {
5320   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5321 
5322   PetscFunctionBegin;
5323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5324   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5325   PetscValidBoolPointer(flg,3);
5326   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5327   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5328   if (f && g) {
5329     if (f==g) {
5330       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5331     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5332   }
5333   PetscFunctionReturn(0);
5334 }
5335 
5336 /*@
5337    MatPermute - Creates a new matrix with rows and columns permuted from the
5338    original.
5339 
5340    Collective on Mat
5341 
5342    Input Parameters:
5343 +  mat - the matrix to permute
5344 .  row - row permutation, each processor supplies only the permutation for its rows
5345 -  col - column permutation, each processor supplies only the permutation for its columns
5346 
5347    Output Parameters:
5348 .  B - the permuted matrix
5349 
5350    Level: advanced
5351 
5352    Note:
5353    The index sets map from row/col of permuted matrix to row/col of original matrix.
5354    The index sets should be on the same communicator as Mat and have the same local sizes.
5355 
5356    Developer Note:
5357      If you want to implement MatPermute for a matrix type, and your approach doesn't
5358      exploit the fact that row and col are permutations, consider implementing the
5359      more general MatCreateSubMatrix() instead.
5360 
5361 .seealso: MatGetOrdering(), ISAllGather()
5362 
5363 @*/
5364 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5365 {
5366   PetscErrorCode ierr;
5367 
5368   PetscFunctionBegin;
5369   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5370   PetscValidType(mat,1);
5371   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5372   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5373   PetscValidPointer(B,4);
5374   PetscCheckSameComm(mat,1,row,2);
5375   if (row != col) PetscCheckSameComm(row,2,col,3);
5376   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5377   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5378   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);
5379   MatCheckPreallocated(mat,1);
5380 
5381   if (mat->ops->permute) {
5382     ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5383     ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5384   } else {
5385     ierr = MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B);CHKERRQ(ierr);
5386   }
5387   PetscFunctionReturn(0);
5388 }
5389 
5390 /*@
5391    MatEqual - Compares two matrices.
5392 
5393    Collective on Mat
5394 
5395    Input Parameters:
5396 +  A - the first matrix
5397 -  B - the second matrix
5398 
5399    Output Parameter:
5400 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5401 
5402    Level: intermediate
5403 
5404 @*/
5405 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5406 {
5407   PetscErrorCode ierr;
5408 
5409   PetscFunctionBegin;
5410   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5411   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5412   PetscValidType(A,1);
5413   PetscValidType(B,2);
5414   PetscValidBoolPointer(flg,3);
5415   PetscCheckSameComm(A,1,B,2);
5416   MatCheckPreallocated(B,2);
5417   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5418   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5419   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);
5420   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5421   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5422   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);
5423   MatCheckPreallocated(A,1);
5424 
5425   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5426   PetscFunctionReturn(0);
5427 }
5428 
5429 /*@
5430    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5431    matrices that are stored as vectors.  Either of the two scaling
5432    matrices can be NULL.
5433 
5434    Collective on Mat
5435 
5436    Input Parameters:
5437 +  mat - the matrix to be scaled
5438 .  l - the left scaling vector (or NULL)
5439 -  r - the right scaling vector (or NULL)
5440 
5441    Notes:
5442    MatDiagonalScale() computes A = LAR, where
5443    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5444    The L scales the rows of the matrix, the R scales the columns of the matrix.
5445 
5446    Level: intermediate
5447 
5448 
5449 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5450 @*/
5451 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5452 {
5453   PetscErrorCode ierr;
5454 
5455   PetscFunctionBegin;
5456   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5457   PetscValidType(mat,1);
5458   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5459   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5460   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5461   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5462   MatCheckPreallocated(mat,1);
5463   if (!l && !r) PetscFunctionReturn(0);
5464 
5465   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5466   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5467   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5468   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5469   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5470   PetscFunctionReturn(0);
5471 }
5472 
5473 /*@
5474     MatScale - Scales all elements of a matrix by a given number.
5475 
5476     Logically Collective on Mat
5477 
5478     Input Parameters:
5479 +   mat - the matrix to be scaled
5480 -   a  - the scaling value
5481 
5482     Output Parameter:
5483 .   mat - the scaled matrix
5484 
5485     Level: intermediate
5486 
5487 .seealso: MatDiagonalScale()
5488 @*/
5489 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5490 {
5491   PetscErrorCode ierr;
5492 
5493   PetscFunctionBegin;
5494   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5495   PetscValidType(mat,1);
5496   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5497   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5498   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5499   PetscValidLogicalCollectiveScalar(mat,a,2);
5500   MatCheckPreallocated(mat,1);
5501 
5502   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5503   if (a != (PetscScalar)1.0) {
5504     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5505     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5506   }
5507   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5508   PetscFunctionReturn(0);
5509 }
5510 
5511 /*@
5512    MatNorm - Calculates various norms of a matrix.
5513 
5514    Collective on Mat
5515 
5516    Input Parameters:
5517 +  mat - the matrix
5518 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5519 
5520    Output Parameters:
5521 .  nrm - the resulting norm
5522 
5523    Level: intermediate
5524 
5525 @*/
5526 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5527 {
5528   PetscErrorCode ierr;
5529 
5530   PetscFunctionBegin;
5531   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5532   PetscValidType(mat,1);
5533   PetscValidScalarPointer(nrm,3);
5534 
5535   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5536   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5537   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5538   MatCheckPreallocated(mat,1);
5539 
5540   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5541   PetscFunctionReturn(0);
5542 }
5543 
5544 /*
5545      This variable is used to prevent counting of MatAssemblyBegin() that
5546    are called from within a MatAssemblyEnd().
5547 */
5548 static PetscInt MatAssemblyEnd_InUse = 0;
5549 /*@
5550    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5551    be called after completing all calls to MatSetValues().
5552 
5553    Collective on Mat
5554 
5555    Input Parameters:
5556 +  mat - the matrix
5557 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5558 
5559    Notes:
5560    MatSetValues() generally caches the values.  The matrix is ready to
5561    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5562    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5563    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5564    using the matrix.
5565 
5566    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5567    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
5568    a global collective operation requring all processes that share the matrix.
5569 
5570    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5571    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5572    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5573 
5574    Level: beginner
5575 
5576 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5577 @*/
5578 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5579 {
5580   PetscErrorCode ierr;
5581 
5582   PetscFunctionBegin;
5583   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5584   PetscValidType(mat,1);
5585   MatCheckPreallocated(mat,1);
5586   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5587   if (mat->assembled) {
5588     mat->was_assembled = PETSC_TRUE;
5589     mat->assembled     = PETSC_FALSE;
5590   }
5591 
5592   if (!MatAssemblyEnd_InUse) {
5593     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5594     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5595     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5596   } else if (mat->ops->assemblybegin) {
5597     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5598   }
5599   PetscFunctionReturn(0);
5600 }
5601 
5602 /*@
5603    MatAssembled - Indicates if a matrix has been assembled and is ready for
5604      use; for example, in matrix-vector product.
5605 
5606    Not Collective
5607 
5608    Input Parameter:
5609 .  mat - the matrix
5610 
5611    Output Parameter:
5612 .  assembled - PETSC_TRUE or PETSC_FALSE
5613 
5614    Level: advanced
5615 
5616 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5617 @*/
5618 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5619 {
5620   PetscFunctionBegin;
5621   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5622   PetscValidPointer(assembled,2);
5623   *assembled = mat->assembled;
5624   PetscFunctionReturn(0);
5625 }
5626 
5627 /*@
5628    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5629    be called after MatAssemblyBegin().
5630 
5631    Collective on Mat
5632 
5633    Input Parameters:
5634 +  mat - the matrix
5635 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5636 
5637    Options Database Keys:
5638 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5639 .  -mat_view ::ascii_info_detail - Prints more detailed info
5640 .  -mat_view - Prints matrix in ASCII format
5641 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5642 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5643 .  -display <name> - Sets display name (default is host)
5644 .  -draw_pause <sec> - Sets number of seconds to pause after display
5645 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab)
5646 .  -viewer_socket_machine <machine> - Machine to use for socket
5647 .  -viewer_socket_port <port> - Port number to use for socket
5648 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5649 
5650    Notes:
5651    MatSetValues() generally caches the values.  The matrix is ready to
5652    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5653    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5654    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5655    using the matrix.
5656 
5657    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5658    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5659    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5660 
5661    Level: beginner
5662 
5663 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5664 @*/
5665 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5666 {
5667   PetscErrorCode  ierr;
5668   static PetscInt inassm = 0;
5669   PetscBool       flg    = PETSC_FALSE;
5670 
5671   PetscFunctionBegin;
5672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5673   PetscValidType(mat,1);
5674 
5675   inassm++;
5676   MatAssemblyEnd_InUse++;
5677   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5678     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5679     if (mat->ops->assemblyend) {
5680       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5681     }
5682     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5683   } else if (mat->ops->assemblyend) {
5684     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5685   }
5686 
5687   /* Flush assembly is not a true assembly */
5688   if (type != MAT_FLUSH_ASSEMBLY) {
5689     mat->num_ass++;
5690     mat->assembled        = PETSC_TRUE;
5691     mat->ass_nonzerostate = mat->nonzerostate;
5692   }
5693 
5694   mat->insertmode = NOT_SET_VALUES;
5695   MatAssemblyEnd_InUse--;
5696   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5697   if (!mat->symmetric_eternal) {
5698     mat->symmetric_set              = PETSC_FALSE;
5699     mat->hermitian_set              = PETSC_FALSE;
5700     mat->structurally_symmetric_set = PETSC_FALSE;
5701   }
5702   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5703     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5704 
5705     if (mat->checksymmetryonassembly) {
5706       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5707       if (flg) {
5708         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5709       } else {
5710         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5711       }
5712     }
5713     if (mat->nullsp && mat->checknullspaceonassembly) {
5714       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5715     }
5716   }
5717   inassm--;
5718   PetscFunctionReturn(0);
5719 }
5720 
5721 /*@
5722    MatSetOption - Sets a parameter option for a matrix. Some options
5723    may be specific to certain storage formats.  Some options
5724    determine how values will be inserted (or added). Sorted,
5725    row-oriented input will generally assemble the fastest. The default
5726    is row-oriented.
5727 
5728    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5729 
5730    Input Parameters:
5731 +  mat - the matrix
5732 .  option - the option, one of those listed below (and possibly others),
5733 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5734 
5735   Options Describing Matrix Structure:
5736 +    MAT_SPD - symmetric positive definite
5737 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5738 .    MAT_HERMITIAN - transpose is the complex conjugation
5739 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5740 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5741                             you set to be kept with all future use of the matrix
5742                             including after MatAssemblyBegin/End() which could
5743                             potentially change the symmetry structure, i.e. you
5744                             KNOW the matrix will ALWAYS have the property you set.
5745                             Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian;
5746                             the relevant flags must be set independently.
5747 
5748 
5749    Options For Use with MatSetValues():
5750    Insert a logically dense subblock, which can be
5751 .    MAT_ROW_ORIENTED - row-oriented (default)
5752 
5753    Note these options reflect the data you pass in with MatSetValues(); it has
5754    nothing to do with how the data is stored internally in the matrix
5755    data structure.
5756 
5757    When (re)assembling a matrix, we can restrict the input for
5758    efficiency/debugging purposes.  These options include:
5759 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5760 .    MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated
5761 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5762 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5763 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5764 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5765         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5766         performance for very large process counts.
5767 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5768         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5769         functions, instead sending only neighbor messages.
5770 
5771    Notes:
5772    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5773 
5774    Some options are relevant only for particular matrix types and
5775    are thus ignored by others.  Other options are not supported by
5776    certain matrix types and will generate an error message if set.
5777 
5778    If using a Fortran 77 module to compute a matrix, one may need to
5779    use the column-oriented option (or convert to the row-oriented
5780    format).
5781 
5782    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5783    that would generate a new entry in the nonzero structure is instead
5784    ignored.  Thus, if memory has not alredy been allocated for this particular
5785    data, then the insertion is ignored. For dense matrices, in which
5786    the entire array is allocated, no entries are ever ignored.
5787    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5788 
5789    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5790    that would generate a new entry in the nonzero structure instead produces
5791    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
5792 
5793    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5794    that would generate a new entry that has not been preallocated will
5795    instead produce an error. (Currently supported for AIJ and BAIJ formats
5796    only.) This is a useful flag when debugging matrix memory preallocation.
5797    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5798 
5799    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5800    other processors should be dropped, rather than stashed.
5801    This is useful if you know that the "owning" processor is also
5802    always generating the correct matrix entries, so that PETSc need
5803    not transfer duplicate entries generated on another processor.
5804 
5805    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5806    searches during matrix assembly. When this flag is set, the hash table
5807    is created during the first Matrix Assembly. This hash table is
5808    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5809    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5810    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5811    supported by MATMPIBAIJ format only.
5812 
5813    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5814    are kept in the nonzero structure
5815 
5816    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5817    a zero location in the matrix
5818 
5819    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5820 
5821    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5822         zero row routines and thus improves performance for very large process counts.
5823 
5824    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5825         part of the matrix (since they should match the upper triangular part).
5826 
5827    MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a
5828                      single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common
5829                      with finite difference schemes with non-periodic boundary conditions.
5830 
5831    Level: intermediate
5832 
5833 .seealso:  MatOption, Mat
5834 
5835 @*/
5836 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5837 {
5838   PetscErrorCode ierr;
5839 
5840   PetscFunctionBegin;
5841   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5842   if (op > 0) {
5843     PetscValidLogicalCollectiveEnum(mat,op,2);
5844     PetscValidLogicalCollectiveBool(mat,flg,3);
5845   }
5846 
5847   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);
5848 
5849   switch (op) {
5850   case MAT_FORCE_DIAGONAL_ENTRIES:
5851     mat->force_diagonals = flg;
5852     PetscFunctionReturn(0);
5853   case MAT_NO_OFF_PROC_ENTRIES:
5854     mat->nooffprocentries = flg;
5855     PetscFunctionReturn(0);
5856   case MAT_SUBSET_OFF_PROC_ENTRIES:
5857     mat->assembly_subset = flg;
5858     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5859 #if !defined(PETSC_HAVE_MPIUNI)
5860       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5861 #endif
5862       mat->stash.first_assembly_done = PETSC_FALSE;
5863     }
5864     PetscFunctionReturn(0);
5865   case MAT_NO_OFF_PROC_ZERO_ROWS:
5866     mat->nooffproczerorows = flg;
5867     PetscFunctionReturn(0);
5868   case MAT_SPD:
5869     mat->spd_set = PETSC_TRUE;
5870     mat->spd     = flg;
5871     if (flg) {
5872       mat->symmetric                  = PETSC_TRUE;
5873       mat->structurally_symmetric     = PETSC_TRUE;
5874       mat->symmetric_set              = PETSC_TRUE;
5875       mat->structurally_symmetric_set = PETSC_TRUE;
5876     }
5877     break;
5878   case MAT_SYMMETRIC:
5879     mat->symmetric = flg;
5880     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5881     mat->symmetric_set              = PETSC_TRUE;
5882     mat->structurally_symmetric_set = flg;
5883 #if !defined(PETSC_USE_COMPLEX)
5884     mat->hermitian     = flg;
5885     mat->hermitian_set = PETSC_TRUE;
5886 #endif
5887     break;
5888   case MAT_HERMITIAN:
5889     mat->hermitian = flg;
5890     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5891     mat->hermitian_set              = PETSC_TRUE;
5892     mat->structurally_symmetric_set = flg;
5893 #if !defined(PETSC_USE_COMPLEX)
5894     mat->symmetric     = flg;
5895     mat->symmetric_set = PETSC_TRUE;
5896 #endif
5897     break;
5898   case MAT_STRUCTURALLY_SYMMETRIC:
5899     mat->structurally_symmetric     = flg;
5900     mat->structurally_symmetric_set = PETSC_TRUE;
5901     break;
5902   case MAT_SYMMETRY_ETERNAL:
5903     mat->symmetric_eternal = flg;
5904     break;
5905   case MAT_STRUCTURE_ONLY:
5906     mat->structure_only = flg;
5907     break;
5908   case MAT_SORTED_FULL:
5909     mat->sortedfull = flg;
5910     break;
5911   default:
5912     break;
5913   }
5914   if (mat->ops->setoption) {
5915     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5916   }
5917   PetscFunctionReturn(0);
5918 }
5919 
5920 /*@
5921    MatGetOption - Gets a parameter option that has been set for a matrix.
5922 
5923    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5924 
5925    Input Parameters:
5926 +  mat - the matrix
5927 -  option - the option, this only responds to certain options, check the code for which ones
5928 
5929    Output Parameter:
5930 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5931 
5932     Notes:
5933     Can only be called after MatSetSizes() and MatSetType() have been set.
5934 
5935    Level: intermediate
5936 
5937 .seealso:  MatOption, MatSetOption()
5938 
5939 @*/
5940 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5941 {
5942   PetscFunctionBegin;
5943   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5944   PetscValidType(mat,1);
5945 
5946   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);
5947   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()");
5948 
5949   switch (op) {
5950   case MAT_NO_OFF_PROC_ENTRIES:
5951     *flg = mat->nooffprocentries;
5952     break;
5953   case MAT_NO_OFF_PROC_ZERO_ROWS:
5954     *flg = mat->nooffproczerorows;
5955     break;
5956   case MAT_SYMMETRIC:
5957     *flg = mat->symmetric;
5958     break;
5959   case MAT_HERMITIAN:
5960     *flg = mat->hermitian;
5961     break;
5962   case MAT_STRUCTURALLY_SYMMETRIC:
5963     *flg = mat->structurally_symmetric;
5964     break;
5965   case MAT_SYMMETRY_ETERNAL:
5966     *flg = mat->symmetric_eternal;
5967     break;
5968   case MAT_SPD:
5969     *flg = mat->spd;
5970     break;
5971   default:
5972     break;
5973   }
5974   PetscFunctionReturn(0);
5975 }
5976 
5977 /*@
5978    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5979    this routine retains the old nonzero structure.
5980 
5981    Logically Collective on Mat
5982 
5983    Input Parameters:
5984 .  mat - the matrix
5985 
5986    Level: intermediate
5987 
5988    Notes:
5989     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.
5990    See the Performance chapter of the users manual for information on preallocating matrices.
5991 
5992 .seealso: MatZeroRows()
5993 @*/
5994 PetscErrorCode MatZeroEntries(Mat mat)
5995 {
5996   PetscErrorCode ierr;
5997 
5998   PetscFunctionBegin;
5999   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6000   PetscValidType(mat,1);
6001   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6002   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");
6003   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6004   MatCheckPreallocated(mat,1);
6005 
6006   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
6007   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
6008   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
6009   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6010   PetscFunctionReturn(0);
6011 }
6012 
6013 /*@
6014    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
6015    of a set of rows and columns of a matrix.
6016 
6017    Collective on Mat
6018 
6019    Input Parameters:
6020 +  mat - the matrix
6021 .  numRows - the number of rows to remove
6022 .  rows - the global row indices
6023 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6024 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6025 -  b - optional vector of right hand side, that will be adjusted by provided solution
6026 
6027    Notes:
6028    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
6029 
6030    The user can set a value in the diagonal entry (or for the AIJ and
6031    row formats can optionally remove the main diagonal entry from the
6032    nonzero structure as well, by passing 0.0 as the final argument).
6033 
6034    For the parallel case, all processes that share the matrix (i.e.,
6035    those in the communicator used for matrix creation) MUST call this
6036    routine, regardless of whether any rows being zeroed are owned by
6037    them.
6038 
6039    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6040    list only rows local to itself).
6041 
6042    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
6043 
6044    Level: intermediate
6045 
6046 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6047           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6048 @*/
6049 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6050 {
6051   PetscErrorCode ierr;
6052 
6053   PetscFunctionBegin;
6054   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6055   PetscValidType(mat,1);
6056   if (numRows) PetscValidIntPointer(rows,3);
6057   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6058   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6059   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6060   MatCheckPreallocated(mat,1);
6061 
6062   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6063   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
6064   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6065   PetscFunctionReturn(0);
6066 }
6067 
6068 /*@
6069    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
6070    of a set of rows and columns of a matrix.
6071 
6072    Collective on Mat
6073 
6074    Input Parameters:
6075 +  mat - the matrix
6076 .  is - the rows to zero
6077 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6078 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6079 -  b - optional vector of right hand side, that will be adjusted by provided solution
6080 
6081    Notes:
6082    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
6083 
6084    The user can set a value in the diagonal entry (or for the AIJ and
6085    row formats can optionally remove the main diagonal entry from the
6086    nonzero structure as well, by passing 0.0 as the final argument).
6087 
6088    For the parallel case, all processes that share the matrix (i.e.,
6089    those in the communicator used for matrix creation) MUST call this
6090    routine, regardless of whether any rows being zeroed are owned by
6091    them.
6092 
6093    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6094    list only rows local to itself).
6095 
6096    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
6097 
6098    Level: intermediate
6099 
6100 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6101           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
6102 @*/
6103 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6104 {
6105   PetscErrorCode ierr;
6106   PetscInt       numRows;
6107   const PetscInt *rows;
6108 
6109   PetscFunctionBegin;
6110   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6111   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6112   PetscValidType(mat,1);
6113   PetscValidType(is,2);
6114   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6115   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6116   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6117   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6118   PetscFunctionReturn(0);
6119 }
6120 
6121 /*@
6122    MatZeroRows - Zeros all entries (except possibly the main diagonal)
6123    of a set of rows of a matrix.
6124 
6125    Collective on Mat
6126 
6127    Input Parameters:
6128 +  mat - the matrix
6129 .  numRows - the number of rows to remove
6130 .  rows - the global row indices
6131 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6132 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6133 -  b - optional vector of right hand side, that will be adjusted by provided solution
6134 
6135    Notes:
6136    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6137    but does not release memory.  For the dense and block diagonal
6138    formats this does not alter the nonzero structure.
6139 
6140    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6141    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6142    merely zeroed.
6143 
6144    The user can set a value in the diagonal entry (or for the AIJ and
6145    row formats can optionally remove the main diagonal entry from the
6146    nonzero structure as well, by passing 0.0 as the final argument).
6147 
6148    For the parallel case, all processes that share the matrix (i.e.,
6149    those in the communicator used for matrix creation) MUST call this
6150    routine, regardless of whether any rows being zeroed are owned by
6151    them.
6152 
6153    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6154    list only rows local to itself).
6155 
6156    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6157    owns that are to be zeroed. This saves a global synchronization in the implementation.
6158 
6159    Level: intermediate
6160 
6161 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6162           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6163 @*/
6164 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6165 {
6166   PetscErrorCode ierr;
6167 
6168   PetscFunctionBegin;
6169   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6170   PetscValidType(mat,1);
6171   if (numRows) PetscValidIntPointer(rows,3);
6172   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6173   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6174   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6175   MatCheckPreallocated(mat,1);
6176 
6177   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6178   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
6179   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6180   PetscFunctionReturn(0);
6181 }
6182 
6183 /*@
6184    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
6185    of a set of rows of a matrix.
6186 
6187    Collective on Mat
6188 
6189    Input Parameters:
6190 +  mat - the matrix
6191 .  is - index set of rows to remove
6192 .  diag - value put in all diagonals of eliminated rows
6193 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6194 -  b - optional vector of right hand side, that will be adjusted by provided solution
6195 
6196    Notes:
6197    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6198    but does not release memory.  For the dense and block diagonal
6199    formats this does not alter the nonzero structure.
6200 
6201    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6202    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6203    merely zeroed.
6204 
6205    The user can set a value in the diagonal entry (or for the AIJ and
6206    row formats can optionally remove the main diagonal entry from the
6207    nonzero structure as well, by passing 0.0 as the final argument).
6208 
6209    For the parallel case, all processes that share the matrix (i.e.,
6210    those in the communicator used for matrix creation) MUST call this
6211    routine, regardless of whether any rows being zeroed are owned by
6212    them.
6213 
6214    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6215    list only rows local to itself).
6216 
6217    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6218    owns that are to be zeroed. This saves a global synchronization in the implementation.
6219 
6220    Level: intermediate
6221 
6222 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6223           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6224 @*/
6225 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6226 {
6227   PetscInt       numRows;
6228   const PetscInt *rows;
6229   PetscErrorCode ierr;
6230 
6231   PetscFunctionBegin;
6232   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6233   PetscValidType(mat,1);
6234   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6235   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6236   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6237   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6238   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6239   PetscFunctionReturn(0);
6240 }
6241 
6242 /*@
6243    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6244    of a set of rows of a matrix. These rows must be local to the process.
6245 
6246    Collective on Mat
6247 
6248    Input Parameters:
6249 +  mat - the matrix
6250 .  numRows - the number of rows to remove
6251 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6252 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6253 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6254 -  b - optional vector of right hand side, that will be adjusted by provided solution
6255 
6256    Notes:
6257    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6258    but does not release memory.  For the dense and block diagonal
6259    formats this does not alter the nonzero structure.
6260 
6261    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6262    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6263    merely zeroed.
6264 
6265    The user can set a value in the diagonal entry (or for the AIJ and
6266    row formats can optionally remove the main diagonal entry from the
6267    nonzero structure as well, by passing 0.0 as the final argument).
6268 
6269    For the parallel case, all processes that share the matrix (i.e.,
6270    those in the communicator used for matrix creation) MUST call this
6271    routine, regardless of whether any rows being zeroed are owned by
6272    them.
6273 
6274    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6275    list only rows local to itself).
6276 
6277    The grid coordinates are across the entire grid, not just the local portion
6278 
6279    In Fortran idxm and idxn should be declared as
6280 $     MatStencil idxm(4,m)
6281    and the values inserted using
6282 $    idxm(MatStencil_i,1) = i
6283 $    idxm(MatStencil_j,1) = j
6284 $    idxm(MatStencil_k,1) = k
6285 $    idxm(MatStencil_c,1) = c
6286    etc
6287 
6288    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6289    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6290    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6291    DM_BOUNDARY_PERIODIC boundary type.
6292 
6293    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
6294    a single value per point) you can skip filling those indices.
6295 
6296    Level: intermediate
6297 
6298 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6299           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6300 @*/
6301 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6302 {
6303   PetscInt       dim     = mat->stencil.dim;
6304   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6305   PetscInt       *dims   = mat->stencil.dims+1;
6306   PetscInt       *starts = mat->stencil.starts;
6307   PetscInt       *dxm    = (PetscInt*) rows;
6308   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6309   PetscErrorCode ierr;
6310 
6311   PetscFunctionBegin;
6312   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6313   PetscValidType(mat,1);
6314   if (numRows) PetscValidIntPointer(rows,3);
6315 
6316   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6317   for (i = 0; i < numRows; ++i) {
6318     /* Skip unused dimensions (they are ordered k, j, i, c) */
6319     for (j = 0; j < 3-sdim; ++j) dxm++;
6320     /* Local index in X dir */
6321     tmp = *dxm++ - starts[0];
6322     /* Loop over remaining dimensions */
6323     for (j = 0; j < dim-1; ++j) {
6324       /* If nonlocal, set index to be negative */
6325       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6326       /* Update local index */
6327       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6328     }
6329     /* Skip component slot if necessary */
6330     if (mat->stencil.noc) dxm++;
6331     /* Local row number */
6332     if (tmp >= 0) {
6333       jdxm[numNewRows++] = tmp;
6334     }
6335   }
6336   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6337   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6338   PetscFunctionReturn(0);
6339 }
6340 
6341 /*@
6342    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6343    of a set of rows and columns of a matrix.
6344 
6345    Collective on Mat
6346 
6347    Input Parameters:
6348 +  mat - the matrix
6349 .  numRows - the number of rows/columns to remove
6350 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6351 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6352 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6353 -  b - optional vector of right hand side, that will be adjusted by provided solution
6354 
6355    Notes:
6356    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6357    but does not release memory.  For the dense and block diagonal
6358    formats this does not alter the nonzero structure.
6359 
6360    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6361    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6362    merely zeroed.
6363 
6364    The user can set a value in the diagonal entry (or for the AIJ and
6365    row formats can optionally remove the main diagonal entry from the
6366    nonzero structure as well, by passing 0.0 as the final argument).
6367 
6368    For the parallel case, all processes that share the matrix (i.e.,
6369    those in the communicator used for matrix creation) MUST call this
6370    routine, regardless of whether any rows being zeroed are owned by
6371    them.
6372 
6373    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6374    list only rows local to itself, but the row/column numbers are given in local numbering).
6375 
6376    The grid coordinates are across the entire grid, not just the local portion
6377 
6378    In Fortran idxm and idxn should be declared as
6379 $     MatStencil idxm(4,m)
6380    and the values inserted using
6381 $    idxm(MatStencil_i,1) = i
6382 $    idxm(MatStencil_j,1) = j
6383 $    idxm(MatStencil_k,1) = k
6384 $    idxm(MatStencil_c,1) = c
6385    etc
6386 
6387    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6388    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6389    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6390    DM_BOUNDARY_PERIODIC boundary type.
6391 
6392    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
6393    a single value per point) you can skip filling those indices.
6394 
6395    Level: intermediate
6396 
6397 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6398           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6399 @*/
6400 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6401 {
6402   PetscInt       dim     = mat->stencil.dim;
6403   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6404   PetscInt       *dims   = mat->stencil.dims+1;
6405   PetscInt       *starts = mat->stencil.starts;
6406   PetscInt       *dxm    = (PetscInt*) rows;
6407   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6408   PetscErrorCode ierr;
6409 
6410   PetscFunctionBegin;
6411   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6412   PetscValidType(mat,1);
6413   if (numRows) PetscValidIntPointer(rows,3);
6414 
6415   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6416   for (i = 0; i < numRows; ++i) {
6417     /* Skip unused dimensions (they are ordered k, j, i, c) */
6418     for (j = 0; j < 3-sdim; ++j) dxm++;
6419     /* Local index in X dir */
6420     tmp = *dxm++ - starts[0];
6421     /* Loop over remaining dimensions */
6422     for (j = 0; j < dim-1; ++j) {
6423       /* If nonlocal, set index to be negative */
6424       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6425       /* Update local index */
6426       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6427     }
6428     /* Skip component slot if necessary */
6429     if (mat->stencil.noc) dxm++;
6430     /* Local row number */
6431     if (tmp >= 0) {
6432       jdxm[numNewRows++] = tmp;
6433     }
6434   }
6435   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6436   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6437   PetscFunctionReturn(0);
6438 }
6439 
6440 /*@C
6441    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6442    of a set of rows of a matrix; using local numbering of rows.
6443 
6444    Collective on Mat
6445 
6446    Input Parameters:
6447 +  mat - the matrix
6448 .  numRows - the number of rows to remove
6449 .  rows - the global row indices
6450 .  diag - value put in all diagonals of eliminated rows
6451 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6452 -  b - optional vector of right hand side, that will be adjusted by provided solution
6453 
6454    Notes:
6455    Before calling MatZeroRowsLocal(), the user must first set the
6456    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6457 
6458    For the AIJ matrix formats this removes the old nonzero structure,
6459    but does not release memory.  For the dense and block diagonal
6460    formats this does not alter the nonzero structure.
6461 
6462    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6463    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6464    merely zeroed.
6465 
6466    The user can set a value in the diagonal entry (or for the AIJ and
6467    row formats can optionally remove the main diagonal entry from the
6468    nonzero structure as well, by passing 0.0 as the final argument).
6469 
6470    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6471    owns that are to be zeroed. This saves a global synchronization in the implementation.
6472 
6473    Level: intermediate
6474 
6475 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6476           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6477 @*/
6478 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6479 {
6480   PetscErrorCode ierr;
6481 
6482   PetscFunctionBegin;
6483   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6484   PetscValidType(mat,1);
6485   if (numRows) PetscValidIntPointer(rows,3);
6486   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6487   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6488   MatCheckPreallocated(mat,1);
6489 
6490   if (mat->ops->zerorowslocal) {
6491     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6492   } else {
6493     IS             is, newis;
6494     const PetscInt *newRows;
6495 
6496     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6497     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6498     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6499     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6500     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6501     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6502     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6503     ierr = ISDestroy(&is);CHKERRQ(ierr);
6504   }
6505   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6506   PetscFunctionReturn(0);
6507 }
6508 
6509 /*@
6510    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6511    of a set of rows of a matrix; using local numbering of rows.
6512 
6513    Collective on Mat
6514 
6515    Input Parameters:
6516 +  mat - the matrix
6517 .  is - index set of rows to remove
6518 .  diag - value put in all diagonals of eliminated rows
6519 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6520 -  b - optional vector of right hand side, that will be adjusted by provided solution
6521 
6522    Notes:
6523    Before calling MatZeroRowsLocalIS(), the user must first set the
6524    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6525 
6526    For the AIJ matrix formats this removes the old nonzero structure,
6527    but does not release memory.  For the dense and block diagonal
6528    formats this does not alter the nonzero structure.
6529 
6530    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6531    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6532    merely zeroed.
6533 
6534    The user can set a value in the diagonal entry (or for the AIJ and
6535    row formats can optionally remove the main diagonal entry from the
6536    nonzero structure as well, by passing 0.0 as the final argument).
6537 
6538    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6539    owns that are to be zeroed. This saves a global synchronization in the implementation.
6540 
6541    Level: intermediate
6542 
6543 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6544           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6545 @*/
6546 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6547 {
6548   PetscErrorCode ierr;
6549   PetscInt       numRows;
6550   const PetscInt *rows;
6551 
6552   PetscFunctionBegin;
6553   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6554   PetscValidType(mat,1);
6555   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6556   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6557   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6558   MatCheckPreallocated(mat,1);
6559 
6560   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6561   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6562   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6563   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6564   PetscFunctionReturn(0);
6565 }
6566 
6567 /*@
6568    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6569    of a set of rows and columns of a matrix; using local numbering of rows.
6570 
6571    Collective on Mat
6572 
6573    Input Parameters:
6574 +  mat - the matrix
6575 .  numRows - the number of rows to remove
6576 .  rows - the global row indices
6577 .  diag - value put in all diagonals of eliminated rows
6578 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6579 -  b - optional vector of right hand side, that will be adjusted by provided solution
6580 
6581    Notes:
6582    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6583    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6584 
6585    The user can set a value in the diagonal entry (or for the AIJ and
6586    row formats can optionally remove the main diagonal entry from the
6587    nonzero structure as well, by passing 0.0 as the final argument).
6588 
6589    Level: intermediate
6590 
6591 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6592           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6593 @*/
6594 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6595 {
6596   PetscErrorCode ierr;
6597   IS             is, newis;
6598   const PetscInt *newRows;
6599 
6600   PetscFunctionBegin;
6601   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6602   PetscValidType(mat,1);
6603   if (numRows) PetscValidIntPointer(rows,3);
6604   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6605   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6606   MatCheckPreallocated(mat,1);
6607 
6608   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6609   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6610   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6611   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6612   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6613   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6614   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6615   ierr = ISDestroy(&is);CHKERRQ(ierr);
6616   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6617   PetscFunctionReturn(0);
6618 }
6619 
6620 /*@
6621    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6622    of a set of rows and columns of a matrix; using local numbering of rows.
6623 
6624    Collective on Mat
6625 
6626    Input Parameters:
6627 +  mat - the matrix
6628 .  is - index set of rows to remove
6629 .  diag - value put in all diagonals of eliminated rows
6630 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6631 -  b - optional vector of right hand side, that will be adjusted by provided solution
6632 
6633    Notes:
6634    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6635    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6636 
6637    The user can set a value in the diagonal entry (or for the AIJ and
6638    row formats can optionally remove the main diagonal entry from the
6639    nonzero structure as well, by passing 0.0 as the final argument).
6640 
6641    Level: intermediate
6642 
6643 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6644           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6645 @*/
6646 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6647 {
6648   PetscErrorCode ierr;
6649   PetscInt       numRows;
6650   const PetscInt *rows;
6651 
6652   PetscFunctionBegin;
6653   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6654   PetscValidType(mat,1);
6655   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6656   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6657   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6658   MatCheckPreallocated(mat,1);
6659 
6660   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6661   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6662   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6663   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6664   PetscFunctionReturn(0);
6665 }
6666 
6667 /*@C
6668    MatGetSize - Returns the numbers of rows and columns in a matrix.
6669 
6670    Not Collective
6671 
6672    Input Parameter:
6673 .  mat - the matrix
6674 
6675    Output Parameters:
6676 +  m - the number of global rows
6677 -  n - the number of global columns
6678 
6679    Note: both output parameters can be NULL on input.
6680 
6681    Level: beginner
6682 
6683 .seealso: MatGetLocalSize()
6684 @*/
6685 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6686 {
6687   PetscFunctionBegin;
6688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6689   if (m) *m = mat->rmap->N;
6690   if (n) *n = mat->cmap->N;
6691   PetscFunctionReturn(0);
6692 }
6693 
6694 /*@C
6695    MatGetLocalSize - Returns the number of local rows and local columns
6696    of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs().
6697 
6698    Not Collective
6699 
6700    Input Parameters:
6701 .  mat - the matrix
6702 
6703    Output Parameters:
6704 +  m - the number of local rows
6705 -  n - the number of local columns
6706 
6707    Note: both output parameters can be NULL on input.
6708 
6709    Level: beginner
6710 
6711 .seealso: MatGetSize()
6712 @*/
6713 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6714 {
6715   PetscFunctionBegin;
6716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6717   if (m) PetscValidIntPointer(m,2);
6718   if (n) PetscValidIntPointer(n,3);
6719   if (m) *m = mat->rmap->n;
6720   if (n) *n = mat->cmap->n;
6721   PetscFunctionReturn(0);
6722 }
6723 
6724 /*@C
6725    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6726    this processor. (The columns of the "diagonal block")
6727 
6728    Not Collective, unless matrix has not been allocated, then collective on Mat
6729 
6730    Input Parameters:
6731 .  mat - the matrix
6732 
6733    Output Parameters:
6734 +  m - the global index of the first local column
6735 -  n - one more than the global index of the last local column
6736 
6737    Notes:
6738     both output parameters can be NULL on input.
6739 
6740    Level: developer
6741 
6742 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6743 
6744 @*/
6745 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6746 {
6747   PetscFunctionBegin;
6748   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6749   PetscValidType(mat,1);
6750   if (m) PetscValidIntPointer(m,2);
6751   if (n) PetscValidIntPointer(n,3);
6752   MatCheckPreallocated(mat,1);
6753   if (m) *m = mat->cmap->rstart;
6754   if (n) *n = mat->cmap->rend;
6755   PetscFunctionReturn(0);
6756 }
6757 
6758 /*@C
6759    MatGetOwnershipRange - Returns the range of matrix rows owned by
6760    this processor, assuming that the matrix is laid out with the first
6761    n1 rows on the first processor, the next n2 rows on the second, etc.
6762    For certain parallel layouts this range may not be well defined.
6763 
6764    Not Collective
6765 
6766    Input Parameters:
6767 .  mat - the matrix
6768 
6769    Output Parameters:
6770 +  m - the global index of the first local row
6771 -  n - one more than the global index of the last local row
6772 
6773    Note: Both output parameters can be NULL on input.
6774 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6775 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6776 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6777 
6778    Level: beginner
6779 
6780 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6781 
6782 @*/
6783 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6784 {
6785   PetscFunctionBegin;
6786   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6787   PetscValidType(mat,1);
6788   if (m) PetscValidIntPointer(m,2);
6789   if (n) PetscValidIntPointer(n,3);
6790   MatCheckPreallocated(mat,1);
6791   if (m) *m = mat->rmap->rstart;
6792   if (n) *n = mat->rmap->rend;
6793   PetscFunctionReturn(0);
6794 }
6795 
6796 /*@C
6797    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6798    each process
6799 
6800    Not Collective, unless matrix has not been allocated, then collective on Mat
6801 
6802    Input Parameters:
6803 .  mat - the matrix
6804 
6805    Output Parameters:
6806 .  ranges - start of each processors portion plus one more than the total length at the end
6807 
6808    Level: beginner
6809 
6810 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6811 
6812 @*/
6813 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6814 {
6815   PetscErrorCode ierr;
6816 
6817   PetscFunctionBegin;
6818   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6819   PetscValidType(mat,1);
6820   MatCheckPreallocated(mat,1);
6821   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6822   PetscFunctionReturn(0);
6823 }
6824 
6825 /*@C
6826    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6827    this processor. (The columns of the "diagonal blocks" for each process)
6828 
6829    Not Collective, unless matrix has not been allocated, then collective on Mat
6830 
6831    Input Parameters:
6832 .  mat - the matrix
6833 
6834    Output Parameters:
6835 .  ranges - start of each processors portion plus one more then the total length at the end
6836 
6837    Level: beginner
6838 
6839 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6840 
6841 @*/
6842 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6843 {
6844   PetscErrorCode ierr;
6845 
6846   PetscFunctionBegin;
6847   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6848   PetscValidType(mat,1);
6849   MatCheckPreallocated(mat,1);
6850   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6851   PetscFunctionReturn(0);
6852 }
6853 
6854 /*@C
6855    MatGetOwnershipIS - Get row and column ownership as index sets
6856 
6857    Not Collective
6858 
6859    Input Arguments:
6860 .  A - matrix of type Elemental or ScaLAPACK
6861 
6862    Output Arguments:
6863 +  rows - rows in which this process owns elements
6864 -  cols - columns in which this process owns elements
6865 
6866    Level: intermediate
6867 
6868 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6869 @*/
6870 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6871 {
6872   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6873 
6874   PetscFunctionBegin;
6875   MatCheckPreallocated(A,1);
6876   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6877   if (f) {
6878     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6879   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6880     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6881     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6882   }
6883   PetscFunctionReturn(0);
6884 }
6885 
6886 /*@C
6887    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6888    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6889    to complete the factorization.
6890 
6891    Collective on Mat
6892 
6893    Input Parameters:
6894 +  mat - the matrix
6895 .  row - row permutation
6896 .  column - column permutation
6897 -  info - structure containing
6898 $      levels - number of levels of fill.
6899 $      expected fill - as ratio of original fill.
6900 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6901                 missing diagonal entries)
6902 
6903    Output Parameters:
6904 .  fact - new matrix that has been symbolically factored
6905 
6906    Notes:
6907     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6908 
6909    Most users should employ the simplified KSP interface for linear solvers
6910    instead of working directly with matrix algebra routines such as this.
6911    See, e.g., KSPCreate().
6912 
6913    Level: developer
6914 
6915 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6916           MatGetOrdering(), MatFactorInfo
6917 
6918     Note: this uses the definition of level of fill as in Y. Saad, 2003
6919 
6920     Developer Note: fortran interface is not autogenerated as the f90
6921     interface defintion cannot be generated correctly [due to MatFactorInfo]
6922 
6923    References:
6924      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6925 @*/
6926 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6927 {
6928   PetscErrorCode ierr;
6929 
6930   PetscFunctionBegin;
6931   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6932   PetscValidType(mat,1);
6933   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
6934   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
6935   PetscValidPointer(info,4);
6936   PetscValidPointer(fact,5);
6937   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6938   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6939   if (!fact->ops->ilufactorsymbolic) {
6940     MatSolverType stype;
6941     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
6942     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype);
6943   }
6944   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6945   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6946   MatCheckPreallocated(mat,2);
6947 
6948   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6949   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6950   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6951   PetscFunctionReturn(0);
6952 }
6953 
6954 /*@C
6955    MatICCFactorSymbolic - Performs symbolic incomplete
6956    Cholesky factorization for a symmetric matrix.  Use
6957    MatCholeskyFactorNumeric() to complete the factorization.
6958 
6959    Collective on Mat
6960 
6961    Input Parameters:
6962 +  mat - the matrix
6963 .  perm - row and column permutation
6964 -  info - structure containing
6965 $      levels - number of levels of fill.
6966 $      expected fill - as ratio of original fill.
6967 
6968    Output Parameter:
6969 .  fact - the factored matrix
6970 
6971    Notes:
6972    Most users should employ the KSP interface for linear solvers
6973    instead of working directly with matrix algebra routines such as this.
6974    See, e.g., KSPCreate().
6975 
6976    Level: developer
6977 
6978 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6979 
6980     Note: this uses the definition of level of fill as in Y. Saad, 2003
6981 
6982     Developer Note: fortran interface is not autogenerated as the f90
6983     interface defintion cannot be generated correctly [due to MatFactorInfo]
6984 
6985    References:
6986      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6987 @*/
6988 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6989 {
6990   PetscErrorCode ierr;
6991 
6992   PetscFunctionBegin;
6993   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6994   PetscValidType(mat,1);
6995   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6996   PetscValidPointer(info,3);
6997   PetscValidPointer(fact,4);
6998   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6999   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
7000   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
7001   if (!(fact)->ops->iccfactorsymbolic) {
7002     MatSolverType stype;
7003     ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr);
7004     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype);
7005   }
7006   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7007   MatCheckPreallocated(mat,2);
7008 
7009   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
7010   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
7011   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
7012   PetscFunctionReturn(0);
7013 }
7014 
7015 /*@C
7016    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
7017    points to an array of valid matrices, they may be reused to store the new
7018    submatrices.
7019 
7020    Collective on Mat
7021 
7022    Input Parameters:
7023 +  mat - the matrix
7024 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
7025 .  irow, icol - index sets of rows and columns to extract
7026 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7027 
7028    Output Parameter:
7029 .  submat - the array of submatrices
7030 
7031    Notes:
7032    MatCreateSubMatrices() can extract ONLY sequential submatrices
7033    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
7034    to extract a parallel submatrix.
7035 
7036    Some matrix types place restrictions on the row and column
7037    indices, such as that they be sorted or that they be equal to each other.
7038 
7039    The index sets may not have duplicate entries.
7040 
7041    When extracting submatrices from a parallel matrix, each processor can
7042    form a different submatrix by setting the rows and columns of its
7043    individual index sets according to the local submatrix desired.
7044 
7045    When finished using the submatrices, the user should destroy
7046    them with MatDestroySubMatrices().
7047 
7048    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
7049    original matrix has not changed from that last call to MatCreateSubMatrices().
7050 
7051    This routine creates the matrices in submat; you should NOT create them before
7052    calling it. It also allocates the array of matrix pointers submat.
7053 
7054    For BAIJ matrices the index sets must respect the block structure, that is if they
7055    request one row/column in a block, they must request all rows/columns that are in
7056    that block. For example, if the block size is 2 you cannot request just row 0 and
7057    column 0.
7058 
7059    Fortran Note:
7060    The Fortran interface is slightly different from that given below; it
7061    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
7062 
7063    Level: advanced
7064 
7065 
7066 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
7067 @*/
7068 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
7069 {
7070   PetscErrorCode ierr;
7071   PetscInt       i;
7072   PetscBool      eq;
7073 
7074   PetscFunctionBegin;
7075   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7076   PetscValidType(mat,1);
7077   if (n) {
7078     PetscValidPointer(irow,3);
7079     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
7080     PetscValidPointer(icol,4);
7081     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
7082   }
7083   PetscValidPointer(submat,6);
7084   if (n && scall == MAT_REUSE_MATRIX) {
7085     PetscValidPointer(*submat,6);
7086     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
7087   }
7088   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7089   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7090   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7091   MatCheckPreallocated(mat,1);
7092 
7093   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7094   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
7095   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7096   for (i=0; i<n; i++) {
7097     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
7098     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
7099     if (eq) {
7100       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
7101     }
7102   }
7103   PetscFunctionReturn(0);
7104 }
7105 
7106 /*@C
7107    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
7108 
7109    Collective on Mat
7110 
7111    Input Parameters:
7112 +  mat - the matrix
7113 .  n   - the number of submatrixes to be extracted
7114 .  irow, icol - index sets of rows and columns to extract
7115 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7116 
7117    Output Parameter:
7118 .  submat - the array of submatrices
7119 
7120    Level: advanced
7121 
7122 
7123 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
7124 @*/
7125 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
7126 {
7127   PetscErrorCode ierr;
7128   PetscInt       i;
7129   PetscBool      eq;
7130 
7131   PetscFunctionBegin;
7132   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7133   PetscValidType(mat,1);
7134   if (n) {
7135     PetscValidPointer(irow,3);
7136     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
7137     PetscValidPointer(icol,4);
7138     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
7139   }
7140   PetscValidPointer(submat,6);
7141   if (n && scall == MAT_REUSE_MATRIX) {
7142     PetscValidPointer(*submat,6);
7143     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
7144   }
7145   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7146   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7147   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7148   MatCheckPreallocated(mat,1);
7149 
7150   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7151   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
7152   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
7153   for (i=0; i<n; i++) {
7154     ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr);
7155     if (eq) {
7156       ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr);
7157     }
7158   }
7159   PetscFunctionReturn(0);
7160 }
7161 
7162 /*@C
7163    MatDestroyMatrices - Destroys an array of matrices.
7164 
7165    Collective on Mat
7166 
7167    Input Parameters:
7168 +  n - the number of local matrices
7169 -  mat - the matrices (note that this is a pointer to the array of matrices)
7170 
7171    Level: advanced
7172 
7173     Notes:
7174     Frees not only the matrices, but also the array that contains the matrices
7175            In Fortran will not free the array.
7176 
7177 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7178 @*/
7179 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7180 {
7181   PetscErrorCode ierr;
7182   PetscInt       i;
7183 
7184   PetscFunctionBegin;
7185   if (!*mat) PetscFunctionReturn(0);
7186   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7187   PetscValidPointer(mat,2);
7188 
7189   for (i=0; i<n; i++) {
7190     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7191   }
7192 
7193   /* memory is allocated even if n = 0 */
7194   ierr = PetscFree(*mat);CHKERRQ(ierr);
7195   PetscFunctionReturn(0);
7196 }
7197 
7198 /*@C
7199    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7200 
7201    Collective on Mat
7202 
7203    Input Parameters:
7204 +  n - the number of local matrices
7205 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7206                        sequence of MatCreateSubMatrices())
7207 
7208    Level: advanced
7209 
7210     Notes:
7211     Frees not only the matrices, but also the array that contains the matrices
7212            In Fortran will not free the array.
7213 
7214 .seealso: MatCreateSubMatrices()
7215 @*/
7216 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7217 {
7218   PetscErrorCode ierr;
7219   Mat            mat0;
7220 
7221   PetscFunctionBegin;
7222   if (!*mat) PetscFunctionReturn(0);
7223   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7224   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7225   PetscValidPointer(mat,2);
7226 
7227   mat0 = (*mat)[0];
7228   if (mat0 && mat0->ops->destroysubmatrices) {
7229     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7230   } else {
7231     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7232   }
7233   PetscFunctionReturn(0);
7234 }
7235 
7236 /*@C
7237    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7238 
7239    Collective on Mat
7240 
7241    Input Parameters:
7242 .  mat - the matrix
7243 
7244    Output Parameter:
7245 .  matstruct - the sequential matrix with the nonzero structure of mat
7246 
7247   Level: intermediate
7248 
7249 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7250 @*/
7251 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7252 {
7253   PetscErrorCode ierr;
7254 
7255   PetscFunctionBegin;
7256   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7257   PetscValidPointer(matstruct,2);
7258 
7259   PetscValidType(mat,1);
7260   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7261   MatCheckPreallocated(mat,1);
7262 
7263   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7264   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7265   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7266   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7267   PetscFunctionReturn(0);
7268 }
7269 
7270 /*@C
7271    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7272 
7273    Collective on Mat
7274 
7275    Input Parameters:
7276 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7277                        sequence of MatGetSequentialNonzeroStructure())
7278 
7279    Level: advanced
7280 
7281     Notes:
7282     Frees not only the matrices, but also the array that contains the matrices
7283 
7284 .seealso: MatGetSeqNonzeroStructure()
7285 @*/
7286 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7287 {
7288   PetscErrorCode ierr;
7289 
7290   PetscFunctionBegin;
7291   PetscValidPointer(mat,1);
7292   ierr = MatDestroy(mat);CHKERRQ(ierr);
7293   PetscFunctionReturn(0);
7294 }
7295 
7296 /*@
7297    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7298    replaces the index sets by larger ones that represent submatrices with
7299    additional overlap.
7300 
7301    Collective on Mat
7302 
7303    Input Parameters:
7304 +  mat - the matrix
7305 .  n   - the number of index sets
7306 .  is  - the array of index sets (these index sets will changed during the call)
7307 -  ov  - the additional overlap requested
7308 
7309    Options Database:
7310 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7311 
7312    Level: developer
7313 
7314 
7315 .seealso: MatCreateSubMatrices()
7316 @*/
7317 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7318 {
7319   PetscErrorCode ierr;
7320 
7321   PetscFunctionBegin;
7322   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7323   PetscValidType(mat,1);
7324   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7325   if (n) {
7326     PetscValidPointer(is,3);
7327     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7328   }
7329   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7330   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7331   MatCheckPreallocated(mat,1);
7332 
7333   if (!ov) PetscFunctionReturn(0);
7334   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7335   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7336   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7337   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7338   PetscFunctionReturn(0);
7339 }
7340 
7341 
7342 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7343 
7344 /*@
7345    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7346    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7347    additional overlap.
7348 
7349    Collective on Mat
7350 
7351    Input Parameters:
7352 +  mat - the matrix
7353 .  n   - the number of index sets
7354 .  is  - the array of index sets (these index sets will changed during the call)
7355 -  ov  - the additional overlap requested
7356 
7357    Options Database:
7358 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7359 
7360    Level: developer
7361 
7362 
7363 .seealso: MatCreateSubMatrices()
7364 @*/
7365 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7366 {
7367   PetscInt       i;
7368   PetscErrorCode ierr;
7369 
7370   PetscFunctionBegin;
7371   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7372   PetscValidType(mat,1);
7373   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7374   if (n) {
7375     PetscValidPointer(is,3);
7376     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7377   }
7378   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7379   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7380   MatCheckPreallocated(mat,1);
7381   if (!ov) PetscFunctionReturn(0);
7382   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7383   for (i=0; i<n; i++){
7384         ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7385   }
7386   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7387   PetscFunctionReturn(0);
7388 }
7389 
7390 
7391 
7392 
7393 /*@
7394    MatGetBlockSize - Returns the matrix block size.
7395 
7396    Not Collective
7397 
7398    Input Parameter:
7399 .  mat - the matrix
7400 
7401    Output Parameter:
7402 .  bs - block size
7403 
7404    Notes:
7405     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7406 
7407    If the block size has not been set yet this routine returns 1.
7408 
7409    Level: intermediate
7410 
7411 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7412 @*/
7413 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7414 {
7415   PetscFunctionBegin;
7416   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7417   PetscValidIntPointer(bs,2);
7418   *bs = PetscAbs(mat->rmap->bs);
7419   PetscFunctionReturn(0);
7420 }
7421 
7422 /*@
7423    MatGetBlockSizes - Returns the matrix block row and column sizes.
7424 
7425    Not Collective
7426 
7427    Input Parameter:
7428 .  mat - the matrix
7429 
7430    Output Parameter:
7431 +  rbs - row block size
7432 -  cbs - column block size
7433 
7434    Notes:
7435     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7436     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7437 
7438    If a block size has not been set yet this routine returns 1.
7439 
7440    Level: intermediate
7441 
7442 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7443 @*/
7444 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7445 {
7446   PetscFunctionBegin;
7447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7448   if (rbs) PetscValidIntPointer(rbs,2);
7449   if (cbs) PetscValidIntPointer(cbs,3);
7450   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7451   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7452   PetscFunctionReturn(0);
7453 }
7454 
7455 /*@
7456    MatSetBlockSize - Sets the matrix block size.
7457 
7458    Logically Collective on Mat
7459 
7460    Input Parameters:
7461 +  mat - the matrix
7462 -  bs - block size
7463 
7464    Notes:
7465     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7466     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7467 
7468     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7469     is compatible with the matrix local sizes.
7470 
7471    Level: intermediate
7472 
7473 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7474 @*/
7475 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7476 {
7477   PetscErrorCode ierr;
7478 
7479   PetscFunctionBegin;
7480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7481   PetscValidLogicalCollectiveInt(mat,bs,2);
7482   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7483   PetscFunctionReturn(0);
7484 }
7485 
7486 /*@
7487    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7488 
7489    Logically Collective on Mat
7490 
7491    Input Parameters:
7492 +  mat - the matrix
7493 .  nblocks - the number of blocks on this process
7494 -  bsizes - the block sizes
7495 
7496    Notes:
7497     Currently used by PCVPBJACOBI for SeqAIJ matrices
7498 
7499    Level: intermediate
7500 
7501 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7502 @*/
7503 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7504 {
7505   PetscErrorCode ierr;
7506   PetscInt       i,ncnt = 0, nlocal;
7507 
7508   PetscFunctionBegin;
7509   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7510   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7511   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7512   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7513   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);
7514   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7515   mat->nblocks = nblocks;
7516   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7517   ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr);
7518   PetscFunctionReturn(0);
7519 }
7520 
7521 /*@C
7522    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7523 
7524    Logically Collective on Mat
7525 
7526    Input Parameters:
7527 .  mat - the matrix
7528 
7529    Output Parameters:
7530 +  nblocks - the number of blocks on this process
7531 -  bsizes - the block sizes
7532 
7533    Notes: Currently not supported from Fortran
7534 
7535    Level: intermediate
7536 
7537 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7538 @*/
7539 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7540 {
7541   PetscFunctionBegin;
7542   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7543   *nblocks = mat->nblocks;
7544   *bsizes  = mat->bsizes;
7545   PetscFunctionReturn(0);
7546 }
7547 
7548 /*@
7549    MatSetBlockSizes - Sets the matrix block row and column sizes.
7550 
7551    Logically Collective on Mat
7552 
7553    Input Parameters:
7554 +  mat - the matrix
7555 .  rbs - row block size
7556 -  cbs - column block size
7557 
7558    Notes:
7559     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7560     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7561     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7562 
7563     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7564     are compatible with the matrix local sizes.
7565 
7566     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7567 
7568    Level: intermediate
7569 
7570 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7571 @*/
7572 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7573 {
7574   PetscErrorCode ierr;
7575 
7576   PetscFunctionBegin;
7577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7578   PetscValidLogicalCollectiveInt(mat,rbs,2);
7579   PetscValidLogicalCollectiveInt(mat,cbs,3);
7580   if (mat->ops->setblocksizes) {
7581     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7582   }
7583   if (mat->rmap->refcnt) {
7584     ISLocalToGlobalMapping l2g = NULL;
7585     PetscLayout            nmap = NULL;
7586 
7587     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7588     if (mat->rmap->mapping) {
7589       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7590     }
7591     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7592     mat->rmap = nmap;
7593     mat->rmap->mapping = l2g;
7594   }
7595   if (mat->cmap->refcnt) {
7596     ISLocalToGlobalMapping l2g = NULL;
7597     PetscLayout            nmap = NULL;
7598 
7599     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7600     if (mat->cmap->mapping) {
7601       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7602     }
7603     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7604     mat->cmap = nmap;
7605     mat->cmap->mapping = l2g;
7606   }
7607   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7608   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7609   PetscFunctionReturn(0);
7610 }
7611 
7612 /*@
7613    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7614 
7615    Logically Collective on Mat
7616 
7617    Input Parameters:
7618 +  mat - the matrix
7619 .  fromRow - matrix from which to copy row block size
7620 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7621 
7622    Level: developer
7623 
7624 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7625 @*/
7626 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7627 {
7628   PetscErrorCode ierr;
7629 
7630   PetscFunctionBegin;
7631   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7632   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7633   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7634   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7635   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7636   PetscFunctionReturn(0);
7637 }
7638 
7639 /*@
7640    MatResidual - Default routine to calculate the residual.
7641 
7642    Collective on Mat
7643 
7644    Input Parameters:
7645 +  mat - the matrix
7646 .  b   - the right-hand-side
7647 -  x   - the approximate solution
7648 
7649    Output Parameter:
7650 .  r - location to store the residual
7651 
7652    Level: developer
7653 
7654 .seealso: PCMGSetResidual()
7655 @*/
7656 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7657 {
7658   PetscErrorCode ierr;
7659 
7660   PetscFunctionBegin;
7661   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7662   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7663   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7664   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7665   PetscValidType(mat,1);
7666   MatCheckPreallocated(mat,1);
7667   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7668   if (!mat->ops->residual) {
7669     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7670     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7671   } else {
7672     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7673   }
7674   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7675   PetscFunctionReturn(0);
7676 }
7677 
7678 /*@C
7679     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7680 
7681    Collective on Mat
7682 
7683     Input Parameters:
7684 +   mat - the matrix
7685 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7686 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7687 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7688                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7689                  always used.
7690 
7691     Output Parameters:
7692 +   n - number of rows in the (possibly compressed) matrix
7693 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7694 .   ja - the column indices
7695 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7696            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7697 
7698     Level: developer
7699 
7700     Notes:
7701     You CANNOT change any of the ia[] or ja[] values.
7702 
7703     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7704 
7705     Fortran Notes:
7706     In Fortran use
7707 $
7708 $      PetscInt ia(1), ja(1)
7709 $      PetscOffset iia, jja
7710 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7711 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7712 
7713      or
7714 $
7715 $    PetscInt, pointer :: ia(:),ja(:)
7716 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7717 $    ! Access the ith and jth entries via ia(i) and ja(j)
7718 
7719 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7720 @*/
7721 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7722 {
7723   PetscErrorCode ierr;
7724 
7725   PetscFunctionBegin;
7726   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7727   PetscValidType(mat,1);
7728   PetscValidIntPointer(n,5);
7729   if (ia) PetscValidIntPointer(ia,6);
7730   if (ja) PetscValidIntPointer(ja,7);
7731   PetscValidIntPointer(done,8);
7732   MatCheckPreallocated(mat,1);
7733   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7734   else {
7735     *done = PETSC_TRUE;
7736     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7737     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7738     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7739   }
7740   PetscFunctionReturn(0);
7741 }
7742 
7743 /*@C
7744     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7745 
7746     Collective on Mat
7747 
7748     Input Parameters:
7749 +   mat - the matrix
7750 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7751 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7752                 symmetrized
7753 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7754                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7755                  always used.
7756 .   n - number of columns in the (possibly compressed) matrix
7757 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7758 -   ja - the row indices
7759 
7760     Output Parameters:
7761 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7762 
7763     Level: developer
7764 
7765 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7766 @*/
7767 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7768 {
7769   PetscErrorCode ierr;
7770 
7771   PetscFunctionBegin;
7772   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7773   PetscValidType(mat,1);
7774   PetscValidIntPointer(n,4);
7775   if (ia) PetscValidIntPointer(ia,5);
7776   if (ja) PetscValidIntPointer(ja,6);
7777   PetscValidIntPointer(done,7);
7778   MatCheckPreallocated(mat,1);
7779   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7780   else {
7781     *done = PETSC_TRUE;
7782     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7783   }
7784   PetscFunctionReturn(0);
7785 }
7786 
7787 /*@C
7788     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7789     MatGetRowIJ().
7790 
7791     Collective on Mat
7792 
7793     Input Parameters:
7794 +   mat - the matrix
7795 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7796 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7797                 symmetrized
7798 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7799                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7800                  always used.
7801 .   n - size of (possibly compressed) matrix
7802 .   ia - the row pointers
7803 -   ja - the column indices
7804 
7805     Output Parameters:
7806 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7807 
7808     Note:
7809     This routine zeros out n, ia, and ja. This is to prevent accidental
7810     us of the array after it has been restored. If you pass NULL, it will
7811     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7812 
7813     Level: developer
7814 
7815 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7816 @*/
7817 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7818 {
7819   PetscErrorCode ierr;
7820 
7821   PetscFunctionBegin;
7822   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7823   PetscValidType(mat,1);
7824   if (ia) PetscValidIntPointer(ia,6);
7825   if (ja) PetscValidIntPointer(ja,7);
7826   PetscValidIntPointer(done,8);
7827   MatCheckPreallocated(mat,1);
7828 
7829   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7830   else {
7831     *done = PETSC_TRUE;
7832     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7833     if (n)  *n = 0;
7834     if (ia) *ia = NULL;
7835     if (ja) *ja = NULL;
7836   }
7837   PetscFunctionReturn(0);
7838 }
7839 
7840 /*@C
7841     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7842     MatGetColumnIJ().
7843 
7844     Collective on Mat
7845 
7846     Input Parameters:
7847 +   mat - the matrix
7848 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7849 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7850                 symmetrized
7851 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7852                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7853                  always used.
7854 
7855     Output Parameters:
7856 +   n - size of (possibly compressed) matrix
7857 .   ia - the column pointers
7858 .   ja - the row indices
7859 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7860 
7861     Level: developer
7862 
7863 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7864 @*/
7865 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7866 {
7867   PetscErrorCode ierr;
7868 
7869   PetscFunctionBegin;
7870   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7871   PetscValidType(mat,1);
7872   if (ia) PetscValidIntPointer(ia,5);
7873   if (ja) PetscValidIntPointer(ja,6);
7874   PetscValidIntPointer(done,7);
7875   MatCheckPreallocated(mat,1);
7876 
7877   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7878   else {
7879     *done = PETSC_TRUE;
7880     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7881     if (n)  *n = 0;
7882     if (ia) *ia = NULL;
7883     if (ja) *ja = NULL;
7884   }
7885   PetscFunctionReturn(0);
7886 }
7887 
7888 /*@C
7889     MatColoringPatch -Used inside matrix coloring routines that
7890     use MatGetRowIJ() and/or MatGetColumnIJ().
7891 
7892     Collective on Mat
7893 
7894     Input Parameters:
7895 +   mat - the matrix
7896 .   ncolors - max color value
7897 .   n   - number of entries in colorarray
7898 -   colorarray - array indicating color for each column
7899 
7900     Output Parameters:
7901 .   iscoloring - coloring generated using colorarray information
7902 
7903     Level: developer
7904 
7905 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7906 
7907 @*/
7908 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7909 {
7910   PetscErrorCode ierr;
7911 
7912   PetscFunctionBegin;
7913   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7914   PetscValidType(mat,1);
7915   PetscValidIntPointer(colorarray,4);
7916   PetscValidPointer(iscoloring,5);
7917   MatCheckPreallocated(mat,1);
7918 
7919   if (!mat->ops->coloringpatch) {
7920     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7921   } else {
7922     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7923   }
7924   PetscFunctionReturn(0);
7925 }
7926 
7927 
7928 /*@
7929    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7930 
7931    Logically Collective on Mat
7932 
7933    Input Parameter:
7934 .  mat - the factored matrix to be reset
7935 
7936    Notes:
7937    This routine should be used only with factored matrices formed by in-place
7938    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7939    format).  This option can save memory, for example, when solving nonlinear
7940    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7941    ILU(0) preconditioner.
7942 
7943    Note that one can specify in-place ILU(0) factorization by calling
7944 .vb
7945      PCType(pc,PCILU);
7946      PCFactorSeUseInPlace(pc);
7947 .ve
7948    or by using the options -pc_type ilu -pc_factor_in_place
7949 
7950    In-place factorization ILU(0) can also be used as a local
7951    solver for the blocks within the block Jacobi or additive Schwarz
7952    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7953    for details on setting local solver options.
7954 
7955    Most users should employ the simplified KSP interface for linear solvers
7956    instead of working directly with matrix algebra routines such as this.
7957    See, e.g., KSPCreate().
7958 
7959    Level: developer
7960 
7961 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7962 
7963 @*/
7964 PetscErrorCode MatSetUnfactored(Mat mat)
7965 {
7966   PetscErrorCode ierr;
7967 
7968   PetscFunctionBegin;
7969   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7970   PetscValidType(mat,1);
7971   MatCheckPreallocated(mat,1);
7972   mat->factortype = MAT_FACTOR_NONE;
7973   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7974   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7975   PetscFunctionReturn(0);
7976 }
7977 
7978 /*MC
7979     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7980 
7981     Synopsis:
7982     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7983 
7984     Not collective
7985 
7986     Input Parameter:
7987 .   x - matrix
7988 
7989     Output Parameters:
7990 +   xx_v - the Fortran90 pointer to the array
7991 -   ierr - error code
7992 
7993     Example of Usage:
7994 .vb
7995       PetscScalar, pointer xx_v(:,:)
7996       ....
7997       call MatDenseGetArrayF90(x,xx_v,ierr)
7998       a = xx_v(3)
7999       call MatDenseRestoreArrayF90(x,xx_v,ierr)
8000 .ve
8001 
8002     Level: advanced
8003 
8004 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
8005 
8006 M*/
8007 
8008 /*MC
8009     MatDenseRestoreArrayF90 - Restores a matrix array that has been
8010     accessed with MatDenseGetArrayF90().
8011 
8012     Synopsis:
8013     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
8014 
8015     Not collective
8016 
8017     Input Parameters:
8018 +   x - matrix
8019 -   xx_v - the Fortran90 pointer to the array
8020 
8021     Output Parameter:
8022 .   ierr - error code
8023 
8024     Example of Usage:
8025 .vb
8026        PetscScalar, pointer xx_v(:,:)
8027        ....
8028        call MatDenseGetArrayF90(x,xx_v,ierr)
8029        a = xx_v(3)
8030        call MatDenseRestoreArrayF90(x,xx_v,ierr)
8031 .ve
8032 
8033     Level: advanced
8034 
8035 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
8036 
8037 M*/
8038 
8039 
8040 /*MC
8041     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
8042 
8043     Synopsis:
8044     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
8045 
8046     Not collective
8047 
8048     Input Parameter:
8049 .   x - matrix
8050 
8051     Output Parameters:
8052 +   xx_v - the Fortran90 pointer to the array
8053 -   ierr - error code
8054 
8055     Example of Usage:
8056 .vb
8057       PetscScalar, pointer xx_v(:)
8058       ....
8059       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
8060       a = xx_v(3)
8061       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
8062 .ve
8063 
8064     Level: advanced
8065 
8066 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
8067 
8068 M*/
8069 
8070 /*MC
8071     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
8072     accessed with MatSeqAIJGetArrayF90().
8073 
8074     Synopsis:
8075     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
8076 
8077     Not collective
8078 
8079     Input Parameters:
8080 +   x - matrix
8081 -   xx_v - the Fortran90 pointer to the array
8082 
8083     Output Parameter:
8084 .   ierr - error code
8085 
8086     Example of Usage:
8087 .vb
8088        PetscScalar, pointer xx_v(:)
8089        ....
8090        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
8091        a = xx_v(3)
8092        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
8093 .ve
8094 
8095     Level: advanced
8096 
8097 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
8098 
8099 M*/
8100 
8101 
8102 /*@
8103     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
8104                       as the original matrix.
8105 
8106     Collective on Mat
8107 
8108     Input Parameters:
8109 +   mat - the original matrix
8110 .   isrow - parallel IS containing the rows this processor should obtain
8111 .   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.
8112 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8113 
8114     Output Parameter:
8115 .   newmat - the new submatrix, of the same type as the old
8116 
8117     Level: advanced
8118 
8119     Notes:
8120     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
8121 
8122     Some matrix types place restrictions on the row and column indices, such
8123     as that they be sorted or that they be equal to each other.
8124 
8125     The index sets may not have duplicate entries.
8126 
8127       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
8128    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
8129    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
8130    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
8131    you are finished using it.
8132 
8133     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
8134     the input matrix.
8135 
8136     If iscol is NULL then all columns are obtained (not supported in Fortran).
8137 
8138    Example usage:
8139    Consider the following 8x8 matrix with 34 non-zero values, that is
8140    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8141    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8142    as follows:
8143 
8144 .vb
8145             1  2  0  |  0  3  0  |  0  4
8146     Proc0   0  5  6  |  7  0  0  |  8  0
8147             9  0 10  | 11  0  0  | 12  0
8148     -------------------------------------
8149            13  0 14  | 15 16 17  |  0  0
8150     Proc1   0 18  0  | 19 20 21  |  0  0
8151             0  0  0  | 22 23  0  | 24  0
8152     -------------------------------------
8153     Proc2  25 26 27  |  0  0 28  | 29  0
8154            30  0  0  | 31 32 33  |  0 34
8155 .ve
8156 
8157     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8158 
8159 .vb
8160             2  0  |  0  3  0  |  0
8161     Proc0   5  6  |  7  0  0  |  8
8162     -------------------------------
8163     Proc1  18  0  | 19 20 21  |  0
8164     -------------------------------
8165     Proc2  26 27  |  0  0 28  | 29
8166             0  0  | 31 32 33  |  0
8167 .ve
8168 
8169 
8170 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate()
8171 @*/
8172 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8173 {
8174   PetscErrorCode ierr;
8175   PetscMPIInt    size;
8176   Mat            *local;
8177   IS             iscoltmp;
8178   PetscBool      flg;
8179 
8180   PetscFunctionBegin;
8181   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8182   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8183   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8184   PetscValidPointer(newmat,5);
8185   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8186   PetscValidType(mat,1);
8187   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8188   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8189 
8190   MatCheckPreallocated(mat,1);
8191   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
8192 
8193   if (!iscol || isrow == iscol) {
8194     PetscBool   stride;
8195     PetscMPIInt grabentirematrix = 0,grab;
8196     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8197     if (stride) {
8198       PetscInt first,step,n,rstart,rend;
8199       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8200       if (step == 1) {
8201         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8202         if (rstart == first) {
8203           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8204           if (n == rend-rstart) {
8205             grabentirematrix = 1;
8206           }
8207         }
8208       }
8209     }
8210     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRMPI(ierr);
8211     if (grab) {
8212       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8213       if (cll == MAT_INITIAL_MATRIX) {
8214         *newmat = mat;
8215         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8216       }
8217       PetscFunctionReturn(0);
8218     }
8219   }
8220 
8221   if (!iscol) {
8222     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8223   } else {
8224     iscoltmp = iscol;
8225   }
8226 
8227   /* if original matrix is on just one processor then use submatrix generated */
8228   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8229     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8230     goto setproperties;
8231   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8232     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8233     *newmat = *local;
8234     ierr    = PetscFree(local);CHKERRQ(ierr);
8235     goto setproperties;
8236   } else if (!mat->ops->createsubmatrix) {
8237     /* Create a new matrix type that implements the operation using the full matrix */
8238     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8239     switch (cll) {
8240     case MAT_INITIAL_MATRIX:
8241       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8242       break;
8243     case MAT_REUSE_MATRIX:
8244       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8245       break;
8246     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8247     }
8248     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8249     goto setproperties;
8250   }
8251 
8252   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8253   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8254   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8255   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8256 
8257 setproperties:
8258   ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr);
8259   if (flg) {
8260     ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr);
8261   }
8262   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8263   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8264   PetscFunctionReturn(0);
8265 }
8266 
8267 /*@
8268    MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix
8269 
8270    Not Collective
8271 
8272    Input Parameters:
8273 +  A - the matrix we wish to propagate options from
8274 -  B - the matrix we wish to propagate options to
8275 
8276    Level: beginner
8277 
8278    Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC
8279 
8280 .seealso: MatSetOption()
8281 @*/
8282 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B)
8283 {
8284   PetscErrorCode ierr;
8285 
8286   PetscFunctionBegin;
8287   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8288   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
8289   if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */
8290     ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr);
8291   }
8292   if (A->structurally_symmetric_set) {
8293     ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr);
8294   }
8295   if (A->hermitian_set) {
8296     ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr);
8297   }
8298   if (A->spd_set) {
8299     ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr);
8300   }
8301   if (A->symmetric_set) {
8302     ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr);
8303   }
8304   PetscFunctionReturn(0);
8305 }
8306 
8307 /*@
8308    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8309    used during the assembly process to store values that belong to
8310    other processors.
8311 
8312    Not Collective
8313 
8314    Input Parameters:
8315 +  mat   - the matrix
8316 .  size  - the initial size of the stash.
8317 -  bsize - the initial size of the block-stash(if used).
8318 
8319    Options Database Keys:
8320 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8321 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8322 
8323    Level: intermediate
8324 
8325    Notes:
8326      The block-stash is used for values set with MatSetValuesBlocked() while
8327      the stash is used for values set with MatSetValues()
8328 
8329      Run with the option -info and look for output of the form
8330      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8331      to determine the appropriate value, MM, to use for size and
8332      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8333      to determine the value, BMM to use for bsize
8334 
8335 
8336 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8337 
8338 @*/
8339 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8340 {
8341   PetscErrorCode ierr;
8342 
8343   PetscFunctionBegin;
8344   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8345   PetscValidType(mat,1);
8346   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8347   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8348   PetscFunctionReturn(0);
8349 }
8350 
8351 /*@
8352    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8353      the matrix
8354 
8355    Neighbor-wise Collective on Mat
8356 
8357    Input Parameters:
8358 +  mat   - the matrix
8359 .  x,y - the vectors
8360 -  w - where the result is stored
8361 
8362    Level: intermediate
8363 
8364    Notes:
8365     w may be the same vector as y.
8366 
8367     This allows one to use either the restriction or interpolation (its transpose)
8368     matrix to do the interpolation
8369 
8370 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8371 
8372 @*/
8373 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8374 {
8375   PetscErrorCode ierr;
8376   PetscInt       M,N,Ny;
8377 
8378   PetscFunctionBegin;
8379   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8380   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8381   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8382   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8383   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8384   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8385   if (M == Ny) {
8386     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8387   } else {
8388     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8389   }
8390   PetscFunctionReturn(0);
8391 }
8392 
8393 /*@
8394    MatInterpolate - y = A*x or A'*x depending on the shape of
8395      the matrix
8396 
8397    Neighbor-wise Collective on Mat
8398 
8399    Input Parameters:
8400 +  mat   - the matrix
8401 -  x,y - the vectors
8402 
8403    Level: intermediate
8404 
8405    Notes:
8406     This allows one to use either the restriction or interpolation (its transpose)
8407     matrix to do the interpolation
8408 
8409 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8410 
8411 @*/
8412 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8413 {
8414   PetscErrorCode ierr;
8415   PetscInt       M,N,Ny;
8416 
8417   PetscFunctionBegin;
8418   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8419   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8420   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8421   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8422   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8423   if (M == Ny) {
8424     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8425   } else {
8426     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8427   }
8428   PetscFunctionReturn(0);
8429 }
8430 
8431 /*@
8432    MatRestrict - y = A*x or A'*x
8433 
8434    Neighbor-wise Collective on Mat
8435 
8436    Input Parameters:
8437 +  mat   - the matrix
8438 -  x,y - the vectors
8439 
8440    Level: intermediate
8441 
8442    Notes:
8443     This allows one to use either the restriction or interpolation (its transpose)
8444     matrix to do the restriction
8445 
8446 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8447 
8448 @*/
8449 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8450 {
8451   PetscErrorCode ierr;
8452   PetscInt       M,N,Ny;
8453 
8454   PetscFunctionBegin;
8455   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8456   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8457   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8458   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8459   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8460   if (M == Ny) {
8461     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8462   } else {
8463     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8464   }
8465   PetscFunctionReturn(0);
8466 }
8467 
8468 /*@
8469    MatMatInterpolateAdd - Y = W + A*X or W + A'*X
8470 
8471    Neighbor-wise Collective on Mat
8472 
8473    Input Parameters:
8474 +  mat   - the matrix
8475 -  w, x - the input dense matrices
8476 
8477    Output Parameters:
8478 .  y - the output dense matrix
8479 
8480    Level: intermediate
8481 
8482    Notes:
8483     This allows one to use either the restriction or interpolation (its transpose)
8484     matrix to do the interpolation. y matrix can be reused if already created with the proper sizes,
8485     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8486 
8487 .seealso: MatInterpolateAdd(), MatMatInterpolate(), MatMatRestrict()
8488 
8489 @*/
8490 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y)
8491 {
8492   PetscErrorCode ierr;
8493   PetscInt       M,N,Mx,Nx,Mo,My = 0,Ny = 0;
8494   PetscBool      trans = PETSC_TRUE;
8495   MatReuse       reuse = MAT_INITIAL_MATRIX;
8496 
8497   PetscFunctionBegin;
8498   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8499   PetscValidHeaderSpecific(x,MAT_CLASSID,2);
8500   PetscValidType(x,2);
8501   if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3);
8502   if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4);
8503   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8504   ierr = MatGetSize(x,&Mx,&Nx);CHKERRQ(ierr);
8505   if (N == Mx) trans = PETSC_FALSE;
8506   else if (M != Mx) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Size mismatch: A %Dx%D, X %Dx%D",M,N,Mx,Nx);
8507   Mo = trans ? N : M;
8508   if (*y) {
8509     ierr = MatGetSize(*y,&My,&Ny);CHKERRQ(ierr);
8510     if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; }
8511     else {
8512       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);
8513       ierr = MatDestroy(y);CHKERRQ(ierr);
8514     }
8515   }
8516 
8517   if (w && *y == w) { /* this is to minimize changes in PCMG */
8518     PetscBool flg;
8519 
8520     ierr = PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w);CHKERRQ(ierr);
8521     if (w) {
8522       PetscInt My,Ny,Mw,Nw;
8523 
8524       ierr = PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg);CHKERRQ(ierr);
8525       ierr = MatGetSize(*y,&My,&Ny);CHKERRQ(ierr);
8526       ierr = MatGetSize(w,&Mw,&Nw);CHKERRQ(ierr);
8527       if (!flg || My != Mw || Ny != Nw) w = NULL;
8528     }
8529     if (!w) {
8530       ierr = MatDuplicate(*y,MAT_COPY_VALUES,&w);CHKERRQ(ierr);
8531       ierr = PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w);CHKERRQ(ierr);
8532       ierr = PetscLogObjectParent((PetscObject)*y,(PetscObject)w);CHKERRQ(ierr);
8533       ierr = PetscObjectDereference((PetscObject)w);CHKERRQ(ierr);
8534     } else {
8535       ierr = MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr);
8536     }
8537   }
8538   if (!trans) {
8539     ierr = MatMatMult(A,x,reuse,PETSC_DEFAULT,y);CHKERRQ(ierr);
8540   } else {
8541     ierr = MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y);CHKERRQ(ierr);
8542   }
8543   if (w) {
8544     ierr = MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr);
8545   }
8546   PetscFunctionReturn(0);
8547 }
8548 
8549 /*@
8550    MatMatInterpolate - Y = A*X or A'*X
8551 
8552    Neighbor-wise Collective on Mat
8553 
8554    Input Parameters:
8555 +  mat   - the matrix
8556 -  x - the input dense matrix
8557 
8558    Output Parameters:
8559 .  y - the output dense matrix
8560 
8561 
8562    Level: intermediate
8563 
8564    Notes:
8565     This allows one to use either the restriction or interpolation (its transpose)
8566     matrix to do the interpolation. y matrix can be reused if already created with the proper sizes,
8567     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8568 
8569 .seealso: MatInterpolate(), MatRestrict(), MatMatRestrict()
8570 
8571 @*/
8572 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y)
8573 {
8574   PetscErrorCode ierr;
8575 
8576   PetscFunctionBegin;
8577   ierr = MatMatInterpolateAdd(A,x,NULL,y);CHKERRQ(ierr);
8578   PetscFunctionReturn(0);
8579 }
8580 
8581 /*@
8582    MatMatRestrict - Y = A*X or A'*X
8583 
8584    Neighbor-wise Collective on Mat
8585 
8586    Input Parameters:
8587 +  mat   - the matrix
8588 -  x - the input dense matrix
8589 
8590    Output Parameters:
8591 .  y - the output dense matrix
8592 
8593 
8594    Level: intermediate
8595 
8596    Notes:
8597     This allows one to use either the restriction or interpolation (its transpose)
8598     matrix to do the restriction. y matrix can be reused if already created with the proper sizes,
8599     otherwise it will be recreated. y must be initialized to NULL if not supplied.
8600 
8601 .seealso: MatRestrict(), MatInterpolate(), MatMatInterpolate()
8602 @*/
8603 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y)
8604 {
8605   PetscErrorCode ierr;
8606 
8607   PetscFunctionBegin;
8608   ierr = MatMatInterpolateAdd(A,x,NULL,y);CHKERRQ(ierr);
8609   PetscFunctionReturn(0);
8610 }
8611 
8612 /*@
8613    MatGetNullSpace - retrieves the null space of a matrix.
8614 
8615    Logically Collective on Mat
8616 
8617    Input Parameters:
8618 +  mat - the matrix
8619 -  nullsp - the null space object
8620 
8621    Level: developer
8622 
8623 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8624 @*/
8625 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8626 {
8627   PetscFunctionBegin;
8628   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8629   PetscValidPointer(nullsp,2);
8630   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8631   PetscFunctionReturn(0);
8632 }
8633 
8634 /*@
8635    MatSetNullSpace - attaches a null space to a matrix.
8636 
8637    Logically Collective on Mat
8638 
8639    Input Parameters:
8640 +  mat - the matrix
8641 -  nullsp - the null space object
8642 
8643    Level: advanced
8644 
8645    Notes:
8646       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8647 
8648       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8649       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8650 
8651       You can remove the null space by calling this routine with an nullsp of NULL
8652 
8653 
8654       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8655    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).
8656    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
8657    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
8658    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).
8659 
8660       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8661 
8662     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
8663     routine also automatically calls MatSetTransposeNullSpace().
8664 
8665 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8666 @*/
8667 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8668 {
8669   PetscErrorCode ierr;
8670 
8671   PetscFunctionBegin;
8672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8673   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8674   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8675   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8676   mat->nullsp = nullsp;
8677   if (mat->symmetric_set && mat->symmetric) {
8678     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8679   }
8680   PetscFunctionReturn(0);
8681 }
8682 
8683 /*@
8684    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8685 
8686    Logically Collective on Mat
8687 
8688    Input Parameters:
8689 +  mat - the matrix
8690 -  nullsp - the null space object
8691 
8692    Level: developer
8693 
8694 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8695 @*/
8696 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8697 {
8698   PetscFunctionBegin;
8699   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8700   PetscValidType(mat,1);
8701   PetscValidPointer(nullsp,2);
8702   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8703   PetscFunctionReturn(0);
8704 }
8705 
8706 /*@
8707    MatSetTransposeNullSpace - attaches a null space to a matrix.
8708 
8709    Logically Collective on Mat
8710 
8711    Input Parameters:
8712 +  mat - the matrix
8713 -  nullsp - the null space object
8714 
8715    Level: advanced
8716 
8717    Notes:
8718       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.
8719       You must also call MatSetNullSpace()
8720 
8721 
8722       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8723    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).
8724    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
8725    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
8726    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).
8727 
8728       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8729 
8730 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8731 @*/
8732 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8733 {
8734   PetscErrorCode ierr;
8735 
8736   PetscFunctionBegin;
8737   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8738   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8739   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8740   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8741   mat->transnullsp = nullsp;
8742   PetscFunctionReturn(0);
8743 }
8744 
8745 /*@
8746    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8747         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8748 
8749    Logically Collective on Mat
8750 
8751    Input Parameters:
8752 +  mat - the matrix
8753 -  nullsp - the null space object
8754 
8755    Level: advanced
8756 
8757    Notes:
8758       Overwrites any previous near null space that may have been attached
8759 
8760       You can remove the null space by calling this routine with an nullsp of NULL
8761 
8762 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8763 @*/
8764 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8765 {
8766   PetscErrorCode ierr;
8767 
8768   PetscFunctionBegin;
8769   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8770   PetscValidType(mat,1);
8771   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8772   MatCheckPreallocated(mat,1);
8773   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8774   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8775   mat->nearnullsp = nullsp;
8776   PetscFunctionReturn(0);
8777 }
8778 
8779 /*@
8780    MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace()
8781 
8782    Not Collective
8783 
8784    Input Parameter:
8785 .  mat - the matrix
8786 
8787    Output Parameter:
8788 .  nullsp - the null space object, NULL if not set
8789 
8790    Level: developer
8791 
8792 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8793 @*/
8794 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8795 {
8796   PetscFunctionBegin;
8797   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8798   PetscValidType(mat,1);
8799   PetscValidPointer(nullsp,2);
8800   MatCheckPreallocated(mat,1);
8801   *nullsp = mat->nearnullsp;
8802   PetscFunctionReturn(0);
8803 }
8804 
8805 /*@C
8806    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8807 
8808    Collective on Mat
8809 
8810    Input Parameters:
8811 +  mat - the matrix
8812 .  row - row/column permutation
8813 .  fill - expected fill factor >= 1.0
8814 -  level - level of fill, for ICC(k)
8815 
8816    Notes:
8817    Probably really in-place only when level of fill is zero, otherwise allocates
8818    new space to store factored matrix and deletes previous memory.
8819 
8820    Most users should employ the simplified KSP interface for linear solvers
8821    instead of working directly with matrix algebra routines such as this.
8822    See, e.g., KSPCreate().
8823 
8824    Level: developer
8825 
8826 
8827 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8828 
8829     Developer Note: fortran interface is not autogenerated as the f90
8830     interface defintion cannot be generated correctly [due to MatFactorInfo]
8831 
8832 @*/
8833 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8834 {
8835   PetscErrorCode ierr;
8836 
8837   PetscFunctionBegin;
8838   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8839   PetscValidType(mat,1);
8840   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8841   PetscValidPointer(info,3);
8842   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8843   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8844   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8845   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8846   MatCheckPreallocated(mat,1);
8847   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8848   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8849   PetscFunctionReturn(0);
8850 }
8851 
8852 /*@
8853    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8854          ghosted ones.
8855 
8856    Not Collective
8857 
8858    Input Parameters:
8859 +  mat - the matrix
8860 -  diag = the diagonal values, including ghost ones
8861 
8862    Level: developer
8863 
8864    Notes:
8865     Works only for MPIAIJ and MPIBAIJ matrices
8866 
8867 .seealso: MatDiagonalScale()
8868 @*/
8869 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8870 {
8871   PetscErrorCode ierr;
8872   PetscMPIInt    size;
8873 
8874   PetscFunctionBegin;
8875   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8876   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8877   PetscValidType(mat,1);
8878 
8879   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8880   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8881   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
8882   if (size == 1) {
8883     PetscInt n,m;
8884     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8885     ierr = MatGetSize(mat,NULL,&m);CHKERRQ(ierr);
8886     if (m == n) {
8887       ierr = MatDiagonalScale(mat,NULL,diag);CHKERRQ(ierr);
8888     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8889   } else {
8890     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8891   }
8892   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8893   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8894   PetscFunctionReturn(0);
8895 }
8896 
8897 /*@
8898    MatGetInertia - Gets the inertia from a factored matrix
8899 
8900    Collective on Mat
8901 
8902    Input Parameter:
8903 .  mat - the matrix
8904 
8905    Output Parameters:
8906 +   nneg - number of negative eigenvalues
8907 .   nzero - number of zero eigenvalues
8908 -   npos - number of positive eigenvalues
8909 
8910    Level: advanced
8911 
8912    Notes:
8913     Matrix must have been factored by MatCholeskyFactor()
8914 
8915 
8916 @*/
8917 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8918 {
8919   PetscErrorCode ierr;
8920 
8921   PetscFunctionBegin;
8922   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8923   PetscValidType(mat,1);
8924   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8925   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8926   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8927   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8928   PetscFunctionReturn(0);
8929 }
8930 
8931 /* ----------------------------------------------------------------*/
8932 /*@C
8933    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8934 
8935    Neighbor-wise Collective on Mats
8936 
8937    Input Parameters:
8938 +  mat - the factored matrix
8939 -  b - the right-hand-side vectors
8940 
8941    Output Parameter:
8942 .  x - the result vectors
8943 
8944    Notes:
8945    The vectors b and x cannot be the same.  I.e., one cannot
8946    call MatSolves(A,x,x).
8947 
8948    Notes:
8949    Most users should employ the simplified KSP interface for linear solvers
8950    instead of working directly with matrix algebra routines such as this.
8951    See, e.g., KSPCreate().
8952 
8953    Level: developer
8954 
8955 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8956 @*/
8957 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8958 {
8959   PetscErrorCode ierr;
8960 
8961   PetscFunctionBegin;
8962   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8963   PetscValidType(mat,1);
8964   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8965   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8966   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8967 
8968   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8969   MatCheckPreallocated(mat,1);
8970   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8971   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8972   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8973   PetscFunctionReturn(0);
8974 }
8975 
8976 /*@
8977    MatIsSymmetric - Test whether a matrix is symmetric
8978 
8979    Collective on Mat
8980 
8981    Input Parameter:
8982 +  A - the matrix to test
8983 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8984 
8985    Output Parameters:
8986 .  flg - the result
8987 
8988    Notes:
8989     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8990 
8991    Level: intermediate
8992 
8993 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8994 @*/
8995 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8996 {
8997   PetscErrorCode ierr;
8998 
8999   PetscFunctionBegin;
9000   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9001   PetscValidBoolPointer(flg,2);
9002 
9003   if (!A->symmetric_set) {
9004     if (!A->ops->issymmetric) {
9005       MatType mattype;
9006       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9007       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
9008     }
9009     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
9010     if (!tol) {
9011       ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr);
9012     }
9013   } else if (A->symmetric) {
9014     *flg = PETSC_TRUE;
9015   } else if (!tol) {
9016     *flg = PETSC_FALSE;
9017   } else {
9018     if (!A->ops->issymmetric) {
9019       MatType mattype;
9020       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9021       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype);
9022     }
9023     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
9024   }
9025   PetscFunctionReturn(0);
9026 }
9027 
9028 /*@
9029    MatIsHermitian - Test whether a matrix is Hermitian
9030 
9031    Collective on Mat
9032 
9033    Input Parameter:
9034 +  A - the matrix to test
9035 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
9036 
9037    Output Parameters:
9038 .  flg - the result
9039 
9040    Level: intermediate
9041 
9042 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
9043           MatIsSymmetricKnown(), MatIsSymmetric()
9044 @*/
9045 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
9046 {
9047   PetscErrorCode ierr;
9048 
9049   PetscFunctionBegin;
9050   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9051   PetscValidBoolPointer(flg,2);
9052 
9053   if (!A->hermitian_set) {
9054     if (!A->ops->ishermitian) {
9055       MatType mattype;
9056       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9057       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
9058     }
9059     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
9060     if (!tol) {
9061       ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr);
9062     }
9063   } else if (A->hermitian) {
9064     *flg = PETSC_TRUE;
9065   } else if (!tol) {
9066     *flg = PETSC_FALSE;
9067   } else {
9068     if (!A->ops->ishermitian) {
9069       MatType mattype;
9070       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9071       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype);
9072     }
9073     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
9074   }
9075   PetscFunctionReturn(0);
9076 }
9077 
9078 /*@
9079    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
9080 
9081    Not Collective
9082 
9083    Input Parameter:
9084 .  A - the matrix to check
9085 
9086    Output Parameters:
9087 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
9088 -  flg - the result
9089 
9090    Level: advanced
9091 
9092    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
9093          if you want it explicitly checked
9094 
9095 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
9096 @*/
9097 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
9098 {
9099   PetscFunctionBegin;
9100   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9101   PetscValidPointer(set,2);
9102   PetscValidBoolPointer(flg,3);
9103   if (A->symmetric_set) {
9104     *set = PETSC_TRUE;
9105     *flg = A->symmetric;
9106   } else {
9107     *set = PETSC_FALSE;
9108   }
9109   PetscFunctionReturn(0);
9110 }
9111 
9112 /*@
9113    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
9114 
9115    Not Collective
9116 
9117    Input Parameter:
9118 .  A - the matrix to check
9119 
9120    Output Parameters:
9121 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
9122 -  flg - the result
9123 
9124    Level: advanced
9125 
9126    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
9127          if you want it explicitly checked
9128 
9129 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
9130 @*/
9131 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
9132 {
9133   PetscFunctionBegin;
9134   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9135   PetscValidPointer(set,2);
9136   PetscValidBoolPointer(flg,3);
9137   if (A->hermitian_set) {
9138     *set = PETSC_TRUE;
9139     *flg = A->hermitian;
9140   } else {
9141     *set = PETSC_FALSE;
9142   }
9143   PetscFunctionReturn(0);
9144 }
9145 
9146 /*@
9147    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
9148 
9149    Collective on Mat
9150 
9151    Input Parameter:
9152 .  A - the matrix to test
9153 
9154    Output Parameters:
9155 .  flg - the result
9156 
9157    Level: intermediate
9158 
9159 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
9160 @*/
9161 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
9162 {
9163   PetscErrorCode ierr;
9164 
9165   PetscFunctionBegin;
9166   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9167   PetscValidBoolPointer(flg,2);
9168   if (!A->structurally_symmetric_set) {
9169     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);
9170     ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr);
9171     ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr);
9172   } else *flg = A->structurally_symmetric;
9173   PetscFunctionReturn(0);
9174 }
9175 
9176 /*@
9177    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
9178        to be communicated to other processors during the MatAssemblyBegin/End() process
9179 
9180     Not collective
9181 
9182    Input Parameter:
9183 .   vec - the vector
9184 
9185    Output Parameters:
9186 +   nstash   - the size of the stash
9187 .   reallocs - the number of additional mallocs incurred.
9188 .   bnstash   - the size of the block stash
9189 -   breallocs - the number of additional mallocs incurred.in the block stash
9190 
9191    Level: advanced
9192 
9193 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
9194 
9195 @*/
9196 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
9197 {
9198   PetscErrorCode ierr;
9199 
9200   PetscFunctionBegin;
9201   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
9202   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
9203   PetscFunctionReturn(0);
9204 }
9205 
9206 /*@C
9207    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
9208      parallel layout
9209 
9210    Collective on Mat
9211 
9212    Input Parameter:
9213 .  mat - the matrix
9214 
9215    Output Parameter:
9216 +   right - (optional) vector that the matrix can be multiplied against
9217 -   left - (optional) vector that the matrix vector product can be stored in
9218 
9219    Notes:
9220     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().
9221 
9222   Notes:
9223     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
9224 
9225   Level: advanced
9226 
9227 .seealso: MatCreate(), VecDestroy()
9228 @*/
9229 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
9230 {
9231   PetscErrorCode ierr;
9232 
9233   PetscFunctionBegin;
9234   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9235   PetscValidType(mat,1);
9236   if (mat->ops->getvecs) {
9237     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
9238   } else {
9239     PetscInt rbs,cbs;
9240     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
9241     if (right) {
9242       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
9243       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
9244       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9245       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
9246       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
9247       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
9248     }
9249     if (left) {
9250       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9251       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
9252       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9253       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9254       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9255       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9256     }
9257   }
9258   PetscFunctionReturn(0);
9259 }
9260 
9261 /*@C
9262    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9263      with default values.
9264 
9265    Not Collective
9266 
9267    Input Parameters:
9268 .    info - the MatFactorInfo data structure
9269 
9270 
9271    Notes:
9272     The solvers are generally used through the KSP and PC objects, for example
9273           PCLU, PCILU, PCCHOLESKY, PCICC
9274 
9275    Level: developer
9276 
9277 .seealso: MatFactorInfo
9278 
9279     Developer Note: fortran interface is not autogenerated as the f90
9280     interface defintion cannot be generated correctly [due to MatFactorInfo]
9281 
9282 @*/
9283 
9284 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9285 {
9286   PetscErrorCode ierr;
9287 
9288   PetscFunctionBegin;
9289   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9290   PetscFunctionReturn(0);
9291 }
9292 
9293 /*@
9294    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9295 
9296    Collective on Mat
9297 
9298    Input Parameters:
9299 +  mat - the factored matrix
9300 -  is - the index set defining the Schur indices (0-based)
9301 
9302    Notes:
9303     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9304 
9305    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9306 
9307    Level: developer
9308 
9309 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9310           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9311 
9312 @*/
9313 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9314 {
9315   PetscErrorCode ierr,(*f)(Mat,IS);
9316 
9317   PetscFunctionBegin;
9318   PetscValidType(mat,1);
9319   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9320   PetscValidType(is,2);
9321   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9322   PetscCheckSameComm(mat,1,is,2);
9323   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9324   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9325   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");
9326   ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9327   ierr = (*f)(mat,is);CHKERRQ(ierr);
9328   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9329   PetscFunctionReturn(0);
9330 }
9331 
9332 /*@
9333   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9334 
9335    Logically Collective on Mat
9336 
9337    Input Parameters:
9338 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9339 .  S - location where to return the Schur complement, can be NULL
9340 -  status - the status of the Schur complement matrix, can be NULL
9341 
9342    Notes:
9343    You must call MatFactorSetSchurIS() before calling this routine.
9344 
9345    The routine provides a copy of the Schur matrix stored within the solver data structures.
9346    The caller must destroy the object when it is no longer needed.
9347    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9348 
9349    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)
9350 
9351    Developer Notes:
9352     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9353    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9354 
9355    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9356 
9357    Level: advanced
9358 
9359    References:
9360 
9361 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9362 @*/
9363 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9364 {
9365   PetscErrorCode ierr;
9366 
9367   PetscFunctionBegin;
9368   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9369   if (S) PetscValidPointer(S,2);
9370   if (status) PetscValidPointer(status,3);
9371   if (S) {
9372     PetscErrorCode (*f)(Mat,Mat*);
9373 
9374     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9375     if (f) {
9376       ierr = (*f)(F,S);CHKERRQ(ierr);
9377     } else {
9378       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9379     }
9380   }
9381   if (status) *status = F->schur_status;
9382   PetscFunctionReturn(0);
9383 }
9384 
9385 /*@
9386   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9387 
9388    Logically Collective on Mat
9389 
9390    Input Parameters:
9391 +  F - the factored matrix obtained by calling MatGetFactor()
9392 .  *S - location where to return the Schur complement, can be NULL
9393 -  status - the status of the Schur complement matrix, can be NULL
9394 
9395    Notes:
9396    You must call MatFactorSetSchurIS() before calling this routine.
9397 
9398    Schur complement mode is currently implemented for sequential matrices.
9399    The routine returns a the Schur Complement stored within the data strutures of the solver.
9400    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9401    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9402 
9403    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9404 
9405    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9406 
9407    Level: advanced
9408 
9409    References:
9410 
9411 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9412 @*/
9413 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9414 {
9415   PetscFunctionBegin;
9416   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9417   if (S) PetscValidPointer(S,2);
9418   if (status) PetscValidPointer(status,3);
9419   if (S) *S = F->schur;
9420   if (status) *status = F->schur_status;
9421   PetscFunctionReturn(0);
9422 }
9423 
9424 /*@
9425   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9426 
9427    Logically Collective on Mat
9428 
9429    Input Parameters:
9430 +  F - the factored matrix obtained by calling MatGetFactor()
9431 .  *S - location where the Schur complement is stored
9432 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9433 
9434    Notes:
9435 
9436    Level: advanced
9437 
9438    References:
9439 
9440 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9441 @*/
9442 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9443 {
9444   PetscErrorCode ierr;
9445 
9446   PetscFunctionBegin;
9447   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9448   if (S) {
9449     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9450     *S = NULL;
9451   }
9452   F->schur_status = status;
9453   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9454   PetscFunctionReturn(0);
9455 }
9456 
9457 /*@
9458   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9459 
9460    Logically Collective on Mat
9461 
9462    Input Parameters:
9463 +  F - the factored matrix obtained by calling MatGetFactor()
9464 .  rhs - location where the right hand side of the Schur complement system is stored
9465 -  sol - location where the solution of the Schur complement system has to be returned
9466 
9467    Notes:
9468    The sizes of the vectors should match the size of the Schur complement
9469 
9470    Must be called after MatFactorSetSchurIS()
9471 
9472    Level: advanced
9473 
9474    References:
9475 
9476 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9477 @*/
9478 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9479 {
9480   PetscErrorCode ierr;
9481 
9482   PetscFunctionBegin;
9483   PetscValidType(F,1);
9484   PetscValidType(rhs,2);
9485   PetscValidType(sol,3);
9486   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9487   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9488   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9489   PetscCheckSameComm(F,1,rhs,2);
9490   PetscCheckSameComm(F,1,sol,3);
9491   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9492   switch (F->schur_status) {
9493   case MAT_FACTOR_SCHUR_FACTORED:
9494     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9495     break;
9496   case MAT_FACTOR_SCHUR_INVERTED:
9497     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9498     break;
9499   default:
9500     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9501   }
9502   PetscFunctionReturn(0);
9503 }
9504 
9505 /*@
9506   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9507 
9508    Logically Collective on Mat
9509 
9510    Input Parameters:
9511 +  F - the factored matrix obtained by calling MatGetFactor()
9512 .  rhs - location where the right hand side of the Schur complement system is stored
9513 -  sol - location where the solution of the Schur complement system has to be returned
9514 
9515    Notes:
9516    The sizes of the vectors should match the size of the Schur complement
9517 
9518    Must be called after MatFactorSetSchurIS()
9519 
9520    Level: advanced
9521 
9522    References:
9523 
9524 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9525 @*/
9526 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9527 {
9528   PetscErrorCode ierr;
9529 
9530   PetscFunctionBegin;
9531   PetscValidType(F,1);
9532   PetscValidType(rhs,2);
9533   PetscValidType(sol,3);
9534   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9535   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9536   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9537   PetscCheckSameComm(F,1,rhs,2);
9538   PetscCheckSameComm(F,1,sol,3);
9539   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9540   switch (F->schur_status) {
9541   case MAT_FACTOR_SCHUR_FACTORED:
9542     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9543     break;
9544   case MAT_FACTOR_SCHUR_INVERTED:
9545     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9546     break;
9547   default:
9548     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9549   }
9550   PetscFunctionReturn(0);
9551 }
9552 
9553 /*@
9554   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9555 
9556    Logically Collective on Mat
9557 
9558    Input Parameters:
9559 .  F - the factored matrix obtained by calling MatGetFactor()
9560 
9561    Notes:
9562     Must be called after MatFactorSetSchurIS().
9563 
9564    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9565 
9566    Level: advanced
9567 
9568    References:
9569 
9570 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9571 @*/
9572 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9573 {
9574   PetscErrorCode ierr;
9575 
9576   PetscFunctionBegin;
9577   PetscValidType(F,1);
9578   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9579   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9580   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9581   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9582   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9583   PetscFunctionReturn(0);
9584 }
9585 
9586 /*@
9587   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9588 
9589    Logically Collective on Mat
9590 
9591    Input Parameters:
9592 .  F - the factored matrix obtained by calling MatGetFactor()
9593 
9594    Notes:
9595     Must be called after MatFactorSetSchurIS().
9596 
9597    Level: advanced
9598 
9599    References:
9600 
9601 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9602 @*/
9603 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9604 {
9605   PetscErrorCode ierr;
9606 
9607   PetscFunctionBegin;
9608   PetscValidType(F,1);
9609   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9610   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9611   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9612   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9613   PetscFunctionReturn(0);
9614 }
9615 
9616 /*@
9617    MatPtAP - Creates the matrix product C = P^T * A * P
9618 
9619    Neighbor-wise Collective on Mat
9620 
9621    Input Parameters:
9622 +  A - the matrix
9623 .  P - the projection matrix
9624 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9625 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9626           if the result is a dense matrix this is irrelevent
9627 
9628    Output Parameters:
9629 .  C - the product matrix
9630 
9631    Notes:
9632    C will be created and must be destroyed by the user with MatDestroy().
9633 
9634    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9635 
9636    Level: intermediate
9637 
9638 .seealso: MatMatMult(), MatRARt()
9639 @*/
9640 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9641 {
9642   PetscErrorCode ierr;
9643 
9644   PetscFunctionBegin;
9645   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9646   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9647 
9648   if (scall == MAT_INITIAL_MATRIX) {
9649     ierr = MatProductCreate(A,P,NULL,C);CHKERRQ(ierr);
9650     ierr = MatProductSetType(*C,MATPRODUCT_PtAP);CHKERRQ(ierr);
9651     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9652     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9653 
9654     (*C)->product->api_user = PETSC_TRUE;
9655     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9656     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);
9657     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9658   } else { /* scall == MAT_REUSE_MATRIX */
9659     ierr = MatProductReplaceMats(A,P,NULL,*C);CHKERRQ(ierr);
9660   }
9661 
9662   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9663   if (A->symmetric_set && A->symmetric) {
9664     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9665   }
9666   PetscFunctionReturn(0);
9667 }
9668 
9669 /*@
9670    MatRARt - Creates the matrix product C = R * A * R^T
9671 
9672    Neighbor-wise Collective on Mat
9673 
9674    Input Parameters:
9675 +  A - the matrix
9676 .  R - the projection matrix
9677 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9678 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9679           if the result is a dense matrix this is irrelevent
9680 
9681    Output Parameters:
9682 .  C - the product matrix
9683 
9684    Notes:
9685    C will be created and must be destroyed by the user with MatDestroy().
9686 
9687    This routine is currently only implemented for pairs of AIJ matrices and classes
9688    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9689    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9690    We recommend using MatPtAP().
9691 
9692    Level: intermediate
9693 
9694 .seealso: MatMatMult(), MatPtAP()
9695 @*/
9696 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9697 {
9698   PetscErrorCode ierr;
9699 
9700   PetscFunctionBegin;
9701   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5);
9702   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9703 
9704   if (scall == MAT_INITIAL_MATRIX) {
9705     ierr = MatProductCreate(A,R,NULL,C);CHKERRQ(ierr);
9706     ierr = MatProductSetType(*C,MATPRODUCT_RARt);CHKERRQ(ierr);
9707     ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr);
9708     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9709 
9710     (*C)->product->api_user = PETSC_TRUE;
9711     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9712     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);
9713     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9714   } else { /* scall == MAT_REUSE_MATRIX */
9715     ierr = MatProductReplaceMats(A,R,NULL,*C);CHKERRQ(ierr);
9716   }
9717 
9718   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9719   if (A->symmetric_set && A->symmetric) {
9720     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9721   }
9722   PetscFunctionReturn(0);
9723 }
9724 
9725 
9726 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C)
9727 {
9728   PetscErrorCode ierr;
9729 
9730   PetscFunctionBegin;
9731   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9732 
9733   if (scall == MAT_INITIAL_MATRIX) {
9734     ierr = PetscInfo1(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype]);CHKERRQ(ierr);
9735     ierr = MatProductCreate(A,B,NULL,C);CHKERRQ(ierr);
9736     ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9737     ierr = MatProductSetAlgorithm(*C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
9738     ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr);
9739 
9740     (*C)->product->api_user = PETSC_TRUE;
9741     ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9742     ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9743   } else { /* scall == MAT_REUSE_MATRIX */
9744     Mat_Product *product = (*C)->product;
9745 
9746     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);
9747     if (!product) {
9748       /* user provide the dense matrix *C without calling MatProductCreate() */
9749       PetscBool isdense;
9750 
9751       ierr = PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr);
9752       if (isdense) {
9753         /* user wants to reuse an assembled dense matrix */
9754         /* Create product -- see MatCreateProduct() */
9755         ierr = MatProductCreate_Private(A,B,NULL,*C);CHKERRQ(ierr);
9756         product = (*C)->product;
9757         product->fill     = fill;
9758         product->api_user = PETSC_TRUE;
9759         product->clear    = PETSC_TRUE;
9760 
9761         ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr);
9762         ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr);
9763         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);
9764         ierr = MatProductSymbolic(*C);CHKERRQ(ierr);
9765       } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first");
9766     } else { /* user may change input matrices A or B when REUSE */
9767       ierr = MatProductReplaceMats(A,B,NULL,*C);CHKERRQ(ierr);
9768     }
9769   }
9770   ierr = MatProductNumeric(*C);CHKERRQ(ierr);
9771   PetscFunctionReturn(0);
9772 }
9773 
9774 /*@
9775    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9776 
9777    Neighbor-wise Collective on Mat
9778 
9779    Input Parameters:
9780 +  A - the left matrix
9781 .  B - the right matrix
9782 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9783 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9784           if the result is a dense matrix this is irrelevent
9785 
9786    Output Parameters:
9787 .  C - the product matrix
9788 
9789    Notes:
9790    Unless scall is MAT_REUSE_MATRIX C will be created.
9791 
9792    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
9793    call to this function with MAT_INITIAL_MATRIX.
9794 
9795    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed.
9796 
9797    If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic(C)/ReplaceMats(), and call MatProductNumeric() repeatedly.
9798 
9799    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.
9800 
9801    Level: intermediate
9802 
9803 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9804 @*/
9805 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9806 {
9807   PetscErrorCode ierr;
9808 
9809   PetscFunctionBegin;
9810   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C);CHKERRQ(ierr);
9811   PetscFunctionReturn(0);
9812 }
9813 
9814 /*@
9815    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9816 
9817    Neighbor-wise Collective on Mat
9818 
9819    Input Parameters:
9820 +  A - the left matrix
9821 .  B - the right matrix
9822 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9823 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9824 
9825    Output Parameters:
9826 .  C - the product matrix
9827 
9828    Notes:
9829    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9830 
9831    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9832 
9833   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9834    actually needed.
9835 
9836    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9837    and for pairs of MPIDense matrices.
9838 
9839    Options Database Keys:
9840 .  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9841                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9842                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9843 
9844    Level: intermediate
9845 
9846 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP()
9847 @*/
9848 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9849 {
9850   PetscErrorCode ierr;
9851 
9852   PetscFunctionBegin;
9853   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C);CHKERRQ(ierr);
9854   PetscFunctionReturn(0);
9855 }
9856 
9857 /*@
9858    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9859 
9860    Neighbor-wise Collective on Mat
9861 
9862    Input Parameters:
9863 +  A - the left matrix
9864 .  B - the right matrix
9865 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9866 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9867 
9868    Output Parameters:
9869 .  C - the product matrix
9870 
9871    Notes:
9872    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9873 
9874    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call.
9875 
9876   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9877    actually needed.
9878 
9879    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9880    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9881 
9882    Level: intermediate
9883 
9884 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP()
9885 @*/
9886 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9887 {
9888   PetscErrorCode ierr;
9889 
9890   PetscFunctionBegin;
9891   ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C);CHKERRQ(ierr);
9892   PetscFunctionReturn(0);
9893 }
9894 
9895 /*@
9896    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9897 
9898    Neighbor-wise Collective on Mat
9899 
9900    Input Parameters:
9901 +  A - the left matrix
9902 .  B - the middle matrix
9903 .  C - the right matrix
9904 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9905 -  fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
9906           if the result is a dense matrix this is irrelevent
9907 
9908    Output Parameters:
9909 .  D - the product matrix
9910 
9911    Notes:
9912    Unless scall is MAT_REUSE_MATRIX D will be created.
9913 
9914    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9915 
9916    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9917    actually needed.
9918 
9919    If you have many matrices with the same non-zero structure to multiply, you
9920    should use MAT_REUSE_MATRIX in all calls but the first or
9921 
9922    Level: intermediate
9923 
9924 .seealso: MatMatMult, MatPtAP()
9925 @*/
9926 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9927 {
9928   PetscErrorCode ierr;
9929 
9930   PetscFunctionBegin;
9931   if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6);
9932   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9933 
9934   if (scall == MAT_INITIAL_MATRIX) {
9935     ierr = MatProductCreate(A,B,C,D);CHKERRQ(ierr);
9936     ierr = MatProductSetType(*D,MATPRODUCT_ABC);CHKERRQ(ierr);
9937     ierr = MatProductSetAlgorithm(*D,"default");CHKERRQ(ierr);
9938     ierr = MatProductSetFill(*D,fill);CHKERRQ(ierr);
9939 
9940     (*D)->product->api_user = PETSC_TRUE;
9941     ierr = MatProductSetFromOptions(*D);CHKERRQ(ierr);
9942     if (!(*D)->ops->productsymbolic) SETERRQ4(PetscObjectComm((PetscObject)(*D)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s, B %s and C %s",MatProductTypes[MATPRODUCT_ABC],((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
9943     ierr = MatProductSymbolic(*D);CHKERRQ(ierr);
9944   } else { /* user may change input matrices when REUSE */
9945     ierr = MatProductReplaceMats(A,B,C,*D);CHKERRQ(ierr);
9946   }
9947   ierr = MatProductNumeric(*D);CHKERRQ(ierr);
9948   PetscFunctionReturn(0);
9949 }
9950 
9951 /*@
9952    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9953 
9954    Collective on Mat
9955 
9956    Input Parameters:
9957 +  mat - the matrix
9958 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9959 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9960 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9961 
9962    Output Parameter:
9963 .  matredundant - redundant matrix
9964 
9965    Notes:
9966    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9967    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9968 
9969    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9970    calling it.
9971 
9972    Level: advanced
9973 
9974 
9975 .seealso: MatDestroy()
9976 @*/
9977 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9978 {
9979   PetscErrorCode ierr;
9980   MPI_Comm       comm;
9981   PetscMPIInt    size;
9982   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9983   Mat_Redundant  *redund=NULL;
9984   PetscSubcomm   psubcomm=NULL;
9985   MPI_Comm       subcomm_in=subcomm;
9986   Mat            *matseq;
9987   IS             isrow,iscol;
9988   PetscBool      newsubcomm=PETSC_FALSE;
9989 
9990   PetscFunctionBegin;
9991   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9992   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9993     PetscValidPointer(*matredundant,5);
9994     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9995   }
9996 
9997   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
9998   if (size == 1 || nsubcomm == 1) {
9999     if (reuse == MAT_INITIAL_MATRIX) {
10000       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10001     } else {
10002       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");
10003       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10004     }
10005     PetscFunctionReturn(0);
10006   }
10007 
10008   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10009   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10010   MatCheckPreallocated(mat,1);
10011 
10012   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10013   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10014     /* create psubcomm, then get subcomm */
10015     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10016     ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
10017     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10018 
10019     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10020     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10021     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10022     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10023     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10024     newsubcomm = PETSC_TRUE;
10025     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10026   }
10027 
10028   /* get isrow, iscol and a local sequential matrix matseq[0] */
10029   if (reuse == MAT_INITIAL_MATRIX) {
10030     mloc_sub = PETSC_DECIDE;
10031     nloc_sub = PETSC_DECIDE;
10032     if (bs < 1) {
10033       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10034       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10035     } else {
10036       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10037       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10038     }
10039     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRMPI(ierr);
10040     rstart = rend - mloc_sub;
10041     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10042     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10043   } else { /* reuse == MAT_REUSE_MATRIX */
10044     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");
10045     /* retrieve subcomm */
10046     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10047     redund = (*matredundant)->redundant;
10048     isrow  = redund->isrow;
10049     iscol  = redund->iscol;
10050     matseq = redund->matseq;
10051   }
10052   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10053 
10054   /* get matredundant over subcomm */
10055   if (reuse == MAT_INITIAL_MATRIX) {
10056     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10057 
10058     /* create a supporting struct and attach it to C for reuse */
10059     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10060     (*matredundant)->redundant = redund;
10061     redund->isrow              = isrow;
10062     redund->iscol              = iscol;
10063     redund->matseq             = matseq;
10064     if (newsubcomm) {
10065       redund->subcomm          = subcomm;
10066     } else {
10067       redund->subcomm          = MPI_COMM_NULL;
10068     }
10069   } else {
10070     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10071   }
10072   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10073   PetscFunctionReturn(0);
10074 }
10075 
10076 /*@C
10077    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10078    a given 'mat' object. Each submatrix can span multiple procs.
10079 
10080    Collective on Mat
10081 
10082    Input Parameters:
10083 +  mat - the matrix
10084 .  subcomm - the subcommunicator obtained by com_split(comm)
10085 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10086 
10087    Output Parameter:
10088 .  subMat - 'parallel submatrices each spans a given subcomm
10089 
10090   Notes:
10091   The submatrix partition across processors is dictated by 'subComm' a
10092   communicator obtained by com_split(comm). The comm_split
10093   is not restriced to be grouped with consecutive original ranks.
10094 
10095   Due the comm_split() usage, the parallel layout of the submatrices
10096   map directly to the layout of the original matrix [wrt the local
10097   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10098   into the 'DiagonalMat' of the subMat, hence it is used directly from
10099   the subMat. However the offDiagMat looses some columns - and this is
10100   reconstructed with MatSetValues()
10101 
10102   Level: advanced
10103 
10104 
10105 .seealso: MatCreateSubMatrices()
10106 @*/
10107 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10108 {
10109   PetscErrorCode ierr;
10110   PetscMPIInt    commsize,subCommSize;
10111 
10112   PetscFunctionBegin;
10113   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRMPI(ierr);
10114   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRMPI(ierr);
10115   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10116 
10117   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");
10118   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10119   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10120   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10121   PetscFunctionReturn(0);
10122 }
10123 
10124 /*@
10125    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10126 
10127    Not Collective
10128 
10129    Input Arguments:
10130 +  mat - matrix to extract local submatrix from
10131 .  isrow - local row indices for submatrix
10132 -  iscol - local column indices for submatrix
10133 
10134    Output Arguments:
10135 .  submat - the submatrix
10136 
10137    Level: intermediate
10138 
10139    Notes:
10140    The submat should be returned with MatRestoreLocalSubMatrix().
10141 
10142    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10143    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10144 
10145    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10146    MatSetValuesBlockedLocal() will also be implemented.
10147 
10148    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10149    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10150 
10151 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10152 @*/
10153 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10154 {
10155   PetscErrorCode ierr;
10156 
10157   PetscFunctionBegin;
10158   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10159   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10160   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10161   PetscCheckSameComm(isrow,2,iscol,3);
10162   PetscValidPointer(submat,4);
10163   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10164 
10165   if (mat->ops->getlocalsubmatrix) {
10166     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10167   } else {
10168     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10169   }
10170   PetscFunctionReturn(0);
10171 }
10172 
10173 /*@
10174    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10175 
10176    Not Collective
10177 
10178    Input Arguments:
10179    mat - matrix to extract local submatrix from
10180    isrow - local row indices for submatrix
10181    iscol - local column indices for submatrix
10182    submat - the submatrix
10183 
10184    Level: intermediate
10185 
10186 .seealso: MatGetLocalSubMatrix()
10187 @*/
10188 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10189 {
10190   PetscErrorCode ierr;
10191 
10192   PetscFunctionBegin;
10193   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10194   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10195   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10196   PetscCheckSameComm(isrow,2,iscol,3);
10197   PetscValidPointer(submat,4);
10198   if (*submat) {
10199     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10200   }
10201 
10202   if (mat->ops->restorelocalsubmatrix) {
10203     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10204   } else {
10205     ierr = MatDestroy(submat);CHKERRQ(ierr);
10206   }
10207   *submat = NULL;
10208   PetscFunctionReturn(0);
10209 }
10210 
10211 /* --------------------------------------------------------*/
10212 /*@
10213    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10214 
10215    Collective on Mat
10216 
10217    Input Parameter:
10218 .  mat - the matrix
10219 
10220    Output Parameter:
10221 .  is - if any rows have zero diagonals this contains the list of them
10222 
10223    Level: developer
10224 
10225 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10226 @*/
10227 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10228 {
10229   PetscErrorCode ierr;
10230 
10231   PetscFunctionBegin;
10232   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10233   PetscValidType(mat,1);
10234   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10235   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10236 
10237   if (!mat->ops->findzerodiagonals) {
10238     Vec                diag;
10239     const PetscScalar *a;
10240     PetscInt          *rows;
10241     PetscInt           rStart, rEnd, r, nrow = 0;
10242 
10243     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10244     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10245     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10246     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10247     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10248     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10249     nrow = 0;
10250     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10251     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10252     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10253     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10254   } else {
10255     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10256   }
10257   PetscFunctionReturn(0);
10258 }
10259 
10260 /*@
10261    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10262 
10263    Collective on Mat
10264 
10265    Input Parameter:
10266 .  mat - the matrix
10267 
10268    Output Parameter:
10269 .  is - contains the list of rows with off block diagonal entries
10270 
10271    Level: developer
10272 
10273 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10274 @*/
10275 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10276 {
10277   PetscErrorCode ierr;
10278 
10279   PetscFunctionBegin;
10280   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10281   PetscValidType(mat,1);
10282   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10283   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10284 
10285   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);
10286   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10287   PetscFunctionReturn(0);
10288 }
10289 
10290 /*@C
10291   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10292 
10293   Collective on Mat
10294 
10295   Input Parameters:
10296 . mat - the matrix
10297 
10298   Output Parameters:
10299 . values - the block inverses in column major order (FORTRAN-like)
10300 
10301    Note:
10302    This routine is not available from Fortran.
10303 
10304   Level: advanced
10305 
10306 .seealso: MatInvertBockDiagonalMat
10307 @*/
10308 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10309 {
10310   PetscErrorCode ierr;
10311 
10312   PetscFunctionBegin;
10313   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10314   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10315   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10316   if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name);
10317   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10318   PetscFunctionReturn(0);
10319 }
10320 
10321 /*@C
10322   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10323 
10324   Collective on Mat
10325 
10326   Input Parameters:
10327 + mat - the matrix
10328 . nblocks - the number of blocks
10329 - bsizes - the size of each block
10330 
10331   Output Parameters:
10332 . values - the block inverses in column major order (FORTRAN-like)
10333 
10334    Note:
10335    This routine is not available from Fortran.
10336 
10337   Level: advanced
10338 
10339 .seealso: MatInvertBockDiagonal()
10340 @*/
10341 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10342 {
10343   PetscErrorCode ierr;
10344 
10345   PetscFunctionBegin;
10346   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10347   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10348   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10349   if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name);
10350   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10351   PetscFunctionReturn(0);
10352 }
10353 
10354 /*@
10355   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10356 
10357   Collective on Mat
10358 
10359   Input Parameters:
10360 . A - the matrix
10361 
10362   Output Parameters:
10363 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10364 
10365   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10366 
10367   Level: advanced
10368 
10369 .seealso: MatInvertBockDiagonal()
10370 @*/
10371 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10372 {
10373   PetscErrorCode     ierr;
10374   const PetscScalar *vals;
10375   PetscInt          *dnnz;
10376   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10377 
10378   PetscFunctionBegin;
10379   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10380   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10381   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10382   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10383   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10384   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10385   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10386   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10387   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10388   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10389   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10390   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10391   for (i = rstart/bs; i < rend/bs; i++) {
10392     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10393   }
10394   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10395   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10396   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10397   PetscFunctionReturn(0);
10398 }
10399 
10400 /*@C
10401     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10402     via MatTransposeColoringCreate().
10403 
10404     Collective on MatTransposeColoring
10405 
10406     Input Parameter:
10407 .   c - coloring context
10408 
10409     Level: intermediate
10410 
10411 .seealso: MatTransposeColoringCreate()
10412 @*/
10413 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10414 {
10415   PetscErrorCode       ierr;
10416   MatTransposeColoring matcolor=*c;
10417 
10418   PetscFunctionBegin;
10419   if (!matcolor) PetscFunctionReturn(0);
10420   if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);}
10421 
10422   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10423   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10424   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10425   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10426   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10427   if (matcolor->brows>0) {
10428     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10429   }
10430   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10431   PetscFunctionReturn(0);
10432 }
10433 
10434 /*@C
10435     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10436     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10437     MatTransposeColoring to sparse B.
10438 
10439     Collective on MatTransposeColoring
10440 
10441     Input Parameters:
10442 +   B - sparse matrix B
10443 .   Btdense - symbolic dense matrix B^T
10444 -   coloring - coloring context created with MatTransposeColoringCreate()
10445 
10446     Output Parameter:
10447 .   Btdense - dense matrix B^T
10448 
10449     Level: advanced
10450 
10451      Notes:
10452     These are used internally for some implementations of MatRARt()
10453 
10454 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10455 
10456 @*/
10457 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10458 {
10459   PetscErrorCode ierr;
10460 
10461   PetscFunctionBegin;
10462   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10463   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10464   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10465 
10466   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10467   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10468   PetscFunctionReturn(0);
10469 }
10470 
10471 /*@C
10472     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10473     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10474     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10475     Csp from Cden.
10476 
10477     Collective on MatTransposeColoring
10478 
10479     Input Parameters:
10480 +   coloring - coloring context created with MatTransposeColoringCreate()
10481 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10482 
10483     Output Parameter:
10484 .   Csp - sparse matrix
10485 
10486     Level: advanced
10487 
10488      Notes:
10489     These are used internally for some implementations of MatRARt()
10490 
10491 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10492 
10493 @*/
10494 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10495 {
10496   PetscErrorCode ierr;
10497 
10498   PetscFunctionBegin;
10499   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10500   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10501   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10502 
10503   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10504   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10505   ierr = MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10506   ierr = MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10507   PetscFunctionReturn(0);
10508 }
10509 
10510 /*@C
10511    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10512 
10513    Collective on Mat
10514 
10515    Input Parameters:
10516 +  mat - the matrix product C
10517 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10518 
10519     Output Parameter:
10520 .   color - the new coloring context
10521 
10522     Level: intermediate
10523 
10524 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10525            MatTransColoringApplyDenToSp()
10526 @*/
10527 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10528 {
10529   MatTransposeColoring c;
10530   MPI_Comm             comm;
10531   PetscErrorCode       ierr;
10532 
10533   PetscFunctionBegin;
10534   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10535   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10536   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10537 
10538   c->ctype = iscoloring->ctype;
10539   if (mat->ops->transposecoloringcreate) {
10540     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10541   } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name);
10542 
10543   *color = c;
10544   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10545   PetscFunctionReturn(0);
10546 }
10547 
10548 /*@
10549       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10550         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10551         same, otherwise it will be larger
10552 
10553      Not Collective
10554 
10555   Input Parameter:
10556 .    A  - the matrix
10557 
10558   Output Parameter:
10559 .    state - the current state
10560 
10561   Notes:
10562     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10563          different matrices
10564 
10565   Level: intermediate
10566 
10567 @*/
10568 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10569 {
10570   PetscFunctionBegin;
10571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10572   *state = mat->nonzerostate;
10573   PetscFunctionReturn(0);
10574 }
10575 
10576 /*@
10577       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10578                  matrices from each processor
10579 
10580     Collective
10581 
10582    Input Parameters:
10583 +    comm - the communicators the parallel matrix will live on
10584 .    seqmat - the input sequential matrices
10585 .    n - number of local columns (or PETSC_DECIDE)
10586 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10587 
10588    Output Parameter:
10589 .    mpimat - the parallel matrix generated
10590 
10591     Level: advanced
10592 
10593    Notes:
10594     The number of columns of the matrix in EACH processor MUST be the same.
10595 
10596 @*/
10597 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10598 {
10599   PetscErrorCode ierr;
10600 
10601   PetscFunctionBegin;
10602   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10603   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");
10604 
10605   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10606   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10607   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10608   PetscFunctionReturn(0);
10609 }
10610 
10611 /*@
10612      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10613                  ranks' ownership ranges.
10614 
10615     Collective on A
10616 
10617    Input Parameters:
10618 +    A   - the matrix to create subdomains from
10619 -    N   - requested number of subdomains
10620 
10621 
10622    Output Parameters:
10623 +    n   - number of subdomains resulting on this rank
10624 -    iss - IS list with indices of subdomains on this rank
10625 
10626     Level: advanced
10627 
10628     Notes:
10629     number of subdomains must be smaller than the communicator size
10630 @*/
10631 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10632 {
10633   MPI_Comm        comm,subcomm;
10634   PetscMPIInt     size,rank,color;
10635   PetscInt        rstart,rend,k;
10636   PetscErrorCode  ierr;
10637 
10638   PetscFunctionBegin;
10639   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10640   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
10641   ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr);
10642   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);
10643   *n = 1;
10644   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10645   color = rank/k;
10646   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRMPI(ierr);
10647   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10648   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10649   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10650   ierr = MPI_Comm_free(&subcomm);CHKERRMPI(ierr);
10651   PetscFunctionReturn(0);
10652 }
10653 
10654 /*@
10655    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10656 
10657    If the interpolation and restriction operators are the same, uses MatPtAP.
10658    If they are not the same, use MatMatMatMult.
10659 
10660    Once the coarse grid problem is constructed, correct for interpolation operators
10661    that are not of full rank, which can legitimately happen in the case of non-nested
10662    geometric multigrid.
10663 
10664    Input Parameters:
10665 +  restrct - restriction operator
10666 .  dA - fine grid matrix
10667 .  interpolate - interpolation operator
10668 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10669 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10670 
10671    Output Parameters:
10672 .  A - the Galerkin coarse matrix
10673 
10674    Options Database Key:
10675 .  -pc_mg_galerkin <both,pmat,mat,none>
10676 
10677    Level: developer
10678 
10679 .seealso: MatPtAP(), MatMatMatMult()
10680 @*/
10681 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10682 {
10683   PetscErrorCode ierr;
10684   IS             zerorows;
10685   Vec            diag;
10686 
10687   PetscFunctionBegin;
10688   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10689   /* Construct the coarse grid matrix */
10690   if (interpolate == restrct) {
10691     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10692   } else {
10693     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10694   }
10695 
10696   /* If the interpolation matrix is not of full rank, A will have zero rows.
10697      This can legitimately happen in the case of non-nested geometric multigrid.
10698      In that event, we set the rows of the matrix to the rows of the identity,
10699      ignoring the equations (as the RHS will also be zero). */
10700 
10701   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10702 
10703   if (zerorows != NULL) { /* if there are any zero rows */
10704     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10705     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10706     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10707     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10708     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10709     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10710   }
10711   PetscFunctionReturn(0);
10712 }
10713 
10714 /*@C
10715     MatSetOperation - Allows user to set a matrix operation for any matrix type
10716 
10717    Logically Collective on Mat
10718 
10719     Input Parameters:
10720 +   mat - the matrix
10721 .   op - the name of the operation
10722 -   f - the function that provides the operation
10723 
10724    Level: developer
10725 
10726     Usage:
10727 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10728 $      ierr = MatCreateXXX(comm,...&A);
10729 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10730 
10731     Notes:
10732     See the file include/petscmat.h for a complete list of matrix
10733     operations, which all have the form MATOP_<OPERATION>, where
10734     <OPERATION> is the name (in all capital letters) of the
10735     user interface routine (e.g., MatMult() -> MATOP_MULT).
10736 
10737     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10738     sequence as the usual matrix interface routines, since they
10739     are intended to be accessed via the usual matrix interface
10740     routines, e.g.,
10741 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10742 
10743     In particular each function MUST return an error code of 0 on success and
10744     nonzero on failure.
10745 
10746     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10747 
10748 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10749 @*/
10750 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10751 {
10752   PetscFunctionBegin;
10753   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10754   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10755     mat->ops->viewnative = mat->ops->view;
10756   }
10757   (((void(**)(void))mat->ops)[op]) = f;
10758   PetscFunctionReturn(0);
10759 }
10760 
10761 /*@C
10762     MatGetOperation - Gets a matrix operation for any matrix type.
10763 
10764     Not Collective
10765 
10766     Input Parameters:
10767 +   mat - the matrix
10768 -   op - the name of the operation
10769 
10770     Output Parameter:
10771 .   f - the function that provides the operation
10772 
10773     Level: developer
10774 
10775     Usage:
10776 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10777 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10778 
10779     Notes:
10780     See the file include/petscmat.h for a complete list of matrix
10781     operations, which all have the form MATOP_<OPERATION>, where
10782     <OPERATION> is the name (in all capital letters) of the
10783     user interface routine (e.g., MatMult() -> MATOP_MULT).
10784 
10785     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
10786 
10787 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
10788 @*/
10789 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
10790 {
10791   PetscFunctionBegin;
10792   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10793   *f = (((void (**)(void))mat->ops)[op]);
10794   PetscFunctionReturn(0);
10795 }
10796 
10797 /*@
10798     MatHasOperation - Determines whether the given matrix supports the particular
10799     operation.
10800 
10801    Not Collective
10802 
10803    Input Parameters:
10804 +  mat - the matrix
10805 -  op - the operation, for example, MATOP_GET_DIAGONAL
10806 
10807    Output Parameter:
10808 .  has - either PETSC_TRUE or PETSC_FALSE
10809 
10810    Level: advanced
10811 
10812    Notes:
10813    See the file include/petscmat.h for a complete list of matrix
10814    operations, which all have the form MATOP_<OPERATION>, where
10815    <OPERATION> is the name (in all capital letters) of the
10816    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
10817 
10818 .seealso: MatCreateShell()
10819 @*/
10820 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
10821 {
10822   PetscErrorCode ierr;
10823 
10824   PetscFunctionBegin;
10825   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10826   /* symbolic product can be set before matrix type */
10827   if (op != MATOP_PRODUCTSYMBOLIC) PetscValidType(mat,1);
10828   PetscValidPointer(has,3);
10829   if (mat->ops->hasoperation) {
10830     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
10831   } else {
10832     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
10833     else {
10834       *has = PETSC_FALSE;
10835       if (op == MATOP_CREATE_SUBMATRIX) {
10836         PetscMPIInt size;
10837 
10838         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr);
10839         if (size == 1) {
10840           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
10841         }
10842       }
10843     }
10844   }
10845   PetscFunctionReturn(0);
10846 }
10847 
10848 /*@
10849     MatHasCongruentLayouts - Determines whether the rows and columns layouts
10850     of the matrix are congruent
10851 
10852    Collective on mat
10853 
10854    Input Parameters:
10855 .  mat - the matrix
10856 
10857    Output Parameter:
10858 .  cong - either PETSC_TRUE or PETSC_FALSE
10859 
10860    Level: beginner
10861 
10862    Notes:
10863 
10864 .seealso: MatCreate(), MatSetSizes()
10865 @*/
10866 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
10867 {
10868   PetscErrorCode ierr;
10869 
10870   PetscFunctionBegin;
10871   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10872   PetscValidType(mat,1);
10873   PetscValidPointer(cong,2);
10874   if (!mat->rmap || !mat->cmap) {
10875     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
10876     PetscFunctionReturn(0);
10877   }
10878   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
10879     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
10880     if (*cong) mat->congruentlayouts = 1;
10881     else       mat->congruentlayouts = 0;
10882   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
10883   PetscFunctionReturn(0);
10884 }
10885 
10886 PetscErrorCode MatSetInf(Mat A)
10887 {
10888   PetscErrorCode ierr;
10889 
10890   PetscFunctionBegin;
10891   if (!A->ops->setinf) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type");
10892   ierr = (*A->ops->setinf)(A);CHKERRQ(ierr);
10893   PetscFunctionReturn(0);
10894 }
10895