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