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