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