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