xref: /petsc/src/mat/interface/matrix.c (revision a8d69d7b0124b1e6ce75950a93e6ff079980e86f)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    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
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   MatCheckPreallocated(mat,1);
694   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   PetscValidType(mat,1);
722   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
723   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
724   MatCheckPreallocated(mat,1);
725   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
726   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
727   PetscFunctionReturn(0);
728 }
729 
730 /*@C
731    MatSetOptionsPrefix - Sets the prefix used for searching for all
732    Mat options in the database.
733 
734    Logically Collective on Mat
735 
736    Input Parameter:
737 +  A - the Mat context
738 -  prefix - the prefix to prepend to all option names
739 
740    Notes:
741    A hyphen (-) must NOT be given at the beginning of the prefix name.
742    The first character of all runtime options is AUTOMATICALLY the hyphen.
743 
744    Level: advanced
745 
746 .keywords: Mat, set, options, prefix, database
747 
748 .seealso: MatSetFromOptions()
749 @*/
750 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
751 {
752   PetscErrorCode ierr;
753 
754   PetscFunctionBegin;
755   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
756   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
757   PetscFunctionReturn(0);
758 }
759 
760 /*@C
761    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
762    Mat options in the database.
763 
764    Logically Collective on Mat
765 
766    Input Parameters:
767 +  A - the Mat context
768 -  prefix - the prefix to prepend to all option names
769 
770    Notes:
771    A hyphen (-) must NOT be given at the beginning of the prefix name.
772    The first character of all runtime options is AUTOMATICALLY the hyphen.
773 
774    Level: advanced
775 
776 .keywords: Mat, append, options, prefix, database
777 
778 .seealso: MatGetOptionsPrefix()
779 @*/
780 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
781 {
782   PetscErrorCode ierr;
783 
784   PetscFunctionBegin;
785   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
786   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
787   PetscFunctionReturn(0);
788 }
789 
790 /*@C
791    MatGetOptionsPrefix - Sets the prefix used for searching for all
792    Mat options in the database.
793 
794    Not Collective
795 
796    Input Parameter:
797 .  A - the Mat context
798 
799    Output Parameter:
800 .  prefix - pointer to the prefix string used
801 
802    Notes:
803     On the fortran side, the user should pass in a string 'prefix' of
804    sufficient length to hold the prefix.
805 
806    Level: advanced
807 
808 .keywords: Mat, get, options, prefix, database
809 
810 .seealso: MatAppendOptionsPrefix()
811 @*/
812 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
813 {
814   PetscErrorCode ierr;
815 
816   PetscFunctionBegin;
817   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
818   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
819   PetscFunctionReturn(0);
820 }
821 
822 /*@
823    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
824 
825    Collective on Mat
826 
827    Input Parameters:
828 .  A - the Mat context
829 
830    Notes:
831    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
832    Currently support MPIAIJ and SEQAIJ.
833 
834    Level: beginner
835 
836 .keywords: Mat, ResetPreallocation
837 
838 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
839 @*/
840 PetscErrorCode MatResetPreallocation(Mat A)
841 {
842   PetscErrorCode ierr;
843 
844   PetscFunctionBegin;
845   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
846   PetscValidType(A,1);
847   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
848   PetscFunctionReturn(0);
849 }
850 
851 
852 /*@
853    MatSetUp - Sets up the internal matrix data structures for the later use.
854 
855    Collective on Mat
856 
857    Input Parameters:
858 .  A - the Mat context
859 
860    Notes:
861    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
862 
863    If a suitable preallocation routine is used, this function does not need to be called.
864 
865    See the Performance chapter of the PETSc users manual for how to preallocate matrices
866 
867    Level: beginner
868 
869 .keywords: Mat, setup
870 
871 .seealso: MatCreate(), MatDestroy()
872 @*/
873 PetscErrorCode MatSetUp(Mat A)
874 {
875   PetscMPIInt    size;
876   PetscErrorCode ierr;
877 
878   PetscFunctionBegin;
879   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
880   if (!((PetscObject)A)->type_name) {
881     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
882     if (size == 1) {
883       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
884     } else {
885       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
886     }
887   }
888   if (!A->preallocated && A->ops->setup) {
889     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
890     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
891   }
892   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
893   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
894   A->preallocated = PETSC_TRUE;
895   PetscFunctionReturn(0);
896 }
897 
898 #if defined(PETSC_HAVE_SAWS)
899 #include <petscviewersaws.h>
900 #endif
901 /*@C
902    MatView - Visualizes a matrix object.
903 
904    Collective on Mat
905 
906    Input Parameters:
907 +  mat - the matrix
908 -  viewer - visualization context
909 
910   Notes:
911   The available visualization contexts include
912 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
913 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
914 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
915 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
916 
917    The user can open alternative visualization contexts with
918 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
919 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
920          specified file; corresponding input uses MatLoad()
921 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
922          an X window display
923 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
924          Currently only the sequential dense and AIJ
925          matrix types support the Socket viewer.
926 
927    The user can call PetscViewerPushFormat() to specify the output
928    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
929    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
930 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
931 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
932 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
933 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
934          format common among all matrix types
935 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
936          format (which is in many cases the same as the default)
937 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
938          size and structure (not the matrix entries)
939 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
940          the matrix structure
941 
942    Options Database Keys:
943 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
944 .  -mat_view ::ascii_info_detail - Prints more detailed info
945 .  -mat_view - Prints matrix in ASCII format
946 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
947 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
948 .  -display <name> - Sets display name (default is host)
949 .  -draw_pause <sec> - Sets number of seconds to pause after display
950 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
951 .  -viewer_socket_machine <machine> -
952 .  -viewer_socket_port <port> -
953 .  -mat_view binary - save matrix to file in binary format
954 -  -viewer_binary_filename <name> -
955    Level: beginner
956 
957    Notes:
958     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
959     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
960 
961     See the manual page for MatLoad() for the exact format of the binary file when the binary
962       viewer is used.
963 
964       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
965       viewer is used.
966 
967       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
968       and then use the following mouse functions.
969 + left mouse: zoom in
970 . middle mouse: zoom out
971 - right mouse: continue with the simulation
972 
973    Concepts: matrices^viewing
974    Concepts: matrices^plotting
975    Concepts: matrices^printing
976 
977 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
978           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
979 @*/
980 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
981 {
982   PetscErrorCode    ierr;
983   PetscInt          rows,cols,rbs,cbs;
984   PetscBool         iascii,ibinary,isstring;
985   PetscViewerFormat format;
986   PetscMPIInt       size;
987 #if defined(PETSC_HAVE_SAWS)
988   PetscBool         issaws;
989 #endif
990 
991   PetscFunctionBegin;
992   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
993   PetscValidType(mat,1);
994   if (!viewer) {
995     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
996   }
997   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
998   PetscCheckSameComm(mat,1,viewer,2);
999   MatCheckPreallocated(mat,1);
1000   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1001   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
1002   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
1003   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1004   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1005   if (ibinary) {
1006     PetscBool mpiio;
1007     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1008     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1009   }
1010 
1011   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1012   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1013   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1014     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1015   }
1016 
1017 #if defined(PETSC_HAVE_SAWS)
1018   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1019 #endif
1020   if (iascii) {
1021     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1022     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1023     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1024       MatNullSpace nullsp,transnullsp;
1025 
1026       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1027       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1028       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1029       if (rbs != 1 || cbs != 1) {
1030         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1031         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1032       } else {
1033         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1034       }
1035       if (mat->factortype) {
1036         MatSolverType solver;
1037         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1038         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1039       }
1040       if (mat->ops->getinfo) {
1041         MatInfo info;
1042         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1043         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1044         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1045       }
1046       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1047       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1048       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1049       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1050       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1051       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1052     }
1053 #if defined(PETSC_HAVE_SAWS)
1054   } else if (issaws) {
1055     PetscMPIInt rank;
1056 
1057     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1058     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1059     if (!((PetscObject)mat)->amsmem && !rank) {
1060       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1061     }
1062 #endif
1063   } else if (isstring) {
1064     const char *type;
1065     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1066     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1067     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1068   }
1069   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1070     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1071     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1072     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1073   } else if (mat->ops->view) {
1074     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1075     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1076     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1077   }
1078   if (iascii) {
1079     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1080     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1081       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1082     }
1083   }
1084   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1085   PetscFunctionReturn(0);
1086 }
1087 
1088 #if defined(PETSC_USE_DEBUG)
1089 #include <../src/sys/totalview/tv_data_display.h>
1090 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1091 {
1092   TV_add_row("Local rows", "int", &mat->rmap->n);
1093   TV_add_row("Local columns", "int", &mat->cmap->n);
1094   TV_add_row("Global rows", "int", &mat->rmap->N);
1095   TV_add_row("Global columns", "int", &mat->cmap->N);
1096   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1097   return TV_format_OK;
1098 }
1099 #endif
1100 
1101 /*@C
1102    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1103    with MatView().  The matrix format is determined from the options database.
1104    Generates a parallel MPI matrix if the communicator has more than one
1105    processor.  The default matrix type is AIJ.
1106 
1107    Collective on PetscViewer
1108 
1109    Input Parameters:
1110 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1111             or some related function before a call to MatLoad()
1112 -  viewer - binary/HDF5 file viewer
1113 
1114    Options Database Keys:
1115    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1116    block size
1117 .    -matload_block_size <bs>
1118 
1119    Level: beginner
1120 
1121    Notes:
1122    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1123    Mat before calling this routine if you wish to set it from the options database.
1124 
1125    MatLoad() automatically loads into the options database any options
1126    given in the file filename.info where filename is the name of the file
1127    that was passed to the PetscViewerBinaryOpen(). The options in the info
1128    file will be ignored if you use the -viewer_binary_skip_info option.
1129 
1130    If the type or size of newmat is not set before a call to MatLoad, PETSc
1131    sets the default matrix type AIJ and sets the local and global sizes.
1132    If type and/or size is already set, then the same are used.
1133 
1134    In parallel, each processor can load a subset of rows (or the
1135    entire matrix).  This routine is especially useful when a large
1136    matrix is stored on disk and only part of it is desired on each
1137    processor.  For example, a parallel solver may access only some of
1138    the rows from each processor.  The algorithm used here reads
1139    relatively small blocks of data rather than reading the entire
1140    matrix and then subsetting it.
1141 
1142    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1143    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1144    or the sequence like
1145 $    PetscViewer v;
1146 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1147 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1148 $    PetscViewerSetFromOptions(v);
1149 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1150 $    PetscViewerFileSetName(v,"datafile");
1151    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1152 $ -viewer_type {binary,hdf5}
1153 
1154    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1155    and src/mat/examples/tutorials/ex10.c with the second approach.
1156 
1157    Notes about the PETSc binary format:
1158    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1159    is read onto rank 0 and then shipped to its destination rank, one after another.
1160    Multiple objects, both matrices and vectors, can be stored within the same file.
1161    Their PetscObject name is ignored; they are loaded in the order of their storage.
1162 
1163    Most users should not need to know the details of the binary storage
1164    format, since MatLoad() and MatView() completely hide these details.
1165    But for anyone who's interested, the standard binary matrix storage
1166    format is
1167 
1168 $    int    MAT_FILE_CLASSID
1169 $    int    number of rows
1170 $    int    number of columns
1171 $    int    total number of nonzeros
1172 $    int    *number nonzeros in each row
1173 $    int    *column indices of all nonzeros (starting index is zero)
1174 $    PetscScalar *values of all nonzeros
1175 
1176    PETSc automatically does the byte swapping for
1177 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1178 linux, Windows and the paragon; thus if you write your own binary
1179 read/write routines you have to swap the bytes; see PetscBinaryRead()
1180 and PetscBinaryWrite() to see how this may be done.
1181 
1182    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1183    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1184    Each processor's chunk is loaded independently by its owning rank.
1185    Multiple objects, both matrices and vectors, can be stored within the same file.
1186    They are looked up by their PetscObject name.
1187 
1188    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1189    by default the same structure and naming of the AIJ arrays and column count
1190    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1191 $    save example.mat A b -v7.3
1192    can be directly read by this routine (see Reference 1 for details).
1193    Note that depending on your MATLAB version, this format might be a default,
1194    otherwise you can set it as default in Preferences.
1195 
1196    Unless -nocompression flag is used to save the file in MATLAB,
1197    PETSc must be configured with ZLIB package.
1198 
1199    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1200 
1201    Current HDF5 (MAT-File) limitations:
1202    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1203 
1204    Corresponding MatView() is not yet implemented.
1205 
1206    The loaded matrix is actually a transpose of the original one in MATLAB,
1207    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1208    With this format, matrix is automatically transposed by PETSc,
1209    unless the matrix is marked as SPD or symmetric
1210    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1211 
1212    References:
1213 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1214 
1215 .keywords: matrix, load, binary, input, HDF5
1216 
1217 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1218 
1219  @*/
1220 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1221 {
1222   PetscErrorCode ierr;
1223   PetscBool      flg;
1224 
1225   PetscFunctionBegin;
1226   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1227   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1228 
1229   if (!((PetscObject)newmat)->type_name) {
1230     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1231   }
1232 
1233   flg  = PETSC_FALSE;
1234   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1235   if (flg) {
1236     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1237     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1238   }
1239   flg  = PETSC_FALSE;
1240   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1241   if (flg) {
1242     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1243   }
1244 
1245   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1246   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1247   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1248   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1249   PetscFunctionReturn(0);
1250 }
1251 
1252 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1253 {
1254   PetscErrorCode ierr;
1255   Mat_Redundant  *redund = *redundant;
1256   PetscInt       i;
1257 
1258   PetscFunctionBegin;
1259   if (redund){
1260     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1261       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1262       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1263       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1264     } else {
1265       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1266       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1267       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1268       for (i=0; i<redund->nrecvs; i++) {
1269         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1270         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1271       }
1272       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1273     }
1274 
1275     if (redund->subcomm) {
1276       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1277     }
1278     ierr = PetscFree(redund);CHKERRQ(ierr);
1279   }
1280   PetscFunctionReturn(0);
1281 }
1282 
1283 /*@
1284    MatDestroy - Frees space taken by a matrix.
1285 
1286    Collective on Mat
1287 
1288    Input Parameter:
1289 .  A - the matrix
1290 
1291    Level: beginner
1292 
1293 @*/
1294 PetscErrorCode MatDestroy(Mat *A)
1295 {
1296   PetscErrorCode ierr;
1297 
1298   PetscFunctionBegin;
1299   if (!*A) PetscFunctionReturn(0);
1300   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1301   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1302 
1303   /* if memory was published with SAWs then destroy it */
1304   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1305   if ((*A)->ops->destroy) {
1306     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1307   }
1308 
1309   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1310   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1311   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1312   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1313   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1314   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1315   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1316   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1317   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1318   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1319   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1320   PetscFunctionReturn(0);
1321 }
1322 
1323 /*@C
1324    MatSetValues - Inserts or adds a block of values into a matrix.
1325    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1326    MUST be called after all calls to MatSetValues() have been completed.
1327 
1328    Not Collective
1329 
1330    Input Parameters:
1331 +  mat - the matrix
1332 .  v - a logically two-dimensional array of values
1333 .  m, idxm - the number of rows and their global indices
1334 .  n, idxn - the number of columns and their global indices
1335 -  addv - either ADD_VALUES or INSERT_VALUES, where
1336    ADD_VALUES adds values to any existing entries, and
1337    INSERT_VALUES replaces existing entries with new values
1338 
1339    Notes:
1340    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1341       MatSetUp() before using this routine
1342 
1343    By default the values, v, are row-oriented. See MatSetOption() for other options.
1344 
1345    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1346    options cannot be mixed without intervening calls to the assembly
1347    routines.
1348 
1349    MatSetValues() uses 0-based row and column numbers in Fortran
1350    as well as in C.
1351 
1352    Negative indices may be passed in idxm and idxn, these rows and columns are
1353    simply ignored. This allows easily inserting element stiffness matrices
1354    with homogeneous Dirchlet boundary conditions that you don't want represented
1355    in the matrix.
1356 
1357    Efficiency Alert:
1358    The routine MatSetValuesBlocked() may offer much better efficiency
1359    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1360 
1361    Level: beginner
1362 
1363    Developer Notes:
1364     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1365                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1366 
1367    Concepts: matrices^putting entries in
1368 
1369 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1370           InsertMode, INSERT_VALUES, ADD_VALUES
1371 @*/
1372 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1373 {
1374   PetscErrorCode ierr;
1375 #if defined(PETSC_USE_DEBUG)
1376   PetscInt       i,j;
1377 #endif
1378 
1379   PetscFunctionBeginHot;
1380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1381   PetscValidType(mat,1);
1382   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1383   PetscValidIntPointer(idxm,3);
1384   PetscValidIntPointer(idxn,5);
1385   PetscValidScalarPointer(v,6);
1386   MatCheckPreallocated(mat,1);
1387   if (mat->insertmode == NOT_SET_VALUES) {
1388     mat->insertmode = addv;
1389   }
1390 #if defined(PETSC_USE_DEBUG)
1391   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1392   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1393   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1394 
1395   for (i=0; i<m; i++) {
1396     for (j=0; j<n; j++) {
1397       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1398 #if defined(PETSC_USE_COMPLEX)
1399         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]);
1400 #else
1401         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1402 #endif
1403     }
1404   }
1405 #endif
1406 
1407   if (mat->assembled) {
1408     mat->was_assembled = PETSC_TRUE;
1409     mat->assembled     = PETSC_FALSE;
1410   }
1411   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1412   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1413   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1414 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1415   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1416     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1417   }
1418 #endif
1419   PetscFunctionReturn(0);
1420 }
1421 
1422 
1423 /*@
1424    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1425         values into a matrix
1426 
1427    Not Collective
1428 
1429    Input Parameters:
1430 +  mat - the matrix
1431 .  row - the (block) row to set
1432 -  v - a logically two-dimensional array of values
1433 
1434    Notes:
1435    By the values, v, are column-oriented (for the block version) and sorted
1436 
1437    All the nonzeros in the row must be provided
1438 
1439    The matrix must have previously had its column indices set
1440 
1441    The row must belong to this process
1442 
1443    Level: intermediate
1444 
1445    Concepts: matrices^putting entries in
1446 
1447 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1448           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1449 @*/
1450 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1451 {
1452   PetscErrorCode ierr;
1453   PetscInt       globalrow;
1454 
1455   PetscFunctionBegin;
1456   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1457   PetscValidType(mat,1);
1458   PetscValidScalarPointer(v,2);
1459   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1460   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1464   }
1465 #endif
1466   PetscFunctionReturn(0);
1467 }
1468 
1469 /*@
1470    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1471         values into a matrix
1472 
1473    Not Collective
1474 
1475    Input Parameters:
1476 +  mat - the matrix
1477 .  row - the (block) row to set
1478 -  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
1479 
1480    Notes:
1481    The values, v, are column-oriented for the block version.
1482 
1483    All the nonzeros in the row must be provided
1484 
1485    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1486 
1487    The row must belong to this process
1488 
1489    Level: advanced
1490 
1491    Concepts: matrices^putting entries in
1492 
1493 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1494           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1495 @*/
1496 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1497 {
1498   PetscErrorCode ierr;
1499 
1500   PetscFunctionBeginHot;
1501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1502   PetscValidType(mat,1);
1503   MatCheckPreallocated(mat,1);
1504   PetscValidScalarPointer(v,2);
1505 #if defined(PETSC_USE_DEBUG)
1506   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1507   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1508 #endif
1509   mat->insertmode = INSERT_VALUES;
1510 
1511   if (mat->assembled) {
1512     mat->was_assembled = PETSC_TRUE;
1513     mat->assembled     = PETSC_FALSE;
1514   }
1515   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1516   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1517   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1518   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1519 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1520   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1521     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1522   }
1523 #endif
1524   PetscFunctionReturn(0);
1525 }
1526 
1527 /*@
1528    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1529      Using structured grid indexing
1530 
1531    Not Collective
1532 
1533    Input Parameters:
1534 +  mat - the matrix
1535 .  m - number of rows being entered
1536 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1537 .  n - number of columns being entered
1538 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1539 .  v - a logically two-dimensional array of values
1540 -  addv - either ADD_VALUES or INSERT_VALUES, where
1541    ADD_VALUES adds values to any existing entries, and
1542    INSERT_VALUES replaces existing entries with new values
1543 
1544    Notes:
1545    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1546 
1547    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1548    options cannot be mixed without intervening calls to the assembly
1549    routines.
1550 
1551    The grid coordinates are across the entire grid, not just the local portion
1552 
1553    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1554    as well as in C.
1555 
1556    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1557 
1558    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1559    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1560 
1561    The columns and rows in the stencil passed in MUST be contained within the
1562    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1563    if you create a DMDA with an overlap of one grid level and on a particular process its first
1564    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1565    first i index you can use in your column and row indices in MatSetStencil() is 5.
1566 
1567    In Fortran idxm and idxn should be declared as
1568 $     MatStencil idxm(4,m),idxn(4,n)
1569    and the values inserted using
1570 $    idxm(MatStencil_i,1) = i
1571 $    idxm(MatStencil_j,1) = j
1572 $    idxm(MatStencil_k,1) = k
1573 $    idxm(MatStencil_c,1) = c
1574    etc
1575 
1576    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1577    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1578    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1579    DM_BOUNDARY_PERIODIC boundary type.
1580 
1581    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
1582    a single value per point) you can skip filling those indices.
1583 
1584    Inspired by the structured grid interface to the HYPRE package
1585    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1586 
1587    Efficiency Alert:
1588    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1589    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1590 
1591    Level: beginner
1592 
1593    Concepts: matrices^putting entries in
1594 
1595 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1596           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1597 @*/
1598 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1599 {
1600   PetscErrorCode ierr;
1601   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1602   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1603   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1604 
1605   PetscFunctionBegin;
1606   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1607   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1608   PetscValidType(mat,1);
1609   PetscValidIntPointer(idxm,3);
1610   PetscValidIntPointer(idxn,5);
1611   PetscValidScalarPointer(v,6);
1612 
1613   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1614     jdxm = buf; jdxn = buf+m;
1615   } else {
1616     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1617     jdxm = bufm; jdxn = bufn;
1618   }
1619   for (i=0; i<m; i++) {
1620     for (j=0; j<3-sdim; j++) dxm++;
1621     tmp = *dxm++ - starts[0];
1622     for (j=0; j<dim-1; j++) {
1623       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1624       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1625     }
1626     if (mat->stencil.noc) dxm++;
1627     jdxm[i] = tmp;
1628   }
1629   for (i=0; i<n; i++) {
1630     for (j=0; j<3-sdim; j++) dxn++;
1631     tmp = *dxn++ - starts[0];
1632     for (j=0; j<dim-1; j++) {
1633       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1634       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1635     }
1636     if (mat->stencil.noc) dxn++;
1637     jdxn[i] = tmp;
1638   }
1639   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1640   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1641   PetscFunctionReturn(0);
1642 }
1643 
1644 /*@
1645    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1646      Using structured grid indexing
1647 
1648    Not Collective
1649 
1650    Input Parameters:
1651 +  mat - the matrix
1652 .  m - number of rows being entered
1653 .  idxm - grid coordinates for matrix rows being entered
1654 .  n - number of columns being entered
1655 .  idxn - grid coordinates for matrix columns being entered
1656 .  v - a logically two-dimensional array of values
1657 -  addv - either ADD_VALUES or INSERT_VALUES, where
1658    ADD_VALUES adds values to any existing entries, and
1659    INSERT_VALUES replaces existing entries with new values
1660 
1661    Notes:
1662    By default the values, v, are row-oriented and unsorted.
1663    See MatSetOption() for other options.
1664 
1665    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1666    options cannot be mixed without intervening calls to the assembly
1667    routines.
1668 
1669    The grid coordinates are across the entire grid, not just the local portion
1670 
1671    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1672    as well as in C.
1673 
1674    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1675 
1676    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1677    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1678 
1679    The columns and rows in the stencil passed in MUST be contained within the
1680    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1681    if you create a DMDA with an overlap of one grid level and on a particular process its first
1682    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1683    first i index you can use in your column and row indices in MatSetStencil() is 5.
1684 
1685    In Fortran idxm and idxn should be declared as
1686 $     MatStencil idxm(4,m),idxn(4,n)
1687    and the values inserted using
1688 $    idxm(MatStencil_i,1) = i
1689 $    idxm(MatStencil_j,1) = j
1690 $    idxm(MatStencil_k,1) = k
1691    etc
1692 
1693    Negative indices may be passed in idxm and idxn, these rows and columns are
1694    simply ignored. This allows easily inserting element stiffness matrices
1695    with homogeneous Dirchlet boundary conditions that you don't want represented
1696    in the matrix.
1697 
1698    Inspired by the structured grid interface to the HYPRE package
1699    (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods)
1700 
1701    Level: beginner
1702 
1703    Concepts: matrices^putting entries in
1704 
1705 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1706           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1707           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1708 @*/
1709 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1710 {
1711   PetscErrorCode ierr;
1712   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1713   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1714   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1715 
1716   PetscFunctionBegin;
1717   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1718   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1719   PetscValidType(mat,1);
1720   PetscValidIntPointer(idxm,3);
1721   PetscValidIntPointer(idxn,5);
1722   PetscValidScalarPointer(v,6);
1723 
1724   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1725     jdxm = buf; jdxn = buf+m;
1726   } else {
1727     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1728     jdxm = bufm; jdxn = bufn;
1729   }
1730   for (i=0; i<m; i++) {
1731     for (j=0; j<3-sdim; j++) dxm++;
1732     tmp = *dxm++ - starts[0];
1733     for (j=0; j<sdim-1; j++) {
1734       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1735       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1736     }
1737     dxm++;
1738     jdxm[i] = tmp;
1739   }
1740   for (i=0; i<n; i++) {
1741     for (j=0; j<3-sdim; j++) dxn++;
1742     tmp = *dxn++ - starts[0];
1743     for (j=0; j<sdim-1; j++) {
1744       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1745       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1746     }
1747     dxn++;
1748     jdxn[i] = tmp;
1749   }
1750   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1751   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1752 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1753   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1754     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1755   }
1756 #endif
1757   PetscFunctionReturn(0);
1758 }
1759 
1760 /*@
1761    MatSetStencil - Sets the grid information for setting values into a matrix via
1762         MatSetValuesStencil()
1763 
1764    Not Collective
1765 
1766    Input Parameters:
1767 +  mat - the matrix
1768 .  dim - dimension of the grid 1, 2, or 3
1769 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1770 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1771 -  dof - number of degrees of freedom per node
1772 
1773 
1774    Inspired by the structured grid interface to the HYPRE package
1775    (www.llnl.gov/CASC/hyper)
1776 
1777    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1778    user.
1779 
1780    Level: beginner
1781 
1782    Concepts: matrices^putting entries in
1783 
1784 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1785           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1786 @*/
1787 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1788 {
1789   PetscInt i;
1790 
1791   PetscFunctionBegin;
1792   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1793   PetscValidIntPointer(dims,3);
1794   PetscValidIntPointer(starts,4);
1795 
1796   mat->stencil.dim = dim + (dof > 1);
1797   for (i=0; i<dim; i++) {
1798     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1799     mat->stencil.starts[i] = starts[dim-i-1];
1800   }
1801   mat->stencil.dims[dim]   = dof;
1802   mat->stencil.starts[dim] = 0;
1803   mat->stencil.noc         = (PetscBool)(dof == 1);
1804   PetscFunctionReturn(0);
1805 }
1806 
1807 /*@C
1808    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1809 
1810    Not Collective
1811 
1812    Input Parameters:
1813 +  mat - the matrix
1814 .  v - a logically two-dimensional array of values
1815 .  m, idxm - the number of block rows and their global block indices
1816 .  n, idxn - the number of block columns and their global block indices
1817 -  addv - either ADD_VALUES or INSERT_VALUES, where
1818    ADD_VALUES adds values to any existing entries, and
1819    INSERT_VALUES replaces existing entries with new values
1820 
1821    Notes:
1822    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1823    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1824 
1825    The m and n count the NUMBER of blocks in the row direction and column direction,
1826    NOT the total number of rows/columns; for example, if the block size is 2 and
1827    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1828    The values in idxm would be 1 2; that is the first index for each block divided by
1829    the block size.
1830 
1831    Note that you must call MatSetBlockSize() when constructing this matrix (before
1832    preallocating it).
1833 
1834    By default the values, v, are row-oriented, so the layout of
1835    v is the same as for MatSetValues(). See MatSetOption() for other options.
1836 
1837    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1838    options cannot be mixed without intervening calls to the assembly
1839    routines.
1840 
1841    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1842    as well as in C.
1843 
1844    Negative indices may be passed in idxm and idxn, these rows and columns are
1845    simply ignored. This allows easily inserting element stiffness matrices
1846    with homogeneous Dirchlet boundary conditions that you don't want represented
1847    in the matrix.
1848 
1849    Each time an entry is set within a sparse matrix via MatSetValues(),
1850    internal searching must be done to determine where to place the
1851    data in the matrix storage space.  By instead inserting blocks of
1852    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1853    reduced.
1854 
1855    Example:
1856 $   Suppose m=n=2 and block size(bs) = 2 The array is
1857 $
1858 $   1  2  | 3  4
1859 $   5  6  | 7  8
1860 $   - - - | - - -
1861 $   9  10 | 11 12
1862 $   13 14 | 15 16
1863 $
1864 $   v[] should be passed in like
1865 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1866 $
1867 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1868 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1869 
1870    Level: intermediate
1871 
1872    Concepts: matrices^putting entries in blocked
1873 
1874 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1875 @*/
1876 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1877 {
1878   PetscErrorCode ierr;
1879 
1880   PetscFunctionBeginHot;
1881   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1882   PetscValidType(mat,1);
1883   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1884   PetscValidIntPointer(idxm,3);
1885   PetscValidIntPointer(idxn,5);
1886   PetscValidScalarPointer(v,6);
1887   MatCheckPreallocated(mat,1);
1888   if (mat->insertmode == NOT_SET_VALUES) {
1889     mat->insertmode = addv;
1890   }
1891 #if defined(PETSC_USE_DEBUG)
1892   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1893   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1894   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1895 #endif
1896 
1897   if (mat->assembled) {
1898     mat->was_assembled = PETSC_TRUE;
1899     mat->assembled     = PETSC_FALSE;
1900   }
1901   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1902   if (mat->ops->setvaluesblocked) {
1903     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1904   } else {
1905     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1906     PetscInt i,j,bs,cbs;
1907     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1908     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1909       iidxm = buf; iidxn = buf + m*bs;
1910     } else {
1911       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1912       iidxm = bufr; iidxn = bufc;
1913     }
1914     for (i=0; i<m; i++) {
1915       for (j=0; j<bs; j++) {
1916         iidxm[i*bs+j] = bs*idxm[i] + j;
1917       }
1918     }
1919     for (i=0; i<n; i++) {
1920       for (j=0; j<cbs; j++) {
1921         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1922       }
1923     }
1924     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1925     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1926   }
1927   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1928 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1929   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1930     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1931   }
1932 #endif
1933   PetscFunctionReturn(0);
1934 }
1935 
1936 /*@
1937    MatGetValues - Gets a block of values from a matrix.
1938 
1939    Not Collective; currently only returns a local block
1940 
1941    Input Parameters:
1942 +  mat - the matrix
1943 .  v - a logically two-dimensional array for storing the values
1944 .  m, idxm - the number of rows and their global indices
1945 -  n, idxn - the number of columns and their global indices
1946 
1947    Notes:
1948    The user must allocate space (m*n PetscScalars) for the values, v.
1949    The values, v, are then returned in a row-oriented format,
1950    analogous to that used by default in MatSetValues().
1951 
1952    MatGetValues() uses 0-based row and column numbers in
1953    Fortran as well as in C.
1954 
1955    MatGetValues() requires that the matrix has been assembled
1956    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1957    MatSetValues() and MatGetValues() CANNOT be made in succession
1958    without intermediate matrix assembly.
1959 
1960    Negative row or column indices will be ignored and those locations in v[] will be
1961    left unchanged.
1962 
1963    Level: advanced
1964 
1965    Concepts: matrices^accessing values
1966 
1967 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1968 @*/
1969 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1970 {
1971   PetscErrorCode ierr;
1972 
1973   PetscFunctionBegin;
1974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1975   PetscValidType(mat,1);
1976   if (!m || !n) PetscFunctionReturn(0);
1977   PetscValidIntPointer(idxm,3);
1978   PetscValidIntPointer(idxn,5);
1979   PetscValidScalarPointer(v,6);
1980   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1981   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1982   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1983   MatCheckPreallocated(mat,1);
1984 
1985   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1986   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1987   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1988   PetscFunctionReturn(0);
1989 }
1990 
1991 /*@
1992   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1993   the same size. Currently, this can only be called once and creates the given matrix.
1994 
1995   Not Collective
1996 
1997   Input Parameters:
1998 + mat - the matrix
1999 . nb - the number of blocks
2000 . bs - the number of rows (and columns) in each block
2001 . rows - a concatenation of the rows for each block
2002 - v - a concatenation of logically two-dimensional arrays of values
2003 
2004   Notes:
2005   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2006 
2007   Level: advanced
2008 
2009   Concepts: matrices^putting entries in
2010 
2011 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2012           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2013 @*/
2014 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2015 {
2016   PetscErrorCode ierr;
2017 
2018   PetscFunctionBegin;
2019   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2020   PetscValidType(mat,1);
2021   PetscValidScalarPointer(rows,4);
2022   PetscValidScalarPointer(v,5);
2023 #if defined(PETSC_USE_DEBUG)
2024   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2025 #endif
2026 
2027   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2028   if (mat->ops->setvaluesbatch) {
2029     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2030   } else {
2031     PetscInt b;
2032     for (b = 0; b < nb; ++b) {
2033       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2034     }
2035   }
2036   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2037   PetscFunctionReturn(0);
2038 }
2039 
2040 /*@
2041    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2042    the routine MatSetValuesLocal() to allow users to insert matrix entries
2043    using a local (per-processor) numbering.
2044 
2045    Not Collective
2046 
2047    Input Parameters:
2048 +  x - the matrix
2049 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2050 - cmapping - column mapping
2051 
2052    Level: intermediate
2053 
2054    Concepts: matrices^local to global mapping
2055    Concepts: local to global mapping^for matrices
2056 
2057 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2058 @*/
2059 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2060 {
2061   PetscErrorCode ierr;
2062 
2063   PetscFunctionBegin;
2064   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2065   PetscValidType(x,1);
2066   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2067   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2068 
2069   if (x->ops->setlocaltoglobalmapping) {
2070     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2071   } else {
2072     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2073     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2074   }
2075   PetscFunctionReturn(0);
2076 }
2077 
2078 
2079 /*@
2080    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2081 
2082    Not Collective
2083 
2084    Input Parameters:
2085 .  A - the matrix
2086 
2087    Output Parameters:
2088 + rmapping - row mapping
2089 - cmapping - column mapping
2090 
2091    Level: advanced
2092 
2093    Concepts: matrices^local to global mapping
2094    Concepts: local to global mapping^for matrices
2095 
2096 .seealso:  MatSetValuesLocal()
2097 @*/
2098 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2099 {
2100   PetscFunctionBegin;
2101   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2102   PetscValidType(A,1);
2103   if (rmapping) PetscValidPointer(rmapping,2);
2104   if (cmapping) PetscValidPointer(cmapping,3);
2105   if (rmapping) *rmapping = A->rmap->mapping;
2106   if (cmapping) *cmapping = A->cmap->mapping;
2107   PetscFunctionReturn(0);
2108 }
2109 
2110 /*@
2111    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2112 
2113    Not Collective
2114 
2115    Input Parameters:
2116 .  A - the matrix
2117 
2118    Output Parameters:
2119 + rmap - row layout
2120 - cmap - column layout
2121 
2122    Level: advanced
2123 
2124 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2125 @*/
2126 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2127 {
2128   PetscFunctionBegin;
2129   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2130   PetscValidType(A,1);
2131   if (rmap) PetscValidPointer(rmap,2);
2132   if (cmap) PetscValidPointer(cmap,3);
2133   if (rmap) *rmap = A->rmap;
2134   if (cmap) *cmap = A->cmap;
2135   PetscFunctionReturn(0);
2136 }
2137 
2138 /*@C
2139    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2140    using a local ordering of the nodes.
2141 
2142    Not Collective
2143 
2144    Input Parameters:
2145 +  mat - the matrix
2146 .  nrow, irow - number of rows and their local indices
2147 .  ncol, icol - number of columns and their local indices
2148 .  y -  a logically two-dimensional array of values
2149 -  addv - either INSERT_VALUES or ADD_VALUES, where
2150    ADD_VALUES adds values to any existing entries, and
2151    INSERT_VALUES replaces existing entries with new values
2152 
2153    Notes:
2154    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2155       MatSetUp() before using this routine
2156 
2157    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2158 
2159    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2160    options cannot be mixed without intervening calls to the assembly
2161    routines.
2162 
2163    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2164    MUST be called after all calls to MatSetValuesLocal() have been completed.
2165 
2166    Level: intermediate
2167 
2168    Concepts: matrices^putting entries in with local numbering
2169 
2170    Developer Notes:
2171     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2172                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2173 
2174 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2175            MatSetValueLocal()
2176 @*/
2177 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2178 {
2179   PetscErrorCode ierr;
2180 
2181   PetscFunctionBeginHot;
2182   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2183   PetscValidType(mat,1);
2184   MatCheckPreallocated(mat,1);
2185   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2186   PetscValidIntPointer(irow,3);
2187   PetscValidIntPointer(icol,5);
2188   PetscValidScalarPointer(y,6);
2189   if (mat->insertmode == NOT_SET_VALUES) {
2190     mat->insertmode = addv;
2191   }
2192 #if defined(PETSC_USE_DEBUG)
2193   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2194   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2195   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2196 #endif
2197 
2198   if (mat->assembled) {
2199     mat->was_assembled = PETSC_TRUE;
2200     mat->assembled     = PETSC_FALSE;
2201   }
2202   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2203   if (mat->ops->setvalueslocal) {
2204     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2205   } else {
2206     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2207     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2208       irowm = buf; icolm = buf+nrow;
2209     } else {
2210       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2211       irowm = bufr; icolm = bufc;
2212     }
2213     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2214     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2215     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2216     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2217   }
2218   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2219 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2220   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2221     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2222   }
2223 #endif
2224   PetscFunctionReturn(0);
2225 }
2226 
2227 /*@C
2228    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2229    using a local ordering of the nodes a block at a time.
2230 
2231    Not Collective
2232 
2233    Input Parameters:
2234 +  x - the matrix
2235 .  nrow, irow - number of rows and their local indices
2236 .  ncol, icol - number of columns and their local indices
2237 .  y -  a logically two-dimensional array of values
2238 -  addv - either INSERT_VALUES or ADD_VALUES, where
2239    ADD_VALUES adds values to any existing entries, and
2240    INSERT_VALUES replaces existing entries with new values
2241 
2242    Notes:
2243    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2244       MatSetUp() before using this routine
2245 
2246    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2247       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2248 
2249    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2250    options cannot be mixed without intervening calls to the assembly
2251    routines.
2252 
2253    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2254    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2255 
2256    Level: intermediate
2257 
2258    Developer Notes:
2259     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2260                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2261 
2262    Concepts: matrices^putting blocked values in with local numbering
2263 
2264 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2265            MatSetValuesLocal(),  MatSetValuesBlocked()
2266 @*/
2267 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2268 {
2269   PetscErrorCode ierr;
2270 
2271   PetscFunctionBeginHot;
2272   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2273   PetscValidType(mat,1);
2274   MatCheckPreallocated(mat,1);
2275   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2276   PetscValidIntPointer(irow,3);
2277   PetscValidIntPointer(icol,5);
2278   PetscValidScalarPointer(y,6);
2279   if (mat->insertmode == NOT_SET_VALUES) {
2280     mat->insertmode = addv;
2281   }
2282 #if defined(PETSC_USE_DEBUG)
2283   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2284   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2285   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);
2286 #endif
2287 
2288   if (mat->assembled) {
2289     mat->was_assembled = PETSC_TRUE;
2290     mat->assembled     = PETSC_FALSE;
2291   }
2292 #if defined(PETSC_USE_DEBUG)
2293   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2294   if (mat->rmap->mapping) {
2295     PetscInt irbs, rbs;
2296     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2297     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2298     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2299   }
2300   if (mat->cmap->mapping) {
2301     PetscInt icbs, cbs;
2302     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2303     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2304     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2305   }
2306 #endif
2307   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2308   if (mat->ops->setvaluesblockedlocal) {
2309     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2310   } else {
2311     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2312     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2313       irowm = buf; icolm = buf + nrow;
2314     } else {
2315       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2316       irowm = bufr; icolm = bufc;
2317     }
2318     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2319     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2320     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2321     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2322   }
2323   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2324 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2325   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2326     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2327   }
2328 #endif
2329   PetscFunctionReturn(0);
2330 }
2331 
2332 /*@
2333    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2334 
2335    Collective on Mat and Vec
2336 
2337    Input Parameters:
2338 +  mat - the matrix
2339 -  x   - the vector to be multiplied
2340 
2341    Output Parameters:
2342 .  y - the result
2343 
2344    Notes:
2345    The vectors x and y cannot be the same.  I.e., one cannot
2346    call MatMult(A,y,y).
2347 
2348    Level: developer
2349 
2350    Concepts: matrix-vector product
2351 
2352 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2353 @*/
2354 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2355 {
2356   PetscErrorCode ierr;
2357 
2358   PetscFunctionBegin;
2359   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2360   PetscValidType(mat,1);
2361   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2362   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2363 
2364   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2365   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2366   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2367   MatCheckPreallocated(mat,1);
2368 
2369   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2370   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2371   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2372   PetscFunctionReturn(0);
2373 }
2374 
2375 /* --------------------------------------------------------*/
2376 /*@
2377    MatMult - Computes the matrix-vector product, y = Ax.
2378 
2379    Neighbor-wise Collective on Mat and Vec
2380 
2381    Input Parameters:
2382 +  mat - the matrix
2383 -  x   - the vector to be multiplied
2384 
2385    Output Parameters:
2386 .  y - the result
2387 
2388    Notes:
2389    The vectors x and y cannot be the same.  I.e., one cannot
2390    call MatMult(A,y,y).
2391 
2392    Level: beginner
2393 
2394    Concepts: matrix-vector product
2395 
2396 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2397 @*/
2398 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2399 {
2400   PetscErrorCode ierr;
2401 
2402   PetscFunctionBegin;
2403   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2404   PetscValidType(mat,1);
2405   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2406   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2407   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2408   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2409   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2410 #if !defined(PETSC_HAVE_CONSTRAINTS)
2411   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);
2412   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);
2413   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);
2414 #endif
2415   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2416   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2417   MatCheckPreallocated(mat,1);
2418 
2419   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2420   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2421   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2422   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2423   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2424   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2425   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2426   PetscFunctionReturn(0);
2427 }
2428 
2429 /*@
2430    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2431 
2432    Neighbor-wise Collective on Mat and Vec
2433 
2434    Input Parameters:
2435 +  mat - the matrix
2436 -  x   - the vector to be multiplied
2437 
2438    Output Parameters:
2439 .  y - the result
2440 
2441    Notes:
2442    The vectors x and y cannot be the same.  I.e., one cannot
2443    call MatMultTranspose(A,y,y).
2444 
2445    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2446    use MatMultHermitianTranspose()
2447 
2448    Level: beginner
2449 
2450    Concepts: matrix vector product^transpose
2451 
2452 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2453 @*/
2454 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2455 {
2456   PetscErrorCode ierr;
2457 
2458   PetscFunctionBegin;
2459   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2460   PetscValidType(mat,1);
2461   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2462   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2463 
2464   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2465   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2466   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2467 #if !defined(PETSC_HAVE_CONSTRAINTS)
2468   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);
2469   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);
2470 #endif
2471   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2472   MatCheckPreallocated(mat,1);
2473 
2474   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2475   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2476   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2477   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2478   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2479   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2480   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2481   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2482   PetscFunctionReturn(0);
2483 }
2484 
2485 /*@
2486    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2487 
2488    Neighbor-wise Collective on Mat and Vec
2489 
2490    Input Parameters:
2491 +  mat - the matrix
2492 -  x   - the vector to be multilplied
2493 
2494    Output Parameters:
2495 .  y - the result
2496 
2497    Notes:
2498    The vectors x and y cannot be the same.  I.e., one cannot
2499    call MatMultHermitianTranspose(A,y,y).
2500 
2501    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2502 
2503    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2504 
2505    Level: beginner
2506 
2507    Concepts: matrix vector product^transpose
2508 
2509 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2510 @*/
2511 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2512 {
2513   PetscErrorCode ierr;
2514   Vec            w;
2515 
2516   PetscFunctionBegin;
2517   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2518   PetscValidType(mat,1);
2519   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2520   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2521 
2522   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2523   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2524   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2525 #if !defined(PETSC_HAVE_CONSTRAINTS)
2526   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);
2527   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);
2528 #endif
2529   MatCheckPreallocated(mat,1);
2530 
2531   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2532   if (mat->ops->multhermitiantranspose) {
2533     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2534     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2535     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2536   } else {
2537     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2538     ierr = VecCopy(x,w);CHKERRQ(ierr);
2539     ierr = VecConjugate(w);CHKERRQ(ierr);
2540     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2541     ierr = VecDestroy(&w);CHKERRQ(ierr);
2542     ierr = VecConjugate(y);CHKERRQ(ierr);
2543   }
2544   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2545   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2546   PetscFunctionReturn(0);
2547 }
2548 
2549 /*@
2550     MatMultAdd -  Computes v3 = v2 + A * v1.
2551 
2552     Neighbor-wise Collective on Mat and Vec
2553 
2554     Input Parameters:
2555 +   mat - the matrix
2556 -   v1, v2 - the vectors
2557 
2558     Output Parameters:
2559 .   v3 - the result
2560 
2561     Notes:
2562     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2563     call MatMultAdd(A,v1,v2,v1).
2564 
2565     Level: beginner
2566 
2567     Concepts: matrix vector product^addition
2568 
2569 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2570 @*/
2571 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2572 {
2573   PetscErrorCode ierr;
2574 
2575   PetscFunctionBegin;
2576   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2577   PetscValidType(mat,1);
2578   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2579   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2580   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2581 
2582   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2583   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2584   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);
2585   /* 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);
2586      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); */
2587   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);
2588   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);
2589   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2590   MatCheckPreallocated(mat,1);
2591 
2592   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2593   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2594   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2595   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2596   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2597   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2598   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2599   PetscFunctionReturn(0);
2600 }
2601 
2602 /*@
2603    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2604 
2605    Neighbor-wise Collective on Mat and Vec
2606 
2607    Input Parameters:
2608 +  mat - the matrix
2609 -  v1, v2 - the vectors
2610 
2611    Output Parameters:
2612 .  v3 - the result
2613 
2614    Notes:
2615    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2616    call MatMultTransposeAdd(A,v1,v2,v1).
2617 
2618    Level: beginner
2619 
2620    Concepts: matrix vector product^transpose and addition
2621 
2622 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2623 @*/
2624 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2625 {
2626   PetscErrorCode ierr;
2627 
2628   PetscFunctionBegin;
2629   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2630   PetscValidType(mat,1);
2631   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2632   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2633   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2634 
2635   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2636   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2637   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2638   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2639   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);
2640   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);
2641   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);
2642   MatCheckPreallocated(mat,1);
2643 
2644   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2645   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2646   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2647   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2648   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2649   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2650   PetscFunctionReturn(0);
2651 }
2652 
2653 /*@
2654    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2655 
2656    Neighbor-wise Collective on Mat and Vec
2657 
2658    Input Parameters:
2659 +  mat - the matrix
2660 -  v1, v2 - the vectors
2661 
2662    Output Parameters:
2663 .  v3 - the result
2664 
2665    Notes:
2666    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2667    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2668 
2669    Level: beginner
2670 
2671    Concepts: matrix vector product^transpose and addition
2672 
2673 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2674 @*/
2675 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2676 {
2677   PetscErrorCode ierr;
2678 
2679   PetscFunctionBegin;
2680   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2681   PetscValidType(mat,1);
2682   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2683   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2684   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2685 
2686   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2687   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2688   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2689   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);
2690   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);
2691   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);
2692   MatCheckPreallocated(mat,1);
2693 
2694   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2695   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2696   if (mat->ops->multhermitiantransposeadd) {
2697     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2698   } else {
2699     Vec w,z;
2700     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2701     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2702     ierr = VecConjugate(w);CHKERRQ(ierr);
2703     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2704     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2705     ierr = VecDestroy(&w);CHKERRQ(ierr);
2706     ierr = VecConjugate(z);CHKERRQ(ierr);
2707     if (v2 != v3) {
2708       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2709     } else {
2710       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2711     }
2712     ierr = VecDestroy(&z);CHKERRQ(ierr);
2713   }
2714   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2715   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2716   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2717   PetscFunctionReturn(0);
2718 }
2719 
2720 /*@
2721    MatMultConstrained - The inner multiplication routine for a
2722    constrained matrix P^T A P.
2723 
2724    Neighbor-wise Collective on Mat and Vec
2725 
2726    Input Parameters:
2727 +  mat - the matrix
2728 -  x   - the vector to be multilplied
2729 
2730    Output Parameters:
2731 .  y - the result
2732 
2733    Notes:
2734    The vectors x and y cannot be the same.  I.e., one cannot
2735    call MatMult(A,y,y).
2736 
2737    Level: beginner
2738 
2739 .keywords: matrix, multiply, matrix-vector product, constraint
2740 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2741 @*/
2742 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2743 {
2744   PetscErrorCode ierr;
2745 
2746   PetscFunctionBegin;
2747   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2748   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2749   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2750   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2751   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2752   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2753   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);
2754   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);
2755   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);
2756 
2757   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2758   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2759   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2760   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2761   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2762   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2763   PetscFunctionReturn(0);
2764 }
2765 
2766 /*@
2767    MatMultTransposeConstrained - The inner multiplication routine for a
2768    constrained matrix P^T A^T P.
2769 
2770    Neighbor-wise Collective on Mat and Vec
2771 
2772    Input Parameters:
2773 +  mat - the matrix
2774 -  x   - the vector to be multilplied
2775 
2776    Output Parameters:
2777 .  y - the result
2778 
2779    Notes:
2780    The vectors x and y cannot be the same.  I.e., one cannot
2781    call MatMult(A,y,y).
2782 
2783    Level: beginner
2784 
2785 .keywords: matrix, multiply, matrix-vector product, constraint
2786 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2787 @*/
2788 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2789 {
2790   PetscErrorCode ierr;
2791 
2792   PetscFunctionBegin;
2793   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2794   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2795   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2796   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2797   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2798   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2799   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2800   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2801 
2802   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2803   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2804   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2805   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2806   PetscFunctionReturn(0);
2807 }
2808 
2809 /*@C
2810    MatGetFactorType - gets the type of factorization it is
2811 
2812    Not Collective
2813 
2814    Input Parameters:
2815 .  mat - the matrix
2816 
2817    Output Parameters:
2818 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2819 
2820    Level: intermediate
2821 
2822 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2823 @*/
2824 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2825 {
2826   PetscFunctionBegin;
2827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2828   PetscValidType(mat,1);
2829   PetscValidPointer(t,2);
2830   *t = mat->factortype;
2831   PetscFunctionReturn(0);
2832 }
2833 
2834 /*@C
2835    MatSetFactorType - sets the type of factorization it is
2836 
2837    Logically Collective on Mat
2838 
2839    Input Parameters:
2840 +  mat - the matrix
2841 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2842 
2843    Level: intermediate
2844 
2845 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2846 @*/
2847 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2848 {
2849   PetscFunctionBegin;
2850   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2851   PetscValidType(mat,1);
2852   mat->factortype = t;
2853   PetscFunctionReturn(0);
2854 }
2855 
2856 /* ------------------------------------------------------------*/
2857 /*@C
2858    MatGetInfo - Returns information about matrix storage (number of
2859    nonzeros, memory, etc.).
2860 
2861    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2862 
2863    Input Parameters:
2864 .  mat - the matrix
2865 
2866    Output Parameters:
2867 +  flag - flag indicating the type of parameters to be returned
2868    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2869    MAT_GLOBAL_SUM - sum over all processors)
2870 -  info - matrix information context
2871 
2872    Notes:
2873    The MatInfo context contains a variety of matrix data, including
2874    number of nonzeros allocated and used, number of mallocs during
2875    matrix assembly, etc.  Additional information for factored matrices
2876    is provided (such as the fill ratio, number of mallocs during
2877    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2878    when using the runtime options
2879 $       -info -mat_view ::ascii_info
2880 
2881    Example for C/C++ Users:
2882    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2883    data within the MatInfo context.  For example,
2884 .vb
2885       MatInfo info;
2886       Mat     A;
2887       double  mal, nz_a, nz_u;
2888 
2889       MatGetInfo(A,MAT_LOCAL,&info);
2890       mal  = info.mallocs;
2891       nz_a = info.nz_allocated;
2892 .ve
2893 
2894    Example for Fortran Users:
2895    Fortran users should declare info as a double precision
2896    array of dimension MAT_INFO_SIZE, and then extract the parameters
2897    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2898    a complete list of parameter names.
2899 .vb
2900       double  precision info(MAT_INFO_SIZE)
2901       double  precision mal, nz_a
2902       Mat     A
2903       integer ierr
2904 
2905       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2906       mal = info(MAT_INFO_MALLOCS)
2907       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2908 .ve
2909 
2910     Level: intermediate
2911 
2912     Concepts: matrices^getting information on
2913 
2914     Developer Note: fortran interface is not autogenerated as the f90
2915     interface defintion cannot be generated correctly [due to MatInfo]
2916 
2917 .seealso: MatStashGetInfo()
2918 
2919 @*/
2920 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2921 {
2922   PetscErrorCode ierr;
2923 
2924   PetscFunctionBegin;
2925   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2926   PetscValidType(mat,1);
2927   PetscValidPointer(info,3);
2928   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2929   MatCheckPreallocated(mat,1);
2930   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2931   PetscFunctionReturn(0);
2932 }
2933 
2934 /*
2935    This is used by external packages where it is not easy to get the info from the actual
2936    matrix factorization.
2937 */
2938 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2939 {
2940   PetscErrorCode ierr;
2941 
2942   PetscFunctionBegin;
2943   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2944   PetscFunctionReturn(0);
2945 }
2946 
2947 /* ----------------------------------------------------------*/
2948 
2949 /*@C
2950    MatLUFactor - Performs in-place LU factorization of matrix.
2951 
2952    Collective on Mat
2953 
2954    Input Parameters:
2955 +  mat - the matrix
2956 .  row - row permutation
2957 .  col - column permutation
2958 -  info - options for factorization, includes
2959 $          fill - expected fill as ratio of original fill.
2960 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2961 $                   Run with the option -info to determine an optimal value to use
2962 
2963    Notes:
2964    Most users should employ the simplified KSP interface for linear solvers
2965    instead of working directly with matrix algebra routines such as this.
2966    See, e.g., KSPCreate().
2967 
2968    This changes the state of the matrix to a factored matrix; it cannot be used
2969    for example with MatSetValues() unless one first calls MatSetUnfactored().
2970 
2971    Level: developer
2972 
2973    Concepts: matrices^LU factorization
2974 
2975 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2976           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2977 
2978     Developer Note: fortran interface is not autogenerated as the f90
2979     interface defintion cannot be generated correctly [due to MatFactorInfo]
2980 
2981 @*/
2982 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2983 {
2984   PetscErrorCode ierr;
2985   MatFactorInfo  tinfo;
2986 
2987   PetscFunctionBegin;
2988   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2989   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2990   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2991   if (info) PetscValidPointer(info,4);
2992   PetscValidType(mat,1);
2993   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2994   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2995   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2996   MatCheckPreallocated(mat,1);
2997   if (!info) {
2998     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2999     info = &tinfo;
3000   }
3001 
3002   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
3003   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
3004   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
3005   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3006   PetscFunctionReturn(0);
3007 }
3008 
3009 /*@C
3010    MatILUFactor - Performs in-place ILU factorization of matrix.
3011 
3012    Collective on Mat
3013 
3014    Input Parameters:
3015 +  mat - the matrix
3016 .  row - row permutation
3017 .  col - column permutation
3018 -  info - structure containing
3019 $      levels - number of levels of fill.
3020 $      expected fill - as ratio of original fill.
3021 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3022                 missing diagonal entries)
3023 
3024    Notes:
3025    Probably really in-place only when level of fill is zero, otherwise allocates
3026    new space to store factored matrix and deletes previous memory.
3027 
3028    Most users should employ the simplified KSP interface for linear solvers
3029    instead of working directly with matrix algebra routines such as this.
3030    See, e.g., KSPCreate().
3031 
3032    Level: developer
3033 
3034    Concepts: matrices^ILU factorization
3035 
3036 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3037 
3038     Developer Note: fortran interface is not autogenerated as the f90
3039     interface defintion cannot be generated correctly [due to MatFactorInfo]
3040 
3041 @*/
3042 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3043 {
3044   PetscErrorCode ierr;
3045 
3046   PetscFunctionBegin;
3047   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3048   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3049   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3050   PetscValidPointer(info,4);
3051   PetscValidType(mat,1);
3052   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3053   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3054   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3055   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3056   MatCheckPreallocated(mat,1);
3057 
3058   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3059   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3060   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3061   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3062   PetscFunctionReturn(0);
3063 }
3064 
3065 /*@C
3066    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3067    Call this routine before calling MatLUFactorNumeric().
3068 
3069    Collective on Mat
3070 
3071    Input Parameters:
3072 +  fact - the factor matrix obtained with MatGetFactor()
3073 .  mat - the matrix
3074 .  row, col - row and column permutations
3075 -  info - options for factorization, includes
3076 $          fill - expected fill as ratio of original fill.
3077 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3078 $                   Run with the option -info to determine an optimal value to use
3079 
3080 
3081    Notes:
3082     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3083 
3084    Most users should employ the simplified KSP interface for linear solvers
3085    instead of working directly with matrix algebra routines such as this.
3086    See, e.g., KSPCreate().
3087 
3088    Level: developer
3089 
3090    Concepts: matrices^LU symbolic factorization
3091 
3092 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3093 
3094     Developer Note: fortran interface is not autogenerated as the f90
3095     interface defintion cannot be generated correctly [due to MatFactorInfo]
3096 
3097 @*/
3098 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3099 {
3100   PetscErrorCode ierr;
3101 
3102   PetscFunctionBegin;
3103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3104   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3105   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3106   if (info) PetscValidPointer(info,4);
3107   PetscValidType(mat,1);
3108   PetscValidPointer(fact,5);
3109   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3110   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3111   if (!(fact)->ops->lufactorsymbolic) {
3112     MatSolverType spackage;
3113     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3114     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3115   }
3116   MatCheckPreallocated(mat,2);
3117 
3118   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3119   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3120   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3121   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3122   PetscFunctionReturn(0);
3123 }
3124 
3125 /*@C
3126    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3127    Call this routine after first calling MatLUFactorSymbolic().
3128 
3129    Collective on Mat
3130 
3131    Input Parameters:
3132 +  fact - the factor matrix obtained with MatGetFactor()
3133 .  mat - the matrix
3134 -  info - options for factorization
3135 
3136    Notes:
3137    See MatLUFactor() for in-place factorization.  See
3138    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3139 
3140    Most users should employ the simplified KSP interface for linear solvers
3141    instead of working directly with matrix algebra routines such as this.
3142    See, e.g., KSPCreate().
3143 
3144    Level: developer
3145 
3146    Concepts: matrices^LU numeric factorization
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   PetscErrorCode ierr;
3157 
3158   PetscFunctionBegin;
3159   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3160   PetscValidType(mat,1);
3161   PetscValidPointer(fact,2);
3162   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3163   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3164   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);
3165 
3166   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3167   MatCheckPreallocated(mat,2);
3168   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3169   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3170   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3171   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3172   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3173   PetscFunctionReturn(0);
3174 }
3175 
3176 /*@C
3177    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3178    symmetric matrix.
3179 
3180    Collective on Mat
3181 
3182    Input Parameters:
3183 +  mat - the matrix
3184 .  perm - row and column permutations
3185 -  f - expected fill as ratio of original fill
3186 
3187    Notes:
3188    See MatLUFactor() for the nonsymmetric case.  See also
3189    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3190 
3191    Most users should employ the simplified KSP interface for linear solvers
3192    instead of working directly with matrix algebra routines such as this.
3193    See, e.g., KSPCreate().
3194 
3195    Level: developer
3196 
3197    Concepts: matrices^Cholesky factorization
3198 
3199 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3200           MatGetOrdering()
3201 
3202     Developer Note: fortran interface is not autogenerated as the f90
3203     interface defintion cannot be generated correctly [due to MatFactorInfo]
3204 
3205 @*/
3206 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3207 {
3208   PetscErrorCode ierr;
3209 
3210   PetscFunctionBegin;
3211   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3212   PetscValidType(mat,1);
3213   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3214   if (info) PetscValidPointer(info,3);
3215   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3216   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3217   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3218   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3219   MatCheckPreallocated(mat,1);
3220 
3221   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3222   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3223   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3224   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3225   PetscFunctionReturn(0);
3226 }
3227 
3228 /*@C
3229    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3230    of a symmetric matrix.
3231 
3232    Collective on Mat
3233 
3234    Input Parameters:
3235 +  fact - the factor matrix obtained with MatGetFactor()
3236 .  mat - the matrix
3237 .  perm - row and column permutations
3238 -  info - options for factorization, includes
3239 $          fill - expected fill as ratio of original fill.
3240 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3241 $                   Run with the option -info to determine an optimal value to use
3242 
3243    Notes:
3244    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3245    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3246 
3247    Most users should employ the simplified KSP interface for linear solvers
3248    instead of working directly with matrix algebra routines such as this.
3249    See, e.g., KSPCreate().
3250 
3251    Level: developer
3252 
3253    Concepts: matrices^Cholesky symbolic factorization
3254 
3255 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3256           MatGetOrdering()
3257 
3258     Developer Note: fortran interface is not autogenerated as the f90
3259     interface defintion cannot be generated correctly [due to MatFactorInfo]
3260 
3261 @*/
3262 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3263 {
3264   PetscErrorCode ierr;
3265 
3266   PetscFunctionBegin;
3267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3268   PetscValidType(mat,1);
3269   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3270   if (info) PetscValidPointer(info,3);
3271   PetscValidPointer(fact,4);
3272   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3273   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3274   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3275   if (!(fact)->ops->choleskyfactorsymbolic) {
3276     MatSolverType spackage;
3277     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3278     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3279   }
3280   MatCheckPreallocated(mat,2);
3281 
3282   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3283   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3284   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3285   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3286   PetscFunctionReturn(0);
3287 }
3288 
3289 /*@C
3290    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3291    of a symmetric matrix. Call this routine after first calling
3292    MatCholeskyFactorSymbolic().
3293 
3294    Collective on Mat
3295 
3296    Input Parameters:
3297 +  fact - the factor matrix obtained with MatGetFactor()
3298 .  mat - the initial matrix
3299 .  info - options for factorization
3300 -  fact - the symbolic factor of mat
3301 
3302 
3303    Notes:
3304    Most users should employ the simplified KSP interface for linear solvers
3305    instead of working directly with matrix algebra routines such as this.
3306    See, e.g., KSPCreate().
3307 
3308    Level: developer
3309 
3310    Concepts: matrices^Cholesky numeric factorization
3311 
3312 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3313 
3314     Developer Note: fortran interface is not autogenerated as the f90
3315     interface defintion cannot be generated correctly [due to MatFactorInfo]
3316 
3317 @*/
3318 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3319 {
3320   PetscErrorCode ierr;
3321 
3322   PetscFunctionBegin;
3323   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3324   PetscValidType(mat,1);
3325   PetscValidPointer(fact,2);
3326   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3327   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3328   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3329   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);
3330   MatCheckPreallocated(mat,2);
3331 
3332   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3333   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3334   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3335   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3336   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3337   PetscFunctionReturn(0);
3338 }
3339 
3340 /* ----------------------------------------------------------------*/
3341 /*@
3342    MatSolve - Solves A x = b, given a factored matrix.
3343 
3344    Neighbor-wise Collective on Mat and Vec
3345 
3346    Input Parameters:
3347 +  mat - the factored matrix
3348 -  b - the right-hand-side vector
3349 
3350    Output Parameter:
3351 .  x - the result vector
3352 
3353    Notes:
3354    The vectors b and x cannot be the same.  I.e., one cannot
3355    call MatSolve(A,x,x).
3356 
3357    Notes:
3358    Most users should employ the simplified KSP interface for linear solvers
3359    instead of working directly with matrix algebra routines such as this.
3360    See, e.g., KSPCreate().
3361 
3362    Level: developer
3363 
3364    Concepts: matrices^triangular solves
3365 
3366 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3367 @*/
3368 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3369 {
3370   PetscErrorCode ierr;
3371 
3372   PetscFunctionBegin;
3373   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3374   PetscValidType(mat,1);
3375   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3376   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3377   PetscCheckSameComm(mat,1,b,2);
3378   PetscCheckSameComm(mat,1,x,3);
3379   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3380   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);
3381   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);
3382   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);
3383   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3384   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3385   MatCheckPreallocated(mat,1);
3386 
3387   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3388   if (mat->factorerrortype) {
3389     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3390     ierr = VecSetInf(x);CHKERRQ(ierr);
3391   } else {
3392     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3393     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3394   }
3395   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3396   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3397   PetscFunctionReturn(0);
3398 }
3399 
3400 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3401 {
3402   PetscErrorCode ierr;
3403   Vec            b,x;
3404   PetscInt       m,N,i;
3405   PetscScalar    *bb,*xx;
3406   PetscBool      flg;
3407 
3408   PetscFunctionBegin;
3409   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3410   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3411   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3412   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3413 
3414   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3415   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3416   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3417   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3418   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3419   for (i=0; i<N; i++) {
3420     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3421     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3422     if (trans) {
3423       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3424     } else {
3425       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3426     }
3427     ierr = VecResetArray(x);CHKERRQ(ierr);
3428     ierr = VecResetArray(b);CHKERRQ(ierr);
3429   }
3430   ierr = VecDestroy(&b);CHKERRQ(ierr);
3431   ierr = VecDestroy(&x);CHKERRQ(ierr);
3432   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3433   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3434   PetscFunctionReturn(0);
3435 }
3436 
3437 /*@
3438    MatMatSolve - Solves A X = B, given a factored matrix.
3439 
3440    Neighbor-wise Collective on Mat
3441 
3442    Input Parameters:
3443 +  A - the factored matrix
3444 -  B - the right-hand-side matrix  (dense matrix)
3445 
3446    Output Parameter:
3447 .  X - the result matrix (dense matrix)
3448 
3449    Notes:
3450    The matrices b and x cannot be the same.  I.e., one cannot
3451    call MatMatSolve(A,x,x).
3452 
3453    Notes:
3454    Most users should usually employ the simplified KSP interface for linear solvers
3455    instead of working directly with matrix algebra routines such as this.
3456    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3457    at a time.
3458 
3459    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3460    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3461 
3462    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3463 
3464    Level: developer
3465 
3466    Concepts: matrices^triangular solves
3467 
3468 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3469 @*/
3470 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3471 {
3472   PetscErrorCode ierr;
3473 
3474   PetscFunctionBegin;
3475   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3476   PetscValidType(A,1);
3477   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3478   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3479   PetscCheckSameComm(A,1,B,2);
3480   PetscCheckSameComm(A,1,X,3);
3481   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3482   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);
3483   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);
3484   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");
3485   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3486   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3487   MatCheckPreallocated(A,1);
3488 
3489   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3490   if (!A->ops->matsolve) {
3491     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3492     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3493   } else {
3494     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3495   }
3496   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3497   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3498   PetscFunctionReturn(0);
3499 }
3500 
3501 /*@
3502    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3503 
3504    Neighbor-wise Collective on Mat
3505 
3506    Input Parameters:
3507 +  A - the factored matrix
3508 -  B - the right-hand-side matrix  (dense matrix)
3509 
3510    Output Parameter:
3511 .  X - the result matrix (dense matrix)
3512 
3513    Notes:
3514    The matrices B and X cannot be the same.  I.e., one cannot
3515    call MatMatSolveTranspose(A,X,X).
3516 
3517    Notes:
3518    Most users should usually employ the simplified KSP interface for linear solvers
3519    instead of working directly with matrix algebra routines such as this.
3520    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3521    at a time.
3522 
3523    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3524 
3525    Level: developer
3526 
3527    Concepts: matrices^triangular solves
3528 
3529 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3530 @*/
3531 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3532 {
3533   PetscErrorCode ierr;
3534 
3535   PetscFunctionBegin;
3536   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3537   PetscValidType(A,1);
3538   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3539   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3540   PetscCheckSameComm(A,1,B,2);
3541   PetscCheckSameComm(A,1,X,3);
3542   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3543   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);
3544   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);
3545   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);
3546   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");
3547   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3548   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3549   MatCheckPreallocated(A,1);
3550 
3551   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3552   if (!A->ops->matsolvetranspose) {
3553     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3554     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3555   } else {
3556     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3557   }
3558   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3559   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3560   PetscFunctionReturn(0);
3561 }
3562 
3563 /*@
3564    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3565 
3566    Neighbor-wise Collective on Mat
3567 
3568    Input Parameters:
3569 +  A - the factored matrix
3570 -  Bt - the transpose of right-hand-side matrix
3571 
3572    Output Parameter:
3573 .  X - the result matrix (dense matrix)
3574 
3575    Notes:
3576    Most users should usually employ the simplified KSP interface for linear solvers
3577    instead of working directly with matrix algebra routines such as this.
3578    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3579    at a time.
3580 
3581    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().
3582 
3583    Level: developer
3584 
3585    Concepts: matrices^triangular solves
3586 
3587 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3588 @*/
3589 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3590 {
3591   PetscErrorCode ierr;
3592 
3593   PetscFunctionBegin;
3594   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3595   PetscValidType(A,1);
3596   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3597   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3598   PetscCheckSameComm(A,1,Bt,2);
3599   PetscCheckSameComm(A,1,X,3);
3600 
3601   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3602   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);
3603   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);
3604   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");
3605   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3606   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3607   MatCheckPreallocated(A,1);
3608 
3609   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3610   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3611   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3612   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3613   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3614   PetscFunctionReturn(0);
3615 }
3616 
3617 /*@
3618    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3619                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3620 
3621    Neighbor-wise Collective on Mat and Vec
3622 
3623    Input Parameters:
3624 +  mat - the factored matrix
3625 -  b - the right-hand-side vector
3626 
3627    Output Parameter:
3628 .  x - the result vector
3629 
3630    Notes:
3631    MatSolve() should be used for most applications, as it performs
3632    a forward solve followed by a backward solve.
3633 
3634    The vectors b and x cannot be the same,  i.e., one cannot
3635    call MatForwardSolve(A,x,x).
3636 
3637    For matrix in seqsbaij format with block size larger than 1,
3638    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3639    MatForwardSolve() solves U^T*D y = b, and
3640    MatBackwardSolve() solves U x = y.
3641    Thus they do not provide a symmetric preconditioner.
3642 
3643    Most users should employ the simplified KSP interface for linear solvers
3644    instead of working directly with matrix algebra routines such as this.
3645    See, e.g., KSPCreate().
3646 
3647    Level: developer
3648 
3649    Concepts: matrices^forward solves
3650 
3651 .seealso: MatSolve(), MatBackwardSolve()
3652 @*/
3653 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3654 {
3655   PetscErrorCode ierr;
3656 
3657   PetscFunctionBegin;
3658   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3659   PetscValidType(mat,1);
3660   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3661   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3662   PetscCheckSameComm(mat,1,b,2);
3663   PetscCheckSameComm(mat,1,x,3);
3664   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3665   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);
3666   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);
3667   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);
3668   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3669   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3670   MatCheckPreallocated(mat,1);
3671 
3672   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3673   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3674   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3675   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3676   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3677   PetscFunctionReturn(0);
3678 }
3679 
3680 /*@
3681    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3682                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3683 
3684    Neighbor-wise Collective on Mat and Vec
3685 
3686    Input Parameters:
3687 +  mat - the factored matrix
3688 -  b - the right-hand-side vector
3689 
3690    Output Parameter:
3691 .  x - the result vector
3692 
3693    Notes:
3694    MatSolve() should be used for most applications, as it performs
3695    a forward solve followed by a backward solve.
3696 
3697    The vectors b and x cannot be the same.  I.e., one cannot
3698    call MatBackwardSolve(A,x,x).
3699 
3700    For matrix in seqsbaij format with block size larger than 1,
3701    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3702    MatForwardSolve() solves U^T*D y = b, and
3703    MatBackwardSolve() solves U x = y.
3704    Thus they do not provide a symmetric preconditioner.
3705 
3706    Most users should employ the simplified KSP interface for linear solvers
3707    instead of working directly with matrix algebra routines such as this.
3708    See, e.g., KSPCreate().
3709 
3710    Level: developer
3711 
3712    Concepts: matrices^backward solves
3713 
3714 .seealso: MatSolve(), MatForwardSolve()
3715 @*/
3716 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3717 {
3718   PetscErrorCode ierr;
3719 
3720   PetscFunctionBegin;
3721   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3722   PetscValidType(mat,1);
3723   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3724   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3725   PetscCheckSameComm(mat,1,b,2);
3726   PetscCheckSameComm(mat,1,x,3);
3727   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3728   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);
3729   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);
3730   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);
3731   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3732   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3733   MatCheckPreallocated(mat,1);
3734 
3735   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3736   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3737   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3738   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3739   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3740   PetscFunctionReturn(0);
3741 }
3742 
3743 /*@
3744    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3745 
3746    Neighbor-wise Collective on Mat and Vec
3747 
3748    Input Parameters:
3749 +  mat - the factored matrix
3750 .  b - the right-hand-side vector
3751 -  y - the vector to be added to
3752 
3753    Output Parameter:
3754 .  x - the result vector
3755 
3756    Notes:
3757    The vectors b and x cannot be the same.  I.e., one cannot
3758    call MatSolveAdd(A,x,y,x).
3759 
3760    Most users should employ the simplified KSP interface for linear solvers
3761    instead of working directly with matrix algebra routines such as this.
3762    See, e.g., KSPCreate().
3763 
3764    Level: developer
3765 
3766    Concepts: matrices^triangular solves
3767 
3768 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3769 @*/
3770 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3771 {
3772   PetscScalar    one = 1.0;
3773   Vec            tmp;
3774   PetscErrorCode ierr;
3775 
3776   PetscFunctionBegin;
3777   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3778   PetscValidType(mat,1);
3779   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3780   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3781   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3782   PetscCheckSameComm(mat,1,b,2);
3783   PetscCheckSameComm(mat,1,y,2);
3784   PetscCheckSameComm(mat,1,x,3);
3785   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3786   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3787   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3788   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3789   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3790   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3791   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3792   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3793   MatCheckPreallocated(mat,1);
3794 
3795   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3796   if (mat->ops->solveadd) {
3797     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3798   } else {
3799     /* do the solve then the add manually */
3800     if (x != y) {
3801       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3802       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3803     } else {
3804       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3805       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3806       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3807       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3808       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3809       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3810     }
3811   }
3812   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3813   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3814   PetscFunctionReturn(0);
3815 }
3816 
3817 /*@
3818    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3819 
3820    Neighbor-wise Collective on Mat and Vec
3821 
3822    Input Parameters:
3823 +  mat - the factored matrix
3824 -  b - the right-hand-side vector
3825 
3826    Output Parameter:
3827 .  x - the result vector
3828 
3829    Notes:
3830    The vectors b and x cannot be the same.  I.e., one cannot
3831    call MatSolveTranspose(A,x,x).
3832 
3833    Most users should employ the simplified KSP interface for linear solvers
3834    instead of working directly with matrix algebra routines such as this.
3835    See, e.g., KSPCreate().
3836 
3837    Level: developer
3838 
3839    Concepts: matrices^triangular solves
3840 
3841 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3842 @*/
3843 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3844 {
3845   PetscErrorCode ierr;
3846 
3847   PetscFunctionBegin;
3848   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3849   PetscValidType(mat,1);
3850   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3851   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3852   PetscCheckSameComm(mat,1,b,2);
3853   PetscCheckSameComm(mat,1,x,3);
3854   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3855   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3856   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3857   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3858   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3859   MatCheckPreallocated(mat,1);
3860   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3861   if (mat->factorerrortype) {
3862     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3863     ierr = VecSetInf(x);CHKERRQ(ierr);
3864   } else {
3865     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3866     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3867   }
3868   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3869   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3870   PetscFunctionReturn(0);
3871 }
3872 
3873 /*@
3874    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3875                       factored matrix.
3876 
3877    Neighbor-wise Collective on Mat and Vec
3878 
3879    Input Parameters:
3880 +  mat - the factored matrix
3881 .  b - the right-hand-side vector
3882 -  y - the vector to be added to
3883 
3884    Output Parameter:
3885 .  x - the result vector
3886 
3887    Notes:
3888    The vectors b and x cannot be the same.  I.e., one cannot
3889    call MatSolveTransposeAdd(A,x,y,x).
3890 
3891    Most users should employ the simplified KSP interface for linear solvers
3892    instead of working directly with matrix algebra routines such as this.
3893    See, e.g., KSPCreate().
3894 
3895    Level: developer
3896 
3897    Concepts: matrices^triangular solves
3898 
3899 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3900 @*/
3901 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3902 {
3903   PetscScalar    one = 1.0;
3904   PetscErrorCode ierr;
3905   Vec            tmp;
3906 
3907   PetscFunctionBegin;
3908   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3909   PetscValidType(mat,1);
3910   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3911   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3912   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3913   PetscCheckSameComm(mat,1,b,2);
3914   PetscCheckSameComm(mat,1,y,3);
3915   PetscCheckSameComm(mat,1,x,4);
3916   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3917   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);
3918   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);
3919   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);
3920   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);
3921   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3922   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3923   MatCheckPreallocated(mat,1);
3924 
3925   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3926   if (mat->ops->solvetransposeadd) {
3927     if (mat->factorerrortype) {
3928       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3929       ierr = VecSetInf(x);CHKERRQ(ierr);
3930     } else {
3931       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3932     }
3933   } else {
3934     /* do the solve then the add manually */
3935     if (x != y) {
3936       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3937       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3938     } else {
3939       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3940       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3941       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3942       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3943       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3944       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3945     }
3946   }
3947   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3948   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3949   PetscFunctionReturn(0);
3950 }
3951 /* ----------------------------------------------------------------*/
3952 
3953 /*@
3954    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3955 
3956    Neighbor-wise Collective on Mat and Vec
3957 
3958    Input Parameters:
3959 +  mat - the matrix
3960 .  b - the right hand side
3961 .  omega - the relaxation factor
3962 .  flag - flag indicating the type of SOR (see below)
3963 .  shift -  diagonal shift
3964 .  its - the number of iterations
3965 -  lits - the number of local iterations
3966 
3967    Output Parameters:
3968 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3969 
3970    SOR Flags:
3971 .     SOR_FORWARD_SWEEP - forward SOR
3972 .     SOR_BACKWARD_SWEEP - backward SOR
3973 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3974 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3975 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3976 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3977 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3978          upper/lower triangular part of matrix to
3979          vector (with omega)
3980 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3981 
3982    Notes:
3983    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3984    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3985    on each processor.
3986 
3987    Application programmers will not generally use MatSOR() directly,
3988    but instead will employ the KSP/PC interface.
3989 
3990    Notes:
3991     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3992 
3993    Notes for Advanced Users:
3994    The flags are implemented as bitwise inclusive or operations.
3995    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3996    to specify a zero initial guess for SSOR.
3997 
3998    Most users should employ the simplified KSP interface for linear solvers
3999    instead of working directly with matrix algebra routines such as this.
4000    See, e.g., KSPCreate().
4001 
4002    Vectors x and b CANNOT be the same
4003 
4004    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
4005 
4006    Level: developer
4007 
4008    Concepts: matrices^relaxation
4009    Concepts: matrices^SOR
4010    Concepts: matrices^Gauss-Seidel
4011 
4012 @*/
4013 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4014 {
4015   PetscErrorCode ierr;
4016 
4017   PetscFunctionBegin;
4018   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4019   PetscValidType(mat,1);
4020   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4021   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4022   PetscCheckSameComm(mat,1,b,2);
4023   PetscCheckSameComm(mat,1,x,8);
4024   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4025   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4026   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4027   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);
4028   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);
4029   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);
4030   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4031   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4032   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4033 
4034   MatCheckPreallocated(mat,1);
4035   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4036   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4037   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4038   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4039   PetscFunctionReturn(0);
4040 }
4041 
4042 /*
4043       Default matrix copy routine.
4044 */
4045 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4046 {
4047   PetscErrorCode    ierr;
4048   PetscInt          i,rstart = 0,rend = 0,nz;
4049   const PetscInt    *cwork;
4050   const PetscScalar *vwork;
4051 
4052   PetscFunctionBegin;
4053   if (B->assembled) {
4054     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4055   }
4056   if (str == SAME_NONZERO_PATTERN) {
4057     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4058     for (i=rstart; i<rend; i++) {
4059       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4060       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4061       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4062     }
4063   } else {
4064     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4065   }
4066   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4067   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4068   PetscFunctionReturn(0);
4069 }
4070 
4071 /*@
4072    MatCopy - Copies a matrix to another matrix.
4073 
4074    Collective on Mat
4075 
4076    Input Parameters:
4077 +  A - the matrix
4078 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4079 
4080    Output Parameter:
4081 .  B - where the copy is put
4082 
4083    Notes:
4084    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4085    same nonzero pattern or the routine will crash.
4086 
4087    MatCopy() copies the matrix entries of a matrix to another existing
4088    matrix (after first zeroing the second matrix).  A related routine is
4089    MatConvert(), which first creates a new matrix and then copies the data.
4090 
4091    Level: intermediate
4092 
4093    Concepts: matrices^copying
4094 
4095 .seealso: MatConvert(), MatDuplicate()
4096 
4097 @*/
4098 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4099 {
4100   PetscErrorCode ierr;
4101   PetscInt       i;
4102 
4103   PetscFunctionBegin;
4104   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4105   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4106   PetscValidType(A,1);
4107   PetscValidType(B,2);
4108   PetscCheckSameComm(A,1,B,2);
4109   MatCheckPreallocated(B,2);
4110   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4111   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4112   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);
4113   MatCheckPreallocated(A,1);
4114   if (A == B) PetscFunctionReturn(0);
4115 
4116   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4117   if (A->ops->copy) {
4118     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4119   } else { /* generic conversion */
4120     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4121   }
4122 
4123   B->stencil.dim = A->stencil.dim;
4124   B->stencil.noc = A->stencil.noc;
4125   for (i=0; i<=A->stencil.dim; i++) {
4126     B->stencil.dims[i]   = A->stencil.dims[i];
4127     B->stencil.starts[i] = A->stencil.starts[i];
4128   }
4129 
4130   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4131   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4132   PetscFunctionReturn(0);
4133 }
4134 
4135 /*@C
4136    MatConvert - Converts a matrix to another matrix, either of the same
4137    or different type.
4138 
4139    Collective on Mat
4140 
4141    Input Parameters:
4142 +  mat - the matrix
4143 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4144    same type as the original matrix.
4145 -  reuse - denotes if the destination matrix is to be created or reused.
4146    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
4147    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).
4148 
4149    Output Parameter:
4150 .  M - pointer to place new matrix
4151 
4152    Notes:
4153    MatConvert() first creates a new matrix and then copies the data from
4154    the first matrix.  A related routine is MatCopy(), which copies the matrix
4155    entries of one matrix to another already existing matrix context.
4156 
4157    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4158    the MPI communicator of the generated matrix is always the same as the communicator
4159    of the input matrix.
4160 
4161    Level: intermediate
4162 
4163    Concepts: matrices^converting between storage formats
4164 
4165 .seealso: MatCopy(), MatDuplicate()
4166 @*/
4167 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4168 {
4169   PetscErrorCode ierr;
4170   PetscBool      sametype,issame,flg;
4171   char           convname[256],mtype[256];
4172   Mat            B;
4173 
4174   PetscFunctionBegin;
4175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4176   PetscValidType(mat,1);
4177   PetscValidPointer(M,3);
4178   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4179   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4180   MatCheckPreallocated(mat,1);
4181 
4182   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4183   if (flg) {
4184     newtype = mtype;
4185   }
4186   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4187   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4188   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4189   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");
4190 
4191   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4192 
4193   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4194     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4195   } else {
4196     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4197     const char     *prefix[3] = {"seq","mpi",""};
4198     PetscInt       i;
4199     /*
4200        Order of precedence:
4201        0) See if newtype is a superclass of the current matrix.
4202        1) See if a specialized converter is known to the current matrix.
4203        2) See if a specialized converter is known to the desired matrix class.
4204        3) See if a good general converter is registered for the desired class
4205           (as of 6/27/03 only MATMPIADJ falls into this category).
4206        4) See if a good general converter is known for the current matrix.
4207        5) Use a really basic converter.
4208     */
4209 
4210     /* 0) See if newtype is a superclass of the current matrix.
4211           i.e mat is mpiaij and newtype is aij */
4212     for (i=0; i<2; i++) {
4213       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4214       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4215       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4216       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4217       if (flg) {
4218         if (reuse == MAT_INPLACE_MATRIX) {
4219           PetscFunctionReturn(0);
4220         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4221           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4222           PetscFunctionReturn(0);
4223         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4224           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4225           PetscFunctionReturn(0);
4226         }
4227       }
4228     }
4229     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4230     for (i=0; i<3; i++) {
4231       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4232       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4233       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4234       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4235       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4236       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4237       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4238       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4239       if (conv) goto foundconv;
4240     }
4241 
4242     /* 2)  See if a specialized converter is known to the desired matrix class. */
4243     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4244     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4245     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4246     for (i=0; i<3; i++) {
4247       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4248       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4249       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4250       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4251       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4252       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4253       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4254       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4255       if (conv) {
4256         ierr = MatDestroy(&B);CHKERRQ(ierr);
4257         goto foundconv;
4258       }
4259     }
4260 
4261     /* 3) See if a good general converter is registered for the desired class */
4262     conv = B->ops->convertfrom;
4263     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4264     ierr = MatDestroy(&B);CHKERRQ(ierr);
4265     if (conv) goto foundconv;
4266 
4267     /* 4) See if a good general converter is known for the current matrix */
4268     if (mat->ops->convert) {
4269       conv = mat->ops->convert;
4270     }
4271     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4272     if (conv) goto foundconv;
4273 
4274     /* 5) Use a really basic converter. */
4275     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4276     conv = MatConvert_Basic;
4277 
4278 foundconv:
4279     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4280     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4281     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4282       /* the block sizes must be same if the mappings are copied over */
4283       (*M)->rmap->bs = mat->rmap->bs;
4284       (*M)->cmap->bs = mat->cmap->bs;
4285       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4286       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4287       (*M)->rmap->mapping = mat->rmap->mapping;
4288       (*M)->cmap->mapping = mat->cmap->mapping;
4289     }
4290     (*M)->stencil.dim = mat->stencil.dim;
4291     (*M)->stencil.noc = mat->stencil.noc;
4292     for (i=0; i<=mat->stencil.dim; i++) {
4293       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4294       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4295     }
4296     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4297   }
4298   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4299 
4300   /* Copy Mat options */
4301   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4302   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4303   PetscFunctionReturn(0);
4304 }
4305 
4306 /*@C
4307    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4308 
4309    Not Collective
4310 
4311    Input Parameter:
4312 .  mat - the matrix, must be a factored matrix
4313 
4314    Output Parameter:
4315 .   type - the string name of the package (do not free this string)
4316 
4317    Notes:
4318       In Fortran you pass in a empty string and the package name will be copied into it.
4319     (Make sure the string is long enough)
4320 
4321    Level: intermediate
4322 
4323 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4324 @*/
4325 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4326 {
4327   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4328 
4329   PetscFunctionBegin;
4330   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4331   PetscValidType(mat,1);
4332   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4333   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4334   if (!conv) {
4335     *type = MATSOLVERPETSC;
4336   } else {
4337     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4338   }
4339   PetscFunctionReturn(0);
4340 }
4341 
4342 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4343 struct _MatSolverTypeForSpecifcType {
4344   MatType                        mtype;
4345   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4346   MatSolverTypeForSpecifcType next;
4347 };
4348 
4349 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4350 struct _MatSolverTypeHolder {
4351   char                           *name;
4352   MatSolverTypeForSpecifcType handlers;
4353   MatSolverTypeHolder         next;
4354 };
4355 
4356 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4357 
4358 /*@C
4359    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4360 
4361    Input Parameters:
4362 +    package - name of the package, for example petsc or superlu
4363 .    mtype - the matrix type that works with this package
4364 .    ftype - the type of factorization supported by the package
4365 -    getfactor - routine that will create the factored matrix ready to be used
4366 
4367     Level: intermediate
4368 
4369 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4370 @*/
4371 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4372 {
4373   PetscErrorCode              ierr;
4374   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4375   PetscBool                   flg;
4376   MatSolverTypeForSpecifcType inext,iprev = NULL;
4377 
4378   PetscFunctionBegin;
4379   ierr = MatInitializePackage();CHKERRQ(ierr);
4380   if (!next) {
4381     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4382     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4383     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4384     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4385     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4386     PetscFunctionReturn(0);
4387   }
4388   while (next) {
4389     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4390     if (flg) {
4391       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4392       inext = next->handlers;
4393       while (inext) {
4394         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4395         if (flg) {
4396           inext->getfactor[(int)ftype-1] = getfactor;
4397           PetscFunctionReturn(0);
4398         }
4399         iprev = inext;
4400         inext = inext->next;
4401       }
4402       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4403       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4404       iprev->next->getfactor[(int)ftype-1] = getfactor;
4405       PetscFunctionReturn(0);
4406     }
4407     prev = next;
4408     next = next->next;
4409   }
4410   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4411   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4412   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4413   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4414   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4415   PetscFunctionReturn(0);
4416 }
4417 
4418 /*@C
4419    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4420 
4421    Input Parameters:
4422 +    package - name of the package, for example petsc or superlu
4423 .    ftype - the type of factorization supported by the package
4424 -    mtype - the matrix type that works with this package
4425 
4426    Output Parameters:
4427 +   foundpackage - PETSC_TRUE if the package was registered
4428 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4429 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4430 
4431     Level: intermediate
4432 
4433 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4434 @*/
4435 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4436 {
4437   PetscErrorCode                 ierr;
4438   MatSolverTypeHolder         next = MatSolverTypeHolders;
4439   PetscBool                      flg;
4440   MatSolverTypeForSpecifcType inext;
4441 
4442   PetscFunctionBegin;
4443   if (foundpackage) *foundpackage = PETSC_FALSE;
4444   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4445   if (getfactor)    *getfactor    = NULL;
4446 
4447   if (package) {
4448     while (next) {
4449       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4450       if (flg) {
4451         if (foundpackage) *foundpackage = PETSC_TRUE;
4452         inext = next->handlers;
4453         while (inext) {
4454           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4455           if (flg) {
4456             if (foundmtype) *foundmtype = PETSC_TRUE;
4457             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4458             PetscFunctionReturn(0);
4459           }
4460           inext = inext->next;
4461         }
4462       }
4463       next = next->next;
4464     }
4465   } else {
4466     while (next) {
4467       inext = next->handlers;
4468       while (inext) {
4469         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4470         if (flg && inext->getfactor[(int)ftype-1]) {
4471           if (foundpackage) *foundpackage = PETSC_TRUE;
4472           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4473           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4474           PetscFunctionReturn(0);
4475         }
4476         inext = inext->next;
4477       }
4478       next = next->next;
4479     }
4480   }
4481   PetscFunctionReturn(0);
4482 }
4483 
4484 PetscErrorCode MatSolverTypeDestroy(void)
4485 {
4486   PetscErrorCode              ierr;
4487   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4488   MatSolverTypeForSpecifcType inext,iprev;
4489 
4490   PetscFunctionBegin;
4491   while (next) {
4492     ierr = PetscFree(next->name);CHKERRQ(ierr);
4493     inext = next->handlers;
4494     while (inext) {
4495       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4496       iprev = inext;
4497       inext = inext->next;
4498       ierr = PetscFree(iprev);CHKERRQ(ierr);
4499     }
4500     prev = next;
4501     next = next->next;
4502     ierr = PetscFree(prev);CHKERRQ(ierr);
4503   }
4504   MatSolverTypeHolders = NULL;
4505   PetscFunctionReturn(0);
4506 }
4507 
4508 /*@C
4509    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4510 
4511    Collective on Mat
4512 
4513    Input Parameters:
4514 +  mat - the matrix
4515 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4516 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4517 
4518    Output Parameters:
4519 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4520 
4521    Notes:
4522       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4523      such as pastix, superlu, mumps etc.
4524 
4525       PETSc must have been ./configure to use the external solver, using the option --download-package
4526 
4527    Level: intermediate
4528 
4529 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4530 @*/
4531 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4532 {
4533   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4534   PetscBool      foundpackage,foundmtype;
4535 
4536   PetscFunctionBegin;
4537   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4538   PetscValidType(mat,1);
4539 
4540   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4541   MatCheckPreallocated(mat,1);
4542 
4543   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4544   if (!foundpackage) {
4545     if (type) {
4546       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4547     } else {
4548       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4549     }
4550   }
4551 
4552   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4553   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);
4554 
4555 #if defined(PETSC_USE_COMPLEX)
4556   if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported");
4557 #endif
4558 
4559   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4560   PetscFunctionReturn(0);
4561 }
4562 
4563 /*@C
4564    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4565 
4566    Not Collective
4567 
4568    Input Parameters:
4569 +  mat - the matrix
4570 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4571 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4572 
4573    Output Parameter:
4574 .    flg - PETSC_TRUE if the factorization is available
4575 
4576    Notes:
4577       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4578      such as pastix, superlu, mumps etc.
4579 
4580       PETSc must have been ./configure to use the external solver, using the option --download-package
4581 
4582    Level: intermediate
4583 
4584 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4585 @*/
4586 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4587 {
4588   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4589 
4590   PetscFunctionBegin;
4591   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4592   PetscValidType(mat,1);
4593 
4594   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4595   MatCheckPreallocated(mat,1);
4596 
4597   *flg = PETSC_FALSE;
4598   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4599   if (gconv) {
4600     *flg = PETSC_TRUE;
4601   }
4602   PetscFunctionReturn(0);
4603 }
4604 
4605 #include <petscdmtypes.h>
4606 
4607 /*@
4608    MatDuplicate - Duplicates a matrix including the non-zero structure.
4609 
4610    Collective on Mat
4611 
4612    Input Parameters:
4613 +  mat - the matrix
4614 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4615         See the manual page for MatDuplicateOption for an explanation of these options.
4616 
4617    Output Parameter:
4618 .  M - pointer to place new matrix
4619 
4620    Level: intermediate
4621 
4622    Concepts: matrices^duplicating
4623 
4624    Notes:
4625     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4626     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.
4627 
4628 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4629 @*/
4630 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4631 {
4632   PetscErrorCode ierr;
4633   Mat            B;
4634   PetscInt       i;
4635   DM             dm;
4636   void           (*viewf)(void);
4637 
4638   PetscFunctionBegin;
4639   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4640   PetscValidType(mat,1);
4641   PetscValidPointer(M,3);
4642   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4643   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4644   MatCheckPreallocated(mat,1);
4645 
4646   *M = 0;
4647   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4648   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4649   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4650   B    = *M;
4651 
4652   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4653   if (viewf) {
4654     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4655   }
4656 
4657   B->stencil.dim = mat->stencil.dim;
4658   B->stencil.noc = mat->stencil.noc;
4659   for (i=0; i<=mat->stencil.dim; i++) {
4660     B->stencil.dims[i]   = mat->stencil.dims[i];
4661     B->stencil.starts[i] = mat->stencil.starts[i];
4662   }
4663 
4664   B->nooffproczerorows = mat->nooffproczerorows;
4665   B->nooffprocentries  = mat->nooffprocentries;
4666 
4667   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4668   if (dm) {
4669     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4670   }
4671   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4672   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4673   PetscFunctionReturn(0);
4674 }
4675 
4676 /*@
4677    MatGetDiagonal - Gets the diagonal of a matrix.
4678 
4679    Logically Collective on Mat and Vec
4680 
4681    Input Parameters:
4682 +  mat - the matrix
4683 -  v - the vector for storing the diagonal
4684 
4685    Output Parameter:
4686 .  v - the diagonal of the matrix
4687 
4688    Level: intermediate
4689 
4690    Note:
4691    Currently only correct in parallel for square matrices.
4692 
4693    Concepts: matrices^accessing diagonals
4694 
4695 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4696 @*/
4697 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4698 {
4699   PetscErrorCode ierr;
4700 
4701   PetscFunctionBegin;
4702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4703   PetscValidType(mat,1);
4704   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4705   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4706   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4707   MatCheckPreallocated(mat,1);
4708 
4709   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4710   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4711   PetscFunctionReturn(0);
4712 }
4713 
4714 /*@C
4715    MatGetRowMin - Gets the minimum value (of the real part) of each
4716         row of the matrix
4717 
4718    Logically Collective on Mat and Vec
4719 
4720    Input Parameters:
4721 .  mat - the matrix
4722 
4723    Output Parameter:
4724 +  v - the vector for storing the maximums
4725 -  idx - the indices of the column found for each row (optional)
4726 
4727    Level: intermediate
4728 
4729    Notes:
4730     The result of this call are the same as if one converted the matrix to dense format
4731       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4732 
4733     This code is only implemented for a couple of matrix formats.
4734 
4735    Concepts: matrices^getting row maximums
4736 
4737 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4738           MatGetRowMax()
4739 @*/
4740 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4741 {
4742   PetscErrorCode ierr;
4743 
4744   PetscFunctionBegin;
4745   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4746   PetscValidType(mat,1);
4747   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4748   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4749   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4750   MatCheckPreallocated(mat,1);
4751 
4752   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4753   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4754   PetscFunctionReturn(0);
4755 }
4756 
4757 /*@C
4758    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4759         row of the matrix
4760 
4761    Logically Collective on Mat and Vec
4762 
4763    Input Parameters:
4764 .  mat - the matrix
4765 
4766    Output Parameter:
4767 +  v - the vector for storing the minimums
4768 -  idx - the indices of the column found for each row (or NULL if not needed)
4769 
4770    Level: intermediate
4771 
4772    Notes:
4773     if a row is completely empty or has only 0.0 values then the idx[] value for that
4774     row is 0 (the first column).
4775 
4776     This code is only implemented for a couple of matrix formats.
4777 
4778    Concepts: matrices^getting row maximums
4779 
4780 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4781 @*/
4782 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4783 {
4784   PetscErrorCode ierr;
4785 
4786   PetscFunctionBegin;
4787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4788   PetscValidType(mat,1);
4789   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4790   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4791   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4792   MatCheckPreallocated(mat,1);
4793   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4794 
4795   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4796   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4797   PetscFunctionReturn(0);
4798 }
4799 
4800 /*@C
4801    MatGetRowMax - Gets the maximum value (of the real part) of each
4802         row of the matrix
4803 
4804    Logically Collective on Mat and Vec
4805 
4806    Input Parameters:
4807 .  mat - the matrix
4808 
4809    Output Parameter:
4810 +  v - the vector for storing the maximums
4811 -  idx - the indices of the column found for each row (optional)
4812 
4813    Level: intermediate
4814 
4815    Notes:
4816     The result of this call are the same as if one converted the matrix to dense format
4817       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4818 
4819     This code is only implemented for a couple of matrix formats.
4820 
4821    Concepts: matrices^getting row maximums
4822 
4823 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4824 @*/
4825 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4826 {
4827   PetscErrorCode ierr;
4828 
4829   PetscFunctionBegin;
4830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4831   PetscValidType(mat,1);
4832   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4833   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4834   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4835   MatCheckPreallocated(mat,1);
4836 
4837   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4838   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4839   PetscFunctionReturn(0);
4840 }
4841 
4842 /*@C
4843    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4844         row of the matrix
4845 
4846    Logically Collective on Mat and Vec
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 (or NULL if not needed)
4854 
4855    Level: intermediate
4856 
4857    Notes:
4858     if a row is completely empty or has only 0.0 values then the idx[] value for that
4859     row is 0 (the first column).
4860 
4861     This code is only implemented for a couple of matrix formats.
4862 
4863    Concepts: matrices^getting row maximums
4864 
4865 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4866 @*/
4867 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4868 {
4869   PetscErrorCode ierr;
4870 
4871   PetscFunctionBegin;
4872   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4873   PetscValidType(mat,1);
4874   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4875   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4876   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4877   MatCheckPreallocated(mat,1);
4878   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4879 
4880   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4881   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4882   PetscFunctionReturn(0);
4883 }
4884 
4885 /*@
4886    MatGetRowSum - Gets the sum of each row of the matrix
4887 
4888    Logically or Neighborhood Collective on Mat and Vec
4889 
4890    Input Parameters:
4891 .  mat - the matrix
4892 
4893    Output Parameter:
4894 .  v - the vector for storing the sum of rows
4895 
4896    Level: intermediate
4897 
4898    Notes:
4899     This code is slow since it is not currently specialized for different formats
4900 
4901    Concepts: matrices^getting row sums
4902 
4903 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4904 @*/
4905 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4906 {
4907   Vec            ones;
4908   PetscErrorCode ierr;
4909 
4910   PetscFunctionBegin;
4911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4912   PetscValidType(mat,1);
4913   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4914   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4915   MatCheckPreallocated(mat,1);
4916   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4917   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4918   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4919   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4920   PetscFunctionReturn(0);
4921 }
4922 
4923 /*@
4924    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4925 
4926    Collective on Mat
4927 
4928    Input Parameter:
4929 +  mat - the matrix to transpose
4930 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4931 
4932    Output Parameters:
4933 .  B - the transpose
4934 
4935    Notes:
4936      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4937 
4938      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4939 
4940      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4941 
4942    Level: intermediate
4943 
4944    Concepts: matrices^transposing
4945 
4946 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4947 @*/
4948 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4949 {
4950   PetscErrorCode ierr;
4951 
4952   PetscFunctionBegin;
4953   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4954   PetscValidType(mat,1);
4955   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4956   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4957   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4958   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4959   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4960   MatCheckPreallocated(mat,1);
4961 
4962   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4963   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4964   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4965   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4966   PetscFunctionReturn(0);
4967 }
4968 
4969 /*@
4970    MatIsTranspose - Test whether a matrix is another one's transpose,
4971         or its own, in which case it tests symmetry.
4972 
4973    Collective on Mat
4974 
4975    Input Parameter:
4976 +  A - the matrix to test
4977 -  B - the matrix to test against, this can equal the first parameter
4978 
4979    Output Parameters:
4980 .  flg - the result
4981 
4982    Notes:
4983    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4984    has a running time of the order of the number of nonzeros; the parallel
4985    test involves parallel copies of the block-offdiagonal parts of the matrix.
4986 
4987    Level: intermediate
4988 
4989    Concepts: matrices^transposing, matrix^symmetry
4990 
4991 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4992 @*/
4993 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4994 {
4995   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4996 
4997   PetscFunctionBegin;
4998   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4999   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5000   PetscValidPointer(flg,3);
5001   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
5002   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
5003   *flg = PETSC_FALSE;
5004   if (f && g) {
5005     if (f == g) {
5006       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5007     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5008   } else {
5009     MatType mattype;
5010     if (!f) {
5011       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5012     } else {
5013       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5014     }
5015     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
5016   }
5017   PetscFunctionReturn(0);
5018 }
5019 
5020 /*@
5021    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5022 
5023    Collective on Mat
5024 
5025    Input Parameter:
5026 +  mat - the matrix to transpose and complex conjugate
5027 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5028 
5029    Output Parameters:
5030 .  B - the Hermitian
5031 
5032    Level: intermediate
5033 
5034    Concepts: matrices^transposing, complex conjugatex
5035 
5036 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5037 @*/
5038 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5039 {
5040   PetscErrorCode ierr;
5041 
5042   PetscFunctionBegin;
5043   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5044 #if defined(PETSC_USE_COMPLEX)
5045   ierr = MatConjugate(*B);CHKERRQ(ierr);
5046 #endif
5047   PetscFunctionReturn(0);
5048 }
5049 
5050 /*@
5051    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5052 
5053    Collective on Mat
5054 
5055    Input Parameter:
5056 +  A - the matrix to test
5057 -  B - the matrix to test against, this can equal the first parameter
5058 
5059    Output Parameters:
5060 .  flg - the result
5061 
5062    Notes:
5063    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5064    has a running time of the order of the number of nonzeros; the parallel
5065    test involves parallel copies of the block-offdiagonal parts of the matrix.
5066 
5067    Level: intermediate
5068 
5069    Concepts: matrices^transposing, matrix^symmetry
5070 
5071 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5072 @*/
5073 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5074 {
5075   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5076 
5077   PetscFunctionBegin;
5078   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5079   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5080   PetscValidPointer(flg,3);
5081   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5082   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5083   if (f && g) {
5084     if (f==g) {
5085       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5086     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5087   }
5088   PetscFunctionReturn(0);
5089 }
5090 
5091 /*@
5092    MatPermute - Creates a new matrix with rows and columns permuted from the
5093    original.
5094 
5095    Collective on Mat
5096 
5097    Input Parameters:
5098 +  mat - the matrix to permute
5099 .  row - row permutation, each processor supplies only the permutation for its rows
5100 -  col - column permutation, each processor supplies only the permutation for its columns
5101 
5102    Output Parameters:
5103 .  B - the permuted matrix
5104 
5105    Level: advanced
5106 
5107    Note:
5108    The index sets map from row/col of permuted matrix to row/col of original matrix.
5109    The index sets should be on the same communicator as Mat and have the same local sizes.
5110 
5111    Concepts: matrices^permuting
5112 
5113 .seealso: MatGetOrdering(), ISAllGather()
5114 
5115 @*/
5116 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5117 {
5118   PetscErrorCode ierr;
5119 
5120   PetscFunctionBegin;
5121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5122   PetscValidType(mat,1);
5123   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5124   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5125   PetscValidPointer(B,4);
5126   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5127   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5128   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5129   MatCheckPreallocated(mat,1);
5130 
5131   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5132   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5133   PetscFunctionReturn(0);
5134 }
5135 
5136 /*@
5137    MatEqual - Compares two matrices.
5138 
5139    Collective on Mat
5140 
5141    Input Parameters:
5142 +  A - the first matrix
5143 -  B - the second matrix
5144 
5145    Output Parameter:
5146 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5147 
5148    Level: intermediate
5149 
5150    Concepts: matrices^equality between
5151 @*/
5152 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5153 {
5154   PetscErrorCode ierr;
5155 
5156   PetscFunctionBegin;
5157   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5158   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5159   PetscValidType(A,1);
5160   PetscValidType(B,2);
5161   PetscValidIntPointer(flg,3);
5162   PetscCheckSameComm(A,1,B,2);
5163   MatCheckPreallocated(B,2);
5164   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5165   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5166   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);
5167   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5168   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5169   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);
5170   MatCheckPreallocated(A,1);
5171 
5172   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5173   PetscFunctionReturn(0);
5174 }
5175 
5176 /*@
5177    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5178    matrices that are stored as vectors.  Either of the two scaling
5179    matrices can be NULL.
5180 
5181    Collective on Mat
5182 
5183    Input Parameters:
5184 +  mat - the matrix to be scaled
5185 .  l - the left scaling vector (or NULL)
5186 -  r - the right scaling vector (or NULL)
5187 
5188    Notes:
5189    MatDiagonalScale() computes A = LAR, where
5190    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5191    The L scales the rows of the matrix, the R scales the columns of the matrix.
5192 
5193    Level: intermediate
5194 
5195    Concepts: matrices^diagonal scaling
5196    Concepts: diagonal scaling of matrices
5197 
5198 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5199 @*/
5200 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5201 {
5202   PetscErrorCode ierr;
5203 
5204   PetscFunctionBegin;
5205   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5206   PetscValidType(mat,1);
5207   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5208   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5209   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5210   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5211   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5212   MatCheckPreallocated(mat,1);
5213 
5214   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5215   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5216   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5217   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5218 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5219   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5220     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5221   }
5222 #endif
5223   PetscFunctionReturn(0);
5224 }
5225 
5226 /*@
5227     MatScale - Scales all elements of a matrix by a given number.
5228 
5229     Logically Collective on Mat
5230 
5231     Input Parameters:
5232 +   mat - the matrix to be scaled
5233 -   a  - the scaling value
5234 
5235     Output Parameter:
5236 .   mat - the scaled matrix
5237 
5238     Level: intermediate
5239 
5240     Concepts: matrices^scaling all entries
5241 
5242 .seealso: MatDiagonalScale()
5243 @*/
5244 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5245 {
5246   PetscErrorCode ierr;
5247 
5248   PetscFunctionBegin;
5249   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5250   PetscValidType(mat,1);
5251   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5252   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5253   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5254   PetscValidLogicalCollectiveScalar(mat,a,2);
5255   MatCheckPreallocated(mat,1);
5256 
5257   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5258   if (a != (PetscScalar)1.0) {
5259     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5260     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5261 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5262     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5263       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5264     }
5265 #endif
5266   }
5267   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5268   PetscFunctionReturn(0);
5269 }
5270 
5271 /*@
5272    MatNorm - Calculates various norms of a matrix.
5273 
5274    Collective on Mat
5275 
5276    Input Parameters:
5277 +  mat - the matrix
5278 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5279 
5280    Output Parameters:
5281 .  nrm - the resulting norm
5282 
5283    Level: intermediate
5284 
5285    Concepts: matrices^norm
5286    Concepts: norm^of matrix
5287 @*/
5288 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5289 {
5290   PetscErrorCode ierr;
5291 
5292   PetscFunctionBegin;
5293   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5294   PetscValidType(mat,1);
5295   PetscValidScalarPointer(nrm,3);
5296 
5297   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5298   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5299   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5300   MatCheckPreallocated(mat,1);
5301 
5302   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5303   PetscFunctionReturn(0);
5304 }
5305 
5306 /*
5307      This variable is used to prevent counting of MatAssemblyBegin() that
5308    are called from within a MatAssemblyEnd().
5309 */
5310 static PetscInt MatAssemblyEnd_InUse = 0;
5311 /*@
5312    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5313    be called after completing all calls to MatSetValues().
5314 
5315    Collective on Mat
5316 
5317    Input Parameters:
5318 +  mat - the matrix
5319 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5320 
5321    Notes:
5322    MatSetValues() generally caches the values.  The matrix is ready to
5323    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5324    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5325    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5326    using the matrix.
5327 
5328    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5329    same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
5330    a global collective operation requring all processes that share the matrix.
5331 
5332    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5333    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5334    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5335 
5336    Level: beginner
5337 
5338    Concepts: matrices^assembling
5339 
5340 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5341 @*/
5342 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5343 {
5344   PetscErrorCode ierr;
5345 
5346   PetscFunctionBegin;
5347   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5348   PetscValidType(mat,1);
5349   MatCheckPreallocated(mat,1);
5350   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5351   if (mat->assembled) {
5352     mat->was_assembled = PETSC_TRUE;
5353     mat->assembled     = PETSC_FALSE;
5354   }
5355   if (!MatAssemblyEnd_InUse) {
5356     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5357     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5358     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5359   } else if (mat->ops->assemblybegin) {
5360     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5361   }
5362   PetscFunctionReturn(0);
5363 }
5364 
5365 /*@
5366    MatAssembled - Indicates if a matrix has been assembled and is ready for
5367      use; for example, in matrix-vector product.
5368 
5369    Not Collective
5370 
5371    Input Parameter:
5372 .  mat - the matrix
5373 
5374    Output Parameter:
5375 .  assembled - PETSC_TRUE or PETSC_FALSE
5376 
5377    Level: advanced
5378 
5379    Concepts: matrices^assembled?
5380 
5381 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5382 @*/
5383 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5384 {
5385   PetscFunctionBegin;
5386   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5387   PetscValidPointer(assembled,2);
5388   *assembled = mat->assembled;
5389   PetscFunctionReturn(0);
5390 }
5391 
5392 /*@
5393    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5394    be called after MatAssemblyBegin().
5395 
5396    Collective on Mat
5397 
5398    Input Parameters:
5399 +  mat - the matrix
5400 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5401 
5402    Options Database Keys:
5403 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5404 .  -mat_view ::ascii_info_detail - Prints more detailed info
5405 .  -mat_view - Prints matrix in ASCII format
5406 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5407 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5408 .  -display <name> - Sets display name (default is host)
5409 .  -draw_pause <sec> - Sets number of seconds to pause after display
5410 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5411 .  -viewer_socket_machine <machine> - Machine to use for socket
5412 .  -viewer_socket_port <port> - Port number to use for socket
5413 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5414 
5415    Notes:
5416    MatSetValues() generally caches the values.  The matrix is ready to
5417    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5418    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5419    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5420    using the matrix.
5421 
5422    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5423    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5424    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5425 
5426    Level: beginner
5427 
5428 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5429 @*/
5430 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5431 {
5432   PetscErrorCode  ierr;
5433   static PetscInt inassm = 0;
5434   PetscBool       flg    = PETSC_FALSE;
5435 
5436   PetscFunctionBegin;
5437   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5438   PetscValidType(mat,1);
5439 
5440   inassm++;
5441   MatAssemblyEnd_InUse++;
5442   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5443     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5444     if (mat->ops->assemblyend) {
5445       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5446     }
5447     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5448   } else if (mat->ops->assemblyend) {
5449     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5450   }
5451 
5452   /* Flush assembly is not a true assembly */
5453   if (type != MAT_FLUSH_ASSEMBLY) {
5454     mat->assembled = PETSC_TRUE; mat->num_ass++;
5455   }
5456   mat->insertmode = NOT_SET_VALUES;
5457   MatAssemblyEnd_InUse--;
5458   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5459   if (!mat->symmetric_eternal) {
5460     mat->symmetric_set              = PETSC_FALSE;
5461     mat->hermitian_set              = PETSC_FALSE;
5462     mat->structurally_symmetric_set = PETSC_FALSE;
5463   }
5464 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5465   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5466     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5467   }
5468 #endif
5469   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5470     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5471 
5472     if (mat->checksymmetryonassembly) {
5473       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5474       if (flg) {
5475         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5476       } else {
5477         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5478       }
5479     }
5480     if (mat->nullsp && mat->checknullspaceonassembly) {
5481       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5482     }
5483   }
5484   inassm--;
5485   PetscFunctionReturn(0);
5486 }
5487 
5488 /*@
5489    MatSetOption - Sets a parameter option for a matrix. Some options
5490    may be specific to certain storage formats.  Some options
5491    determine how values will be inserted (or added). Sorted,
5492    row-oriented input will generally assemble the fastest. The default
5493    is row-oriented.
5494 
5495    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5496 
5497    Input Parameters:
5498 +  mat - the matrix
5499 .  option - the option, one of those listed below (and possibly others),
5500 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5501 
5502   Options Describing Matrix Structure:
5503 +    MAT_SPD - symmetric positive definite
5504 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5505 .    MAT_HERMITIAN - transpose is the complex conjugation
5506 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5507 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5508                             you set to be kept with all future use of the matrix
5509                             including after MatAssemblyBegin/End() which could
5510                             potentially change the symmetry structure, i.e. you
5511                             KNOW the matrix will ALWAYS have the property you set.
5512 
5513 
5514    Options For Use with MatSetValues():
5515    Insert a logically dense subblock, which can be
5516 .    MAT_ROW_ORIENTED - row-oriented (default)
5517 
5518    Note these options reflect the data you pass in with MatSetValues(); it has
5519    nothing to do with how the data is stored internally in the matrix
5520    data structure.
5521 
5522    When (re)assembling a matrix, we can restrict the input for
5523    efficiency/debugging purposes.  These options include:
5524 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5525 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5526 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5527 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5528 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5529 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5530         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5531         performance for very large process counts.
5532 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5533         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5534         functions, instead sending only neighbor messages.
5535 
5536    Notes:
5537    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5538 
5539    Some options are relevant only for particular matrix types and
5540    are thus ignored by others.  Other options are not supported by
5541    certain matrix types and will generate an error message if set.
5542 
5543    If using a Fortran 77 module to compute a matrix, one may need to
5544    use the column-oriented option (or convert to the row-oriented
5545    format).
5546 
5547    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5548    that would generate a new entry in the nonzero structure is instead
5549    ignored.  Thus, if memory has not alredy been allocated for this particular
5550    data, then the insertion is ignored. For dense matrices, in which
5551    the entire array is allocated, no entries are ever ignored.
5552    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5553 
5554    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5555    that would generate a new entry in the nonzero structure instead produces
5556    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
5557 
5558    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5559    that would generate a new entry that has not been preallocated will
5560    instead produce an error. (Currently supported for AIJ and BAIJ formats
5561    only.) This is a useful flag when debugging matrix memory preallocation.
5562    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5563 
5564    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5565    other processors should be dropped, rather than stashed.
5566    This is useful if you know that the "owning" processor is also
5567    always generating the correct matrix entries, so that PETSc need
5568    not transfer duplicate entries generated on another processor.
5569 
5570    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5571    searches during matrix assembly. When this flag is set, the hash table
5572    is created during the first Matrix Assembly. This hash table is
5573    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5574    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5575    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5576    supported by MATMPIBAIJ format only.
5577 
5578    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5579    are kept in the nonzero structure
5580 
5581    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5582    a zero location in the matrix
5583 
5584    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5585 
5586    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5587         zero row routines and thus improves performance for very large process counts.
5588 
5589    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5590         part of the matrix (since they should match the upper triangular part).
5591 
5592    Notes:
5593     Can only be called after MatSetSizes() and MatSetType() have been set.
5594 
5595    Level: intermediate
5596 
5597    Concepts: matrices^setting options
5598 
5599 .seealso:  MatOption, Mat
5600 
5601 @*/
5602 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5603 {
5604   PetscErrorCode ierr;
5605 
5606   PetscFunctionBegin;
5607   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5608   PetscValidType(mat,1);
5609   if (op > 0) {
5610     PetscValidLogicalCollectiveEnum(mat,op,2);
5611     PetscValidLogicalCollectiveBool(mat,flg,3);
5612   }
5613 
5614   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);
5615   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5616 
5617   switch (op) {
5618   case MAT_NO_OFF_PROC_ENTRIES:
5619     mat->nooffprocentries = flg;
5620     PetscFunctionReturn(0);
5621     break;
5622   case MAT_SUBSET_OFF_PROC_ENTRIES:
5623     mat->assembly_subset = flg;
5624     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5625 #if !defined(PETSC_HAVE_MPIUNI)
5626       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5627 #endif
5628       mat->stash.first_assembly_done = PETSC_FALSE;
5629     }
5630     PetscFunctionReturn(0);
5631   case MAT_NO_OFF_PROC_ZERO_ROWS:
5632     mat->nooffproczerorows = flg;
5633     PetscFunctionReturn(0);
5634     break;
5635   case MAT_SPD:
5636     mat->spd_set = PETSC_TRUE;
5637     mat->spd     = flg;
5638     if (flg) {
5639       mat->symmetric                  = PETSC_TRUE;
5640       mat->structurally_symmetric     = PETSC_TRUE;
5641       mat->symmetric_set              = PETSC_TRUE;
5642       mat->structurally_symmetric_set = PETSC_TRUE;
5643     }
5644     break;
5645   case MAT_SYMMETRIC:
5646     mat->symmetric = flg;
5647     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5648     mat->symmetric_set              = PETSC_TRUE;
5649     mat->structurally_symmetric_set = flg;
5650 #if !defined(PETSC_USE_COMPLEX)
5651     mat->hermitian     = flg;
5652     mat->hermitian_set = PETSC_TRUE;
5653 #endif
5654     break;
5655   case MAT_HERMITIAN:
5656     mat->hermitian = flg;
5657     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5658     mat->hermitian_set              = PETSC_TRUE;
5659     mat->structurally_symmetric_set = flg;
5660 #if !defined(PETSC_USE_COMPLEX)
5661     mat->symmetric     = flg;
5662     mat->symmetric_set = PETSC_TRUE;
5663 #endif
5664     break;
5665   case MAT_STRUCTURALLY_SYMMETRIC:
5666     mat->structurally_symmetric     = flg;
5667     mat->structurally_symmetric_set = PETSC_TRUE;
5668     break;
5669   case MAT_SYMMETRY_ETERNAL:
5670     mat->symmetric_eternal = flg;
5671     break;
5672   case MAT_STRUCTURE_ONLY:
5673     mat->structure_only = flg;
5674     break;
5675   default:
5676     break;
5677   }
5678   if (mat->ops->setoption) {
5679     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5680   }
5681   PetscFunctionReturn(0);
5682 }
5683 
5684 /*@
5685    MatGetOption - Gets a parameter option that has been set for a matrix.
5686 
5687    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5688 
5689    Input Parameters:
5690 +  mat - the matrix
5691 -  option - the option, this only responds to certain options, check the code for which ones
5692 
5693    Output Parameter:
5694 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5695 
5696     Notes:
5697     Can only be called after MatSetSizes() and MatSetType() have been set.
5698 
5699    Level: intermediate
5700 
5701    Concepts: matrices^setting options
5702 
5703 .seealso:  MatOption, MatSetOption()
5704 
5705 @*/
5706 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5707 {
5708   PetscFunctionBegin;
5709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5710   PetscValidType(mat,1);
5711 
5712   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);
5713   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()");
5714 
5715   switch (op) {
5716   case MAT_NO_OFF_PROC_ENTRIES:
5717     *flg = mat->nooffprocentries;
5718     break;
5719   case MAT_NO_OFF_PROC_ZERO_ROWS:
5720     *flg = mat->nooffproczerorows;
5721     break;
5722   case MAT_SYMMETRIC:
5723     *flg = mat->symmetric;
5724     break;
5725   case MAT_HERMITIAN:
5726     *flg = mat->hermitian;
5727     break;
5728   case MAT_STRUCTURALLY_SYMMETRIC:
5729     *flg = mat->structurally_symmetric;
5730     break;
5731   case MAT_SYMMETRY_ETERNAL:
5732     *flg = mat->symmetric_eternal;
5733     break;
5734   case MAT_SPD:
5735     *flg = mat->spd;
5736     break;
5737   default:
5738     break;
5739   }
5740   PetscFunctionReturn(0);
5741 }
5742 
5743 /*@
5744    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5745    this routine retains the old nonzero structure.
5746 
5747    Logically Collective on Mat
5748 
5749    Input Parameters:
5750 .  mat - the matrix
5751 
5752    Level: intermediate
5753 
5754    Notes:
5755     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.
5756    See the Performance chapter of the users manual for information on preallocating matrices.
5757 
5758    Concepts: matrices^zeroing
5759 
5760 .seealso: MatZeroRows()
5761 @*/
5762 PetscErrorCode MatZeroEntries(Mat mat)
5763 {
5764   PetscErrorCode ierr;
5765 
5766   PetscFunctionBegin;
5767   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5768   PetscValidType(mat,1);
5769   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5770   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");
5771   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5772   MatCheckPreallocated(mat,1);
5773 
5774   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5775   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5776   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5777   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5778 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5779   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5780     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5781   }
5782 #endif
5783   PetscFunctionReturn(0);
5784 }
5785 
5786 /*@
5787    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5788    of a set of rows and columns of a matrix.
5789 
5790    Collective on Mat
5791 
5792    Input Parameters:
5793 +  mat - the matrix
5794 .  numRows - the number of rows to remove
5795 .  rows - the global row indices
5796 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5797 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5798 -  b - optional vector of right hand side, that will be adjusted by provided solution
5799 
5800    Notes:
5801    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5802 
5803    The user can set a value in the diagonal entry (or for the AIJ and
5804    row formats can optionally remove the main diagonal entry from the
5805    nonzero structure as well, by passing 0.0 as the final argument).
5806 
5807    For the parallel case, all processes that share the matrix (i.e.,
5808    those in the communicator used for matrix creation) MUST call this
5809    routine, regardless of whether any rows being zeroed are owned by
5810    them.
5811 
5812    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5813    list only rows local to itself).
5814 
5815    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5816 
5817    Level: intermediate
5818 
5819    Concepts: matrices^zeroing rows
5820 
5821 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5822           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5823 @*/
5824 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5825 {
5826   PetscErrorCode ierr;
5827 
5828   PetscFunctionBegin;
5829   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5830   PetscValidType(mat,1);
5831   if (numRows) PetscValidIntPointer(rows,3);
5832   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5833   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5834   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5835   MatCheckPreallocated(mat,1);
5836 
5837   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5838   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5839   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5840 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5841   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5842     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5843   }
5844 #endif
5845   PetscFunctionReturn(0);
5846 }
5847 
5848 /*@
5849    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5850    of a set of rows and columns of a matrix.
5851 
5852    Collective on Mat
5853 
5854    Input Parameters:
5855 +  mat - the matrix
5856 .  is - the rows to zero
5857 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5858 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5859 -  b - optional vector of right hand side, that will be adjusted by provided solution
5860 
5861    Notes:
5862    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5863 
5864    The user can set a value in the diagonal entry (or for the AIJ and
5865    row formats can optionally remove the main diagonal entry from the
5866    nonzero structure as well, by passing 0.0 as the final argument).
5867 
5868    For the parallel case, all processes that share the matrix (i.e.,
5869    those in the communicator used for matrix creation) MUST call this
5870    routine, regardless of whether any rows being zeroed are owned by
5871    them.
5872 
5873    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5874    list only rows local to itself).
5875 
5876    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5877 
5878    Level: intermediate
5879 
5880    Concepts: matrices^zeroing rows
5881 
5882 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5883           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5884 @*/
5885 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5886 {
5887   PetscErrorCode ierr;
5888   PetscInt       numRows;
5889   const PetscInt *rows;
5890 
5891   PetscFunctionBegin;
5892   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5893   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5894   PetscValidType(mat,1);
5895   PetscValidType(is,2);
5896   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5897   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5898   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5899   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5900   PetscFunctionReturn(0);
5901 }
5902 
5903 /*@
5904    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5905    of a set of rows of a matrix.
5906 
5907    Collective on Mat
5908 
5909    Input Parameters:
5910 +  mat - the matrix
5911 .  numRows - the number of rows to remove
5912 .  rows - the global row indices
5913 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5914 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5915 -  b - optional vector of right hand side, that will be adjusted by provided solution
5916 
5917    Notes:
5918    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5919    but does not release memory.  For the dense and block diagonal
5920    formats this does not alter the nonzero structure.
5921 
5922    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5923    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5924    merely zeroed.
5925 
5926    The user can set a value in the diagonal entry (or for the AIJ and
5927    row formats can optionally remove the main diagonal entry from the
5928    nonzero structure as well, by passing 0.0 as the final argument).
5929 
5930    For the parallel case, all processes that share the matrix (i.e.,
5931    those in the communicator used for matrix creation) MUST call this
5932    routine, regardless of whether any rows being zeroed are owned by
5933    them.
5934 
5935    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5936    list only rows local to itself).
5937 
5938    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5939    owns that are to be zeroed. This saves a global synchronization in the implementation.
5940 
5941    Level: intermediate
5942 
5943    Concepts: matrices^zeroing rows
5944 
5945 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5946           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5947 @*/
5948 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5949 {
5950   PetscErrorCode ierr;
5951 
5952   PetscFunctionBegin;
5953   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5954   PetscValidType(mat,1);
5955   if (numRows) PetscValidIntPointer(rows,3);
5956   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5957   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5958   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5959   MatCheckPreallocated(mat,1);
5960 
5961   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5962   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5963   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5964 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5965   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5966     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5967   }
5968 #endif
5969   PetscFunctionReturn(0);
5970 }
5971 
5972 /*@
5973    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5974    of a set of rows of a matrix.
5975 
5976    Collective on Mat
5977 
5978    Input Parameters:
5979 +  mat - the matrix
5980 .  is - index set of rows to remove
5981 .  diag - value put in all diagonals of eliminated rows
5982 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5983 -  b - optional vector of right hand side, that will be adjusted by provided solution
5984 
5985    Notes:
5986    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5987    but does not release memory.  For the dense and block diagonal
5988    formats this does not alter the nonzero structure.
5989 
5990    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5991    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5992    merely zeroed.
5993 
5994    The user can set a value in the diagonal entry (or for the AIJ and
5995    row formats can optionally remove the main diagonal entry from the
5996    nonzero structure as well, by passing 0.0 as the final argument).
5997 
5998    For the parallel case, all processes that share the matrix (i.e.,
5999    those in the communicator used for matrix creation) MUST call this
6000    routine, regardless of whether any rows being zeroed are owned by
6001    them.
6002 
6003    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6004    list only rows local to itself).
6005 
6006    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6007    owns that are to be zeroed. This saves a global synchronization in the implementation.
6008 
6009    Level: intermediate
6010 
6011    Concepts: matrices^zeroing rows
6012 
6013 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6014           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6015 @*/
6016 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6017 {
6018   PetscInt       numRows;
6019   const PetscInt *rows;
6020   PetscErrorCode ierr;
6021 
6022   PetscFunctionBegin;
6023   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6024   PetscValidType(mat,1);
6025   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6026   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6027   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6028   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6029   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6030   PetscFunctionReturn(0);
6031 }
6032 
6033 /*@
6034    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6035    of a set of rows of a matrix. These rows must be local to the process.
6036 
6037    Collective on Mat
6038 
6039    Input Parameters:
6040 +  mat - the matrix
6041 .  numRows - the number of rows to remove
6042 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6043 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6044 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6045 -  b - optional vector of right hand side, that will be adjusted by provided solution
6046 
6047    Notes:
6048    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6049    but does not release memory.  For the dense and block diagonal
6050    formats this does not alter the nonzero structure.
6051 
6052    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6053    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6054    merely zeroed.
6055 
6056    The user can set a value in the diagonal entry (or for the AIJ and
6057    row formats can optionally remove the main diagonal entry from the
6058    nonzero structure as well, by passing 0.0 as the final argument).
6059 
6060    For the parallel case, all processes that share the matrix (i.e.,
6061    those in the communicator used for matrix creation) MUST call this
6062    routine, regardless of whether any rows being zeroed are owned by
6063    them.
6064 
6065    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6066    list only rows local to itself).
6067 
6068    The grid coordinates are across the entire grid, not just the local portion
6069 
6070    In Fortran idxm and idxn should be declared as
6071 $     MatStencil idxm(4,m)
6072    and the values inserted using
6073 $    idxm(MatStencil_i,1) = i
6074 $    idxm(MatStencil_j,1) = j
6075 $    idxm(MatStencil_k,1) = k
6076 $    idxm(MatStencil_c,1) = c
6077    etc
6078 
6079    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6080    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6081    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6082    DM_BOUNDARY_PERIODIC boundary type.
6083 
6084    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
6085    a single value per point) you can skip filling those indices.
6086 
6087    Level: intermediate
6088 
6089    Concepts: matrices^zeroing rows
6090 
6091 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6092           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6093 @*/
6094 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6095 {
6096   PetscInt       dim     = mat->stencil.dim;
6097   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6098   PetscInt       *dims   = mat->stencil.dims+1;
6099   PetscInt       *starts = mat->stencil.starts;
6100   PetscInt       *dxm    = (PetscInt*) rows;
6101   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6102   PetscErrorCode ierr;
6103 
6104   PetscFunctionBegin;
6105   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6106   PetscValidType(mat,1);
6107   if (numRows) PetscValidIntPointer(rows,3);
6108 
6109   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6110   for (i = 0; i < numRows; ++i) {
6111     /* Skip unused dimensions (they are ordered k, j, i, c) */
6112     for (j = 0; j < 3-sdim; ++j) dxm++;
6113     /* Local index in X dir */
6114     tmp = *dxm++ - starts[0];
6115     /* Loop over remaining dimensions */
6116     for (j = 0; j < dim-1; ++j) {
6117       /* If nonlocal, set index to be negative */
6118       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6119       /* Update local index */
6120       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6121     }
6122     /* Skip component slot if necessary */
6123     if (mat->stencil.noc) dxm++;
6124     /* Local row number */
6125     if (tmp >= 0) {
6126       jdxm[numNewRows++] = tmp;
6127     }
6128   }
6129   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6130   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6131   PetscFunctionReturn(0);
6132 }
6133 
6134 /*@
6135    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6136    of a set of rows and columns of a matrix.
6137 
6138    Collective on Mat
6139 
6140    Input Parameters:
6141 +  mat - the matrix
6142 .  numRows - the number of rows/columns to remove
6143 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6144 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6145 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6146 -  b - optional vector of right hand side, that will be adjusted by provided solution
6147 
6148    Notes:
6149    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6150    but does not release memory.  For the dense and block diagonal
6151    formats this does not alter the nonzero structure.
6152 
6153    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6154    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6155    merely zeroed.
6156 
6157    The user can set a value in the diagonal entry (or for the AIJ and
6158    row formats can optionally remove the main diagonal entry from the
6159    nonzero structure as well, by passing 0.0 as the final argument).
6160 
6161    For the parallel case, all processes that share the matrix (i.e.,
6162    those in the communicator used for matrix creation) MUST call this
6163    routine, regardless of whether any rows being zeroed are owned by
6164    them.
6165 
6166    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6167    list only rows local to itself, but the row/column numbers are given in local numbering).
6168 
6169    The grid coordinates are across the entire grid, not just the local portion
6170 
6171    In Fortran idxm and idxn should be declared as
6172 $     MatStencil idxm(4,m)
6173    and the values inserted using
6174 $    idxm(MatStencil_i,1) = i
6175 $    idxm(MatStencil_j,1) = j
6176 $    idxm(MatStencil_k,1) = k
6177 $    idxm(MatStencil_c,1) = c
6178    etc
6179 
6180    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6181    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6182    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6183    DM_BOUNDARY_PERIODIC boundary type.
6184 
6185    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
6186    a single value per point) you can skip filling those indices.
6187 
6188    Level: intermediate
6189 
6190    Concepts: matrices^zeroing rows
6191 
6192 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6193           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6194 @*/
6195 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6196 {
6197   PetscInt       dim     = mat->stencil.dim;
6198   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6199   PetscInt       *dims   = mat->stencil.dims+1;
6200   PetscInt       *starts = mat->stencil.starts;
6201   PetscInt       *dxm    = (PetscInt*) rows;
6202   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6203   PetscErrorCode ierr;
6204 
6205   PetscFunctionBegin;
6206   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6207   PetscValidType(mat,1);
6208   if (numRows) PetscValidIntPointer(rows,3);
6209 
6210   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6211   for (i = 0; i < numRows; ++i) {
6212     /* Skip unused dimensions (they are ordered k, j, i, c) */
6213     for (j = 0; j < 3-sdim; ++j) dxm++;
6214     /* Local index in X dir */
6215     tmp = *dxm++ - starts[0];
6216     /* Loop over remaining dimensions */
6217     for (j = 0; j < dim-1; ++j) {
6218       /* If nonlocal, set index to be negative */
6219       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6220       /* Update local index */
6221       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6222     }
6223     /* Skip component slot if necessary */
6224     if (mat->stencil.noc) dxm++;
6225     /* Local row number */
6226     if (tmp >= 0) {
6227       jdxm[numNewRows++] = tmp;
6228     }
6229   }
6230   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6231   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6232   PetscFunctionReturn(0);
6233 }
6234 
6235 /*@C
6236    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6237    of a set of rows of a matrix; using local numbering of rows.
6238 
6239    Collective on Mat
6240 
6241    Input Parameters:
6242 +  mat - the matrix
6243 .  numRows - the number of rows to remove
6244 .  rows - the global row indices
6245 .  diag - value put in all diagonals of eliminated rows
6246 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6247 -  b - optional vector of right hand side, that will be adjusted by provided solution
6248 
6249    Notes:
6250    Before calling MatZeroRowsLocal(), the user must first set the
6251    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6252 
6253    For the AIJ matrix formats this removes the old nonzero structure,
6254    but does not release memory.  For the dense and block diagonal
6255    formats this does not alter the nonzero structure.
6256 
6257    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6258    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6259    merely zeroed.
6260 
6261    The user can set a value in the diagonal entry (or for the AIJ and
6262    row formats can optionally remove the main diagonal entry from the
6263    nonzero structure as well, by passing 0.0 as the final argument).
6264 
6265    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6266    owns that are to be zeroed. This saves a global synchronization in the implementation.
6267 
6268    Level: intermediate
6269 
6270    Concepts: matrices^zeroing
6271 
6272 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6273           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6274 @*/
6275 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6276 {
6277   PetscErrorCode ierr;
6278 
6279   PetscFunctionBegin;
6280   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6281   PetscValidType(mat,1);
6282   if (numRows) PetscValidIntPointer(rows,3);
6283   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6284   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6285   MatCheckPreallocated(mat,1);
6286 
6287   if (mat->ops->zerorowslocal) {
6288     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6289   } else {
6290     IS             is, newis;
6291     const PetscInt *newRows;
6292 
6293     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6294     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6295     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6296     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6297     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6298     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6299     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6300     ierr = ISDestroy(&is);CHKERRQ(ierr);
6301   }
6302   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6303 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6304   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6305     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6306   }
6307 #endif
6308   PetscFunctionReturn(0);
6309 }
6310 
6311 /*@
6312    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6313    of a set of rows of a matrix; using local numbering of rows.
6314 
6315    Collective on Mat
6316 
6317    Input Parameters:
6318 +  mat - the matrix
6319 .  is - index set of rows to remove
6320 .  diag - value put in all diagonals of eliminated rows
6321 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6322 -  b - optional vector of right hand side, that will be adjusted by provided solution
6323 
6324    Notes:
6325    Before calling MatZeroRowsLocalIS(), the user must first set the
6326    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6327 
6328    For the AIJ matrix formats this removes the old nonzero structure,
6329    but does not release memory.  For the dense and block diagonal
6330    formats this does not alter the nonzero structure.
6331 
6332    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6333    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6334    merely zeroed.
6335 
6336    The user can set a value in the diagonal entry (or for the AIJ and
6337    row formats can optionally remove the main diagonal entry from the
6338    nonzero structure as well, by passing 0.0 as the final argument).
6339 
6340    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6341    owns that are to be zeroed. This saves a global synchronization in the implementation.
6342 
6343    Level: intermediate
6344 
6345    Concepts: matrices^zeroing
6346 
6347 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6348           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6349 @*/
6350 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6351 {
6352   PetscErrorCode ierr;
6353   PetscInt       numRows;
6354   const PetscInt *rows;
6355 
6356   PetscFunctionBegin;
6357   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6358   PetscValidType(mat,1);
6359   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6360   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6361   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6362   MatCheckPreallocated(mat,1);
6363 
6364   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6365   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6366   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6367   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6368   PetscFunctionReturn(0);
6369 }
6370 
6371 /*@
6372    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6373    of a set of rows and columns of a matrix; using local numbering of rows.
6374 
6375    Collective on Mat
6376 
6377    Input Parameters:
6378 +  mat - the matrix
6379 .  numRows - the number of rows to remove
6380 .  rows - the global row indices
6381 .  diag - value put in all diagonals of eliminated rows
6382 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6383 -  b - optional vector of right hand side, that will be adjusted by provided solution
6384 
6385    Notes:
6386    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6387    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6388 
6389    The user can set a value in the diagonal entry (or for the AIJ and
6390    row formats can optionally remove the main diagonal entry from the
6391    nonzero structure as well, by passing 0.0 as the final argument).
6392 
6393    Level: intermediate
6394 
6395    Concepts: matrices^zeroing
6396 
6397 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6398           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6399 @*/
6400 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6401 {
6402   PetscErrorCode ierr;
6403   IS             is, newis;
6404   const PetscInt *newRows;
6405 
6406   PetscFunctionBegin;
6407   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6408   PetscValidType(mat,1);
6409   if (numRows) PetscValidIntPointer(rows,3);
6410   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6411   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6412   MatCheckPreallocated(mat,1);
6413 
6414   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6415   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6416   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6417   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6418   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6419   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6420   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6421   ierr = ISDestroy(&is);CHKERRQ(ierr);
6422   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6423 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6424   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6425     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6426   }
6427 #endif
6428   PetscFunctionReturn(0);
6429 }
6430 
6431 /*@
6432    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6433    of a set of rows and columns of a matrix; using local numbering of rows.
6434 
6435    Collective on Mat
6436 
6437    Input Parameters:
6438 +  mat - the matrix
6439 .  is - index set of rows to remove
6440 .  diag - value put in all diagonals of eliminated rows
6441 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6442 -  b - optional vector of right hand side, that will be adjusted by provided solution
6443 
6444    Notes:
6445    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6446    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6447 
6448    The user can set a value in the diagonal entry (or for the AIJ and
6449    row formats can optionally remove the main diagonal entry from the
6450    nonzero structure as well, by passing 0.0 as the final argument).
6451 
6452    Level: intermediate
6453 
6454    Concepts: matrices^zeroing
6455 
6456 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6457           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6458 @*/
6459 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6460 {
6461   PetscErrorCode ierr;
6462   PetscInt       numRows;
6463   const PetscInt *rows;
6464 
6465   PetscFunctionBegin;
6466   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6467   PetscValidType(mat,1);
6468   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6469   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6470   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6471   MatCheckPreallocated(mat,1);
6472 
6473   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6474   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6475   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6476   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6477   PetscFunctionReturn(0);
6478 }
6479 
6480 /*@C
6481    MatGetSize - Returns the numbers of rows and columns in a matrix.
6482 
6483    Not Collective
6484 
6485    Input Parameter:
6486 .  mat - the matrix
6487 
6488    Output Parameters:
6489 +  m - the number of global rows
6490 -  n - the number of global columns
6491 
6492    Note: both output parameters can be NULL on input.
6493 
6494    Level: beginner
6495 
6496    Concepts: matrices^size
6497 
6498 .seealso: MatGetLocalSize()
6499 @*/
6500 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6501 {
6502   PetscFunctionBegin;
6503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6504   if (m) *m = mat->rmap->N;
6505   if (n) *n = mat->cmap->N;
6506   PetscFunctionReturn(0);
6507 }
6508 
6509 /*@C
6510    MatGetLocalSize - Returns the number of rows and columns in a matrix
6511    stored locally.  This information may be implementation dependent, so
6512    use with care.
6513 
6514    Not Collective
6515 
6516    Input Parameters:
6517 .  mat - the matrix
6518 
6519    Output Parameters:
6520 +  m - the number of local rows
6521 -  n - the number of local columns
6522 
6523    Note: both output parameters can be NULL on input.
6524 
6525    Level: beginner
6526 
6527    Concepts: matrices^local size
6528 
6529 .seealso: MatGetSize()
6530 @*/
6531 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6532 {
6533   PetscFunctionBegin;
6534   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6535   if (m) PetscValidIntPointer(m,2);
6536   if (n) PetscValidIntPointer(n,3);
6537   if (m) *m = mat->rmap->n;
6538   if (n) *n = mat->cmap->n;
6539   PetscFunctionReturn(0);
6540 }
6541 
6542 /*@C
6543    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6544    this processor. (The columns of the "diagonal block")
6545 
6546    Not Collective, unless matrix has not been allocated, then collective on Mat
6547 
6548    Input Parameters:
6549 .  mat - the matrix
6550 
6551    Output Parameters:
6552 +  m - the global index of the first local column
6553 -  n - one more than the global index of the last local column
6554 
6555    Notes:
6556     both output parameters can be NULL on input.
6557 
6558    Level: developer
6559 
6560    Concepts: matrices^column ownership
6561 
6562 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6563 
6564 @*/
6565 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6566 {
6567   PetscFunctionBegin;
6568   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6569   PetscValidType(mat,1);
6570   if (m) PetscValidIntPointer(m,2);
6571   if (n) PetscValidIntPointer(n,3);
6572   MatCheckPreallocated(mat,1);
6573   if (m) *m = mat->cmap->rstart;
6574   if (n) *n = mat->cmap->rend;
6575   PetscFunctionReturn(0);
6576 }
6577 
6578 /*@C
6579    MatGetOwnershipRange - Returns the range of matrix rows owned by
6580    this processor, assuming that the matrix is laid out with the first
6581    n1 rows on the first processor, the next n2 rows on the second, etc.
6582    For certain parallel layouts this range may not be well defined.
6583 
6584    Not Collective
6585 
6586    Input Parameters:
6587 .  mat - the matrix
6588 
6589    Output Parameters:
6590 +  m - the global index of the first local row
6591 -  n - one more than the global index of the last local row
6592 
6593    Note: Both output parameters can be NULL on input.
6594 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6595 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6596 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6597 
6598    Level: beginner
6599 
6600    Concepts: matrices^row ownership
6601 
6602 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6603 
6604 @*/
6605 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6606 {
6607   PetscFunctionBegin;
6608   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6609   PetscValidType(mat,1);
6610   if (m) PetscValidIntPointer(m,2);
6611   if (n) PetscValidIntPointer(n,3);
6612   MatCheckPreallocated(mat,1);
6613   if (m) *m = mat->rmap->rstart;
6614   if (n) *n = mat->rmap->rend;
6615   PetscFunctionReturn(0);
6616 }
6617 
6618 /*@C
6619    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6620    each process
6621 
6622    Not Collective, unless matrix has not been allocated, then collective on Mat
6623 
6624    Input Parameters:
6625 .  mat - the matrix
6626 
6627    Output Parameters:
6628 .  ranges - start of each processors portion plus one more than the total length at the end
6629 
6630    Level: beginner
6631 
6632    Concepts: matrices^row ownership
6633 
6634 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6635 
6636 @*/
6637 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6638 {
6639   PetscErrorCode ierr;
6640 
6641   PetscFunctionBegin;
6642   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6643   PetscValidType(mat,1);
6644   MatCheckPreallocated(mat,1);
6645   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6646   PetscFunctionReturn(0);
6647 }
6648 
6649 /*@C
6650    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6651    this processor. (The columns of the "diagonal blocks" for each process)
6652 
6653    Not Collective, unless matrix has not been allocated, then collective on Mat
6654 
6655    Input Parameters:
6656 .  mat - the matrix
6657 
6658    Output Parameters:
6659 .  ranges - start of each processors portion plus one more then the total length at the end
6660 
6661    Level: beginner
6662 
6663    Concepts: matrices^column ownership
6664 
6665 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6666 
6667 @*/
6668 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6669 {
6670   PetscErrorCode ierr;
6671 
6672   PetscFunctionBegin;
6673   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6674   PetscValidType(mat,1);
6675   MatCheckPreallocated(mat,1);
6676   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6677   PetscFunctionReturn(0);
6678 }
6679 
6680 /*@C
6681    MatGetOwnershipIS - Get row and column ownership as index sets
6682 
6683    Not Collective
6684 
6685    Input Arguments:
6686 .  A - matrix of type Elemental
6687 
6688    Output Arguments:
6689 +  rows - rows in which this process owns elements
6690 .  cols - columns in which this process owns elements
6691 
6692    Level: intermediate
6693 
6694 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6695 @*/
6696 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6697 {
6698   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6699 
6700   PetscFunctionBegin;
6701   MatCheckPreallocated(A,1);
6702   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6703   if (f) {
6704     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6705   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6706     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6707     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6708   }
6709   PetscFunctionReturn(0);
6710 }
6711 
6712 /*@C
6713    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6714    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6715    to complete the factorization.
6716 
6717    Collective on Mat
6718 
6719    Input Parameters:
6720 +  mat - the matrix
6721 .  row - row permutation
6722 .  column - column permutation
6723 -  info - structure containing
6724 $      levels - number of levels of fill.
6725 $      expected fill - as ratio of original fill.
6726 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6727                 missing diagonal entries)
6728 
6729    Output Parameters:
6730 .  fact - new matrix that has been symbolically factored
6731 
6732    Notes:
6733     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6734 
6735    Most users should employ the simplified KSP interface for linear solvers
6736    instead of working directly with matrix algebra routines such as this.
6737    See, e.g., KSPCreate().
6738 
6739    Level: developer
6740 
6741   Concepts: matrices^symbolic LU factorization
6742   Concepts: matrices^factorization
6743   Concepts: LU^symbolic factorization
6744 
6745 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6746           MatGetOrdering(), MatFactorInfo
6747 
6748     Note: this uses the definition of level of fill as in Y. Saad, 2003
6749 
6750     Developer Note: fortran interface is not autogenerated as the f90
6751     interface defintion cannot be generated correctly [due to MatFactorInfo]
6752 
6753    References:
6754      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6755 @*/
6756 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6757 {
6758   PetscErrorCode ierr;
6759 
6760   PetscFunctionBegin;
6761   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6762   PetscValidType(mat,1);
6763   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6764   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6765   PetscValidPointer(info,4);
6766   PetscValidPointer(fact,5);
6767   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6768   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6769   if (!(fact)->ops->ilufactorsymbolic) {
6770     MatSolverType spackage;
6771     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6772     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6773   }
6774   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6775   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6776   MatCheckPreallocated(mat,2);
6777 
6778   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6779   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6780   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6781   PetscFunctionReturn(0);
6782 }
6783 
6784 /*@C
6785    MatICCFactorSymbolic - Performs symbolic incomplete
6786    Cholesky factorization for a symmetric matrix.  Use
6787    MatCholeskyFactorNumeric() to complete the factorization.
6788 
6789    Collective on Mat
6790 
6791    Input Parameters:
6792 +  mat - the matrix
6793 .  perm - row and column permutation
6794 -  info - structure containing
6795 $      levels - number of levels of fill.
6796 $      expected fill - as ratio of original fill.
6797 
6798    Output Parameter:
6799 .  fact - the factored matrix
6800 
6801    Notes:
6802    Most users should employ the KSP interface for linear solvers
6803    instead of working directly with matrix algebra routines such as this.
6804    See, e.g., KSPCreate().
6805 
6806    Level: developer
6807 
6808   Concepts: matrices^symbolic incomplete Cholesky factorization
6809   Concepts: matrices^factorization
6810   Concepts: Cholsky^symbolic factorization
6811 
6812 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6813 
6814     Note: this uses the definition of level of fill as in Y. Saad, 2003
6815 
6816     Developer Note: fortran interface is not autogenerated as the f90
6817     interface defintion cannot be generated correctly [due to MatFactorInfo]
6818 
6819    References:
6820      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6821 @*/
6822 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6823 {
6824   PetscErrorCode ierr;
6825 
6826   PetscFunctionBegin;
6827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6828   PetscValidType(mat,1);
6829   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6830   PetscValidPointer(info,3);
6831   PetscValidPointer(fact,4);
6832   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6833   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6834   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6835   if (!(fact)->ops->iccfactorsymbolic) {
6836     MatSolverType spackage;
6837     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6838     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6839   }
6840   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6841   MatCheckPreallocated(mat,2);
6842 
6843   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6844   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6845   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6846   PetscFunctionReturn(0);
6847 }
6848 
6849 /*@C
6850    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6851    points to an array of valid matrices, they may be reused to store the new
6852    submatrices.
6853 
6854    Collective on Mat
6855 
6856    Input Parameters:
6857 +  mat - the matrix
6858 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6859 .  irow, icol - index sets of rows and columns to extract
6860 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6861 
6862    Output Parameter:
6863 .  submat - the array of submatrices
6864 
6865    Notes:
6866    MatCreateSubMatrices() can extract ONLY sequential submatrices
6867    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6868    to extract a parallel submatrix.
6869 
6870    Some matrix types place restrictions on the row and column
6871    indices, such as that they be sorted or that they be equal to each other.
6872 
6873    The index sets may not have duplicate entries.
6874 
6875    When extracting submatrices from a parallel matrix, each processor can
6876    form a different submatrix by setting the rows and columns of its
6877    individual index sets according to the local submatrix desired.
6878 
6879    When finished using the submatrices, the user should destroy
6880    them with MatDestroySubMatrices().
6881 
6882    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6883    original matrix has not changed from that last call to MatCreateSubMatrices().
6884 
6885    This routine creates the matrices in submat; you should NOT create them before
6886    calling it. It also allocates the array of matrix pointers submat.
6887 
6888    For BAIJ matrices the index sets must respect the block structure, that is if they
6889    request one row/column in a block, they must request all rows/columns that are in
6890    that block. For example, if the block size is 2 you cannot request just row 0 and
6891    column 0.
6892 
6893    Fortran Note:
6894    The Fortran interface is slightly different from that given below; it
6895    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6896 
6897    Level: advanced
6898 
6899    Concepts: matrices^accessing submatrices
6900    Concepts: submatrices
6901 
6902 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6903 @*/
6904 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6905 {
6906   PetscErrorCode ierr;
6907   PetscInt       i;
6908   PetscBool      eq;
6909 
6910   PetscFunctionBegin;
6911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6912   PetscValidType(mat,1);
6913   if (n) {
6914     PetscValidPointer(irow,3);
6915     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6916     PetscValidPointer(icol,4);
6917     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6918   }
6919   PetscValidPointer(submat,6);
6920   if (n && scall == MAT_REUSE_MATRIX) {
6921     PetscValidPointer(*submat,6);
6922     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6923   }
6924   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6925   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6926   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6927   MatCheckPreallocated(mat,1);
6928 
6929   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6930   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6931   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6932   for (i=0; i<n; i++) {
6933     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6934     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6935       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6936       if (eq) {
6937         if (mat->symmetric) {
6938           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6939         } else if (mat->hermitian) {
6940           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6941         } else if (mat->structurally_symmetric) {
6942           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6943         }
6944       }
6945     }
6946   }
6947   PetscFunctionReturn(0);
6948 }
6949 
6950 /*@C
6951    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6952 
6953    Collective on Mat
6954 
6955    Input Parameters:
6956 +  mat - the matrix
6957 .  n   - the number of submatrixes to be extracted
6958 .  irow, icol - index sets of rows and columns to extract
6959 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6960 
6961    Output Parameter:
6962 .  submat - the array of submatrices
6963 
6964    Level: advanced
6965 
6966    Concepts: matrices^accessing submatrices
6967    Concepts: submatrices
6968 
6969 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6970 @*/
6971 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6972 {
6973   PetscErrorCode ierr;
6974   PetscInt       i;
6975   PetscBool      eq;
6976 
6977   PetscFunctionBegin;
6978   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6979   PetscValidType(mat,1);
6980   if (n) {
6981     PetscValidPointer(irow,3);
6982     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6983     PetscValidPointer(icol,4);
6984     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6985   }
6986   PetscValidPointer(submat,6);
6987   if (n && scall == MAT_REUSE_MATRIX) {
6988     PetscValidPointer(*submat,6);
6989     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6990   }
6991   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6992   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6993   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6994   MatCheckPreallocated(mat,1);
6995 
6996   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6997   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6998   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6999   for (i=0; i<n; i++) {
7000     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
7001       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
7002       if (eq) {
7003         if (mat->symmetric) {
7004           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7005         } else if (mat->hermitian) {
7006           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
7007         } else if (mat->structurally_symmetric) {
7008           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7009         }
7010       }
7011     }
7012   }
7013   PetscFunctionReturn(0);
7014 }
7015 
7016 /*@C
7017    MatDestroyMatrices - Destroys an array of matrices.
7018 
7019    Collective on Mat
7020 
7021    Input Parameters:
7022 +  n - the number of local matrices
7023 -  mat - the matrices (note that this is a pointer to the array of matrices)
7024 
7025    Level: advanced
7026 
7027     Notes:
7028     Frees not only the matrices, but also the array that contains the matrices
7029            In Fortran will not free the array.
7030 
7031 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7032 @*/
7033 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7034 {
7035   PetscErrorCode ierr;
7036   PetscInt       i;
7037 
7038   PetscFunctionBegin;
7039   if (!*mat) PetscFunctionReturn(0);
7040   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7041   PetscValidPointer(mat,2);
7042 
7043   for (i=0; i<n; i++) {
7044     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7045   }
7046 
7047   /* memory is allocated even if n = 0 */
7048   ierr = PetscFree(*mat);CHKERRQ(ierr);
7049   PetscFunctionReturn(0);
7050 }
7051 
7052 /*@C
7053    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7054 
7055    Collective on Mat
7056 
7057    Input Parameters:
7058 +  n - the number of local matrices
7059 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7060                        sequence of MatCreateSubMatrices())
7061 
7062    Level: advanced
7063 
7064     Notes:
7065     Frees not only the matrices, but also the array that contains the matrices
7066            In Fortran will not free the array.
7067 
7068 .seealso: MatCreateSubMatrices()
7069 @*/
7070 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7071 {
7072   PetscErrorCode ierr;
7073   Mat            mat0;
7074 
7075   PetscFunctionBegin;
7076   if (!*mat) PetscFunctionReturn(0);
7077   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7078   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7079   PetscValidPointer(mat,2);
7080 
7081   mat0 = (*mat)[0];
7082   if (mat0 && mat0->ops->destroysubmatrices) {
7083     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7084   } else {
7085     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7086   }
7087   PetscFunctionReturn(0);
7088 }
7089 
7090 /*@C
7091    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7092 
7093    Collective on Mat
7094 
7095    Input Parameters:
7096 .  mat - the matrix
7097 
7098    Output Parameter:
7099 .  matstruct - the sequential matrix with the nonzero structure of mat
7100 
7101   Level: intermediate
7102 
7103 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7104 @*/
7105 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7106 {
7107   PetscErrorCode ierr;
7108 
7109   PetscFunctionBegin;
7110   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7111   PetscValidPointer(matstruct,2);
7112 
7113   PetscValidType(mat,1);
7114   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7115   MatCheckPreallocated(mat,1);
7116 
7117   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7118   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7119   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7120   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7121   PetscFunctionReturn(0);
7122 }
7123 
7124 /*@C
7125    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7126 
7127    Collective on Mat
7128 
7129    Input Parameters:
7130 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7131                        sequence of MatGetSequentialNonzeroStructure())
7132 
7133    Level: advanced
7134 
7135     Notes:
7136     Frees not only the matrices, but also the array that contains the matrices
7137 
7138 .seealso: MatGetSeqNonzeroStructure()
7139 @*/
7140 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7141 {
7142   PetscErrorCode ierr;
7143 
7144   PetscFunctionBegin;
7145   PetscValidPointer(mat,1);
7146   ierr = MatDestroy(mat);CHKERRQ(ierr);
7147   PetscFunctionReturn(0);
7148 }
7149 
7150 /*@
7151    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7152    replaces the index sets by larger ones that represent submatrices with
7153    additional overlap.
7154 
7155    Collective on Mat
7156 
7157    Input Parameters:
7158 +  mat - the matrix
7159 .  n   - the number of index sets
7160 .  is  - the array of index sets (these index sets will changed during the call)
7161 -  ov  - the additional overlap requested
7162 
7163    Options Database:
7164 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7165 
7166    Level: developer
7167 
7168    Concepts: overlap
7169    Concepts: ASM^computing overlap
7170 
7171 .seealso: MatCreateSubMatrices()
7172 @*/
7173 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7174 {
7175   PetscErrorCode ierr;
7176 
7177   PetscFunctionBegin;
7178   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7179   PetscValidType(mat,1);
7180   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7181   if (n) {
7182     PetscValidPointer(is,3);
7183     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7184   }
7185   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7186   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7187   MatCheckPreallocated(mat,1);
7188 
7189   if (!ov) PetscFunctionReturn(0);
7190   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7191   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7192   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7193   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7194   PetscFunctionReturn(0);
7195 }
7196 
7197 
7198 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7199 
7200 /*@
7201    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7202    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7203    additional overlap.
7204 
7205    Collective on Mat
7206 
7207    Input Parameters:
7208 +  mat - the matrix
7209 .  n   - the number of index sets
7210 .  is  - the array of index sets (these index sets will changed during the call)
7211 -  ov  - the additional overlap requested
7212 
7213    Options Database:
7214 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7215 
7216    Level: developer
7217 
7218    Concepts: overlap
7219    Concepts: ASM^computing overlap
7220 
7221 .seealso: MatCreateSubMatrices()
7222 @*/
7223 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7224 {
7225   PetscInt       i;
7226   PetscErrorCode ierr;
7227 
7228   PetscFunctionBegin;
7229   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7230   PetscValidType(mat,1);
7231   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7232   if (n) {
7233     PetscValidPointer(is,3);
7234     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7235   }
7236   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7237   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7238   MatCheckPreallocated(mat,1);
7239   if (!ov) PetscFunctionReturn(0);
7240   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7241   for(i=0; i<n; i++){
7242 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7243   }
7244   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7245   PetscFunctionReturn(0);
7246 }
7247 
7248 
7249 
7250 
7251 /*@
7252    MatGetBlockSize - Returns the matrix block size.
7253 
7254    Not Collective
7255 
7256    Input Parameter:
7257 .  mat - the matrix
7258 
7259    Output Parameter:
7260 .  bs - block size
7261 
7262    Notes:
7263     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7264 
7265    If the block size has not been set yet this routine returns 1.
7266 
7267    Level: intermediate
7268 
7269    Concepts: matrices^block size
7270 
7271 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7272 @*/
7273 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7274 {
7275   PetscFunctionBegin;
7276   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7277   PetscValidIntPointer(bs,2);
7278   *bs = PetscAbs(mat->rmap->bs);
7279   PetscFunctionReturn(0);
7280 }
7281 
7282 /*@
7283    MatGetBlockSizes - Returns the matrix block row and column sizes.
7284 
7285    Not Collective
7286 
7287    Input Parameter:
7288 .  mat - the matrix
7289 
7290    Output Parameter:
7291 .  rbs - row block size
7292 .  cbs - column block size
7293 
7294    Notes:
7295     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7296     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7297 
7298    If a block size has not been set yet this routine returns 1.
7299 
7300    Level: intermediate
7301 
7302    Concepts: matrices^block size
7303 
7304 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7305 @*/
7306 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7307 {
7308   PetscFunctionBegin;
7309   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7310   if (rbs) PetscValidIntPointer(rbs,2);
7311   if (cbs) PetscValidIntPointer(cbs,3);
7312   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7313   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7314   PetscFunctionReturn(0);
7315 }
7316 
7317 /*@
7318    MatSetBlockSize - Sets the matrix block size.
7319 
7320    Logically Collective on Mat
7321 
7322    Input Parameters:
7323 +  mat - the matrix
7324 -  bs - block size
7325 
7326    Notes:
7327     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7328     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7329 
7330     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7331     is compatible with the matrix local sizes.
7332 
7333    Level: intermediate
7334 
7335    Concepts: matrices^block size
7336 
7337 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7338 @*/
7339 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7340 {
7341   PetscErrorCode ierr;
7342 
7343   PetscFunctionBegin;
7344   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7345   PetscValidLogicalCollectiveInt(mat,bs,2);
7346   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7347   PetscFunctionReturn(0);
7348 }
7349 
7350 /*@
7351    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7352 
7353    Logically Collective on Mat
7354 
7355    Input Parameters:
7356 +  mat - the matrix
7357 .  nblocks - the number of blocks on this process
7358 -  bsizes - the block sizes
7359 
7360    Notes:
7361     Currently used by PCVPBJACOBI for SeqAIJ matrices
7362 
7363    Level: intermediate
7364 
7365    Concepts: matrices^block size
7366 
7367 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7368 @*/
7369 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7370 {
7371   PetscErrorCode ierr;
7372   PetscInt       i,ncnt = 0, nlocal;
7373 
7374   PetscFunctionBegin;
7375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7376   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7377   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7378   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7379   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);
7380   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7381   mat->nblocks = nblocks;
7382   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7383   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7384   PetscFunctionReturn(0);
7385 }
7386 
7387 /*@C
7388    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7389 
7390    Logically Collective on Mat
7391 
7392    Input Parameters:
7393 .  mat - the matrix
7394 
7395    Output Parameters:
7396 +  nblocks - the number of blocks on this process
7397 -  bsizes - the block sizes
7398 
7399    Notes: Currently not supported from Fortran
7400 
7401    Level: intermediate
7402 
7403    Concepts: matrices^block size
7404 
7405 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7406 @*/
7407 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7408 {
7409   PetscFunctionBegin;
7410   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7411   *nblocks = mat->nblocks;
7412   *bsizes  = mat->bsizes;
7413   PetscFunctionReturn(0);
7414 }
7415 
7416 /*@
7417    MatSetBlockSizes - Sets the matrix block row and column sizes.
7418 
7419    Logically Collective on Mat
7420 
7421    Input Parameters:
7422 +  mat - the matrix
7423 -  rbs - row block size
7424 -  cbs - column block size
7425 
7426    Notes:
7427     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7428     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7429     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7430 
7431     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7432     are compatible with the matrix local sizes.
7433 
7434     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7435 
7436    Level: intermediate
7437 
7438    Concepts: matrices^block size
7439 
7440 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7441 @*/
7442 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7443 {
7444   PetscErrorCode ierr;
7445 
7446   PetscFunctionBegin;
7447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7448   PetscValidLogicalCollectiveInt(mat,rbs,2);
7449   PetscValidLogicalCollectiveInt(mat,cbs,3);
7450   if (mat->ops->setblocksizes) {
7451     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7452   }
7453   if (mat->rmap->refcnt) {
7454     ISLocalToGlobalMapping l2g = NULL;
7455     PetscLayout            nmap = NULL;
7456 
7457     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7458     if (mat->rmap->mapping) {
7459       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7460     }
7461     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7462     mat->rmap = nmap;
7463     mat->rmap->mapping = l2g;
7464   }
7465   if (mat->cmap->refcnt) {
7466     ISLocalToGlobalMapping l2g = NULL;
7467     PetscLayout            nmap = NULL;
7468 
7469     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7470     if (mat->cmap->mapping) {
7471       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7472     }
7473     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7474     mat->cmap = nmap;
7475     mat->cmap->mapping = l2g;
7476   }
7477   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7478   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7479   PetscFunctionReturn(0);
7480 }
7481 
7482 /*@
7483    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7484 
7485    Logically Collective on Mat
7486 
7487    Input Parameters:
7488 +  mat - the matrix
7489 .  fromRow - matrix from which to copy row block size
7490 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7491 
7492    Level: developer
7493 
7494    Concepts: matrices^block size
7495 
7496 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7497 @*/
7498 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7499 {
7500   PetscErrorCode ierr;
7501 
7502   PetscFunctionBegin;
7503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7504   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7505   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7506   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7507   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7508   PetscFunctionReturn(0);
7509 }
7510 
7511 /*@
7512    MatResidual - Default routine to calculate the residual.
7513 
7514    Collective on Mat and Vec
7515 
7516    Input Parameters:
7517 +  mat - the matrix
7518 .  b   - the right-hand-side
7519 -  x   - the approximate solution
7520 
7521    Output Parameter:
7522 .  r - location to store the residual
7523 
7524    Level: developer
7525 
7526 .keywords: MG, default, multigrid, residual
7527 
7528 .seealso: PCMGSetResidual()
7529 @*/
7530 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7531 {
7532   PetscErrorCode ierr;
7533 
7534   PetscFunctionBegin;
7535   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7536   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7537   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7538   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7539   PetscValidType(mat,1);
7540   MatCheckPreallocated(mat,1);
7541   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7542   if (!mat->ops->residual) {
7543     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7544     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7545   } else {
7546     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7547   }
7548   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7549   PetscFunctionReturn(0);
7550 }
7551 
7552 /*@C
7553     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7554 
7555    Collective on Mat
7556 
7557     Input Parameters:
7558 +   mat - the matrix
7559 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7560 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7561 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7562                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7563                  always used.
7564 
7565     Output Parameters:
7566 +   n - number of rows in the (possibly compressed) matrix
7567 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7568 .   ja - the column indices
7569 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7570            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7571 
7572     Level: developer
7573 
7574     Notes:
7575     You CANNOT change any of the ia[] or ja[] values.
7576 
7577     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7578 
7579     Fortran Notes:
7580     In Fortran use
7581 $
7582 $      PetscInt ia(1), ja(1)
7583 $      PetscOffset iia, jja
7584 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7585 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7586 
7587      or
7588 $
7589 $    PetscInt, pointer :: ia(:),ja(:)
7590 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7591 $    ! Access the ith and jth entries via ia(i) and ja(j)
7592 
7593 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7594 @*/
7595 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7596 {
7597   PetscErrorCode ierr;
7598 
7599   PetscFunctionBegin;
7600   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7601   PetscValidType(mat,1);
7602   PetscValidIntPointer(n,5);
7603   if (ia) PetscValidIntPointer(ia,6);
7604   if (ja) PetscValidIntPointer(ja,7);
7605   PetscValidIntPointer(done,8);
7606   MatCheckPreallocated(mat,1);
7607   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7608   else {
7609     *done = PETSC_TRUE;
7610     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7611     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7612     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7613   }
7614   PetscFunctionReturn(0);
7615 }
7616 
7617 /*@C
7618     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7619 
7620     Collective on Mat
7621 
7622     Input Parameters:
7623 +   mat - the matrix
7624 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7625 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7626                 symmetrized
7627 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7628                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7629                  always used.
7630 .   n - number of columns in the (possibly compressed) matrix
7631 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7632 -   ja - the row indices
7633 
7634     Output Parameters:
7635 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7636 
7637     Level: developer
7638 
7639 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7640 @*/
7641 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7642 {
7643   PetscErrorCode ierr;
7644 
7645   PetscFunctionBegin;
7646   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7647   PetscValidType(mat,1);
7648   PetscValidIntPointer(n,4);
7649   if (ia) PetscValidIntPointer(ia,5);
7650   if (ja) PetscValidIntPointer(ja,6);
7651   PetscValidIntPointer(done,7);
7652   MatCheckPreallocated(mat,1);
7653   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7654   else {
7655     *done = PETSC_TRUE;
7656     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7657   }
7658   PetscFunctionReturn(0);
7659 }
7660 
7661 /*@C
7662     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7663     MatGetRowIJ().
7664 
7665     Collective on Mat
7666 
7667     Input Parameters:
7668 +   mat - the matrix
7669 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7670 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7671                 symmetrized
7672 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7673                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7674                  always used.
7675 .   n - size of (possibly compressed) matrix
7676 .   ia - the row pointers
7677 -   ja - the column indices
7678 
7679     Output Parameters:
7680 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7681 
7682     Note:
7683     This routine zeros out n, ia, and ja. This is to prevent accidental
7684     us of the array after it has been restored. If you pass NULL, it will
7685     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7686 
7687     Level: developer
7688 
7689 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7690 @*/
7691 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7692 {
7693   PetscErrorCode ierr;
7694 
7695   PetscFunctionBegin;
7696   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7697   PetscValidType(mat,1);
7698   if (ia) PetscValidIntPointer(ia,6);
7699   if (ja) PetscValidIntPointer(ja,7);
7700   PetscValidIntPointer(done,8);
7701   MatCheckPreallocated(mat,1);
7702 
7703   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7704   else {
7705     *done = PETSC_TRUE;
7706     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7707     if (n)  *n = 0;
7708     if (ia) *ia = NULL;
7709     if (ja) *ja = NULL;
7710   }
7711   PetscFunctionReturn(0);
7712 }
7713 
7714 /*@C
7715     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7716     MatGetColumnIJ().
7717 
7718     Collective on Mat
7719 
7720     Input Parameters:
7721 +   mat - the matrix
7722 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7723 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7724                 symmetrized
7725 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7726                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7727                  always used.
7728 
7729     Output Parameters:
7730 +   n - size of (possibly compressed) matrix
7731 .   ia - the column pointers
7732 .   ja - the row indices
7733 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7734 
7735     Level: developer
7736 
7737 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7738 @*/
7739 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7740 {
7741   PetscErrorCode ierr;
7742 
7743   PetscFunctionBegin;
7744   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7745   PetscValidType(mat,1);
7746   if (ia) PetscValidIntPointer(ia,5);
7747   if (ja) PetscValidIntPointer(ja,6);
7748   PetscValidIntPointer(done,7);
7749   MatCheckPreallocated(mat,1);
7750 
7751   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7752   else {
7753     *done = PETSC_TRUE;
7754     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7755     if (n)  *n = 0;
7756     if (ia) *ia = NULL;
7757     if (ja) *ja = NULL;
7758   }
7759   PetscFunctionReturn(0);
7760 }
7761 
7762 /*@C
7763     MatColoringPatch -Used inside matrix coloring routines that
7764     use MatGetRowIJ() and/or MatGetColumnIJ().
7765 
7766     Collective on Mat
7767 
7768     Input Parameters:
7769 +   mat - the matrix
7770 .   ncolors - max color value
7771 .   n   - number of entries in colorarray
7772 -   colorarray - array indicating color for each column
7773 
7774     Output Parameters:
7775 .   iscoloring - coloring generated using colorarray information
7776 
7777     Level: developer
7778 
7779 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7780 
7781 @*/
7782 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7783 {
7784   PetscErrorCode ierr;
7785 
7786   PetscFunctionBegin;
7787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7788   PetscValidType(mat,1);
7789   PetscValidIntPointer(colorarray,4);
7790   PetscValidPointer(iscoloring,5);
7791   MatCheckPreallocated(mat,1);
7792 
7793   if (!mat->ops->coloringpatch) {
7794     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7795   } else {
7796     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7797   }
7798   PetscFunctionReturn(0);
7799 }
7800 
7801 
7802 /*@
7803    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7804 
7805    Logically Collective on Mat
7806 
7807    Input Parameter:
7808 .  mat - the factored matrix to be reset
7809 
7810    Notes:
7811    This routine should be used only with factored matrices formed by in-place
7812    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7813    format).  This option can save memory, for example, when solving nonlinear
7814    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7815    ILU(0) preconditioner.
7816 
7817    Note that one can specify in-place ILU(0) factorization by calling
7818 .vb
7819      PCType(pc,PCILU);
7820      PCFactorSeUseInPlace(pc);
7821 .ve
7822    or by using the options -pc_type ilu -pc_factor_in_place
7823 
7824    In-place factorization ILU(0) can also be used as a local
7825    solver for the blocks within the block Jacobi or additive Schwarz
7826    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7827    for details on setting local solver options.
7828 
7829    Most users should employ the simplified KSP interface for linear solvers
7830    instead of working directly with matrix algebra routines such as this.
7831    See, e.g., KSPCreate().
7832 
7833    Level: developer
7834 
7835 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7836 
7837    Concepts: matrices^unfactored
7838 
7839 @*/
7840 PetscErrorCode MatSetUnfactored(Mat mat)
7841 {
7842   PetscErrorCode ierr;
7843 
7844   PetscFunctionBegin;
7845   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7846   PetscValidType(mat,1);
7847   MatCheckPreallocated(mat,1);
7848   mat->factortype = MAT_FACTOR_NONE;
7849   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7850   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7851   PetscFunctionReturn(0);
7852 }
7853 
7854 /*MC
7855     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7856 
7857     Synopsis:
7858     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7859 
7860     Not collective
7861 
7862     Input Parameter:
7863 .   x - matrix
7864 
7865     Output Parameters:
7866 +   xx_v - the Fortran90 pointer to the array
7867 -   ierr - error code
7868 
7869     Example of Usage:
7870 .vb
7871       PetscScalar, pointer xx_v(:,:)
7872       ....
7873       call MatDenseGetArrayF90(x,xx_v,ierr)
7874       a = xx_v(3)
7875       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7876 .ve
7877 
7878     Level: advanced
7879 
7880 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7881 
7882     Concepts: matrices^accessing array
7883 
7884 M*/
7885 
7886 /*MC
7887     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7888     accessed with MatDenseGetArrayF90().
7889 
7890     Synopsis:
7891     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7892 
7893     Not collective
7894 
7895     Input Parameters:
7896 +   x - matrix
7897 -   xx_v - the Fortran90 pointer to the array
7898 
7899     Output Parameter:
7900 .   ierr - error code
7901 
7902     Example of Usage:
7903 .vb
7904        PetscScalar, pointer xx_v(:,:)
7905        ....
7906        call MatDenseGetArrayF90(x,xx_v,ierr)
7907        a = xx_v(3)
7908        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7909 .ve
7910 
7911     Level: advanced
7912 
7913 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7914 
7915 M*/
7916 
7917 
7918 /*MC
7919     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7920 
7921     Synopsis:
7922     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7923 
7924     Not collective
7925 
7926     Input Parameter:
7927 .   x - matrix
7928 
7929     Output Parameters:
7930 +   xx_v - the Fortran90 pointer to the array
7931 -   ierr - error code
7932 
7933     Example of Usage:
7934 .vb
7935       PetscScalar, pointer xx_v(:)
7936       ....
7937       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7938       a = xx_v(3)
7939       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7940 .ve
7941 
7942     Level: advanced
7943 
7944 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7945 
7946     Concepts: matrices^accessing array
7947 
7948 M*/
7949 
7950 /*MC
7951     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7952     accessed with MatSeqAIJGetArrayF90().
7953 
7954     Synopsis:
7955     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7956 
7957     Not collective
7958 
7959     Input Parameters:
7960 +   x - matrix
7961 -   xx_v - the Fortran90 pointer to the array
7962 
7963     Output Parameter:
7964 .   ierr - error code
7965 
7966     Example of Usage:
7967 .vb
7968        PetscScalar, pointer xx_v(:)
7969        ....
7970        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7971        a = xx_v(3)
7972        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7973 .ve
7974 
7975     Level: advanced
7976 
7977 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7978 
7979 M*/
7980 
7981 
7982 /*@
7983     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7984                       as the original matrix.
7985 
7986     Collective on Mat
7987 
7988     Input Parameters:
7989 +   mat - the original matrix
7990 .   isrow - parallel IS containing the rows this processor should obtain
7991 .   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.
7992 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7993 
7994     Output Parameter:
7995 .   newmat - the new submatrix, of the same type as the old
7996 
7997     Level: advanced
7998 
7999     Notes:
8000     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
8001 
8002     Some matrix types place restrictions on the row and column indices, such
8003     as that they be sorted or that they be equal to each other.
8004 
8005     The index sets may not have duplicate entries.
8006 
8007       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
8008    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
8009    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
8010    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
8011    you are finished using it.
8012 
8013     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
8014     the input matrix.
8015 
8016     If iscol is NULL then all columns are obtained (not supported in Fortran).
8017 
8018    Example usage:
8019    Consider the following 8x8 matrix with 34 non-zero values, that is
8020    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8021    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8022    as follows:
8023 
8024 .vb
8025             1  2  0  |  0  3  0  |  0  4
8026     Proc0   0  5  6  |  7  0  0  |  8  0
8027             9  0 10  | 11  0  0  | 12  0
8028     -------------------------------------
8029            13  0 14  | 15 16 17  |  0  0
8030     Proc1   0 18  0  | 19 20 21  |  0  0
8031             0  0  0  | 22 23  0  | 24  0
8032     -------------------------------------
8033     Proc2  25 26 27  |  0  0 28  | 29  0
8034            30  0  0  | 31 32 33  |  0 34
8035 .ve
8036 
8037     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8038 
8039 .vb
8040             2  0  |  0  3  0  |  0
8041     Proc0   5  6  |  7  0  0  |  8
8042     -------------------------------
8043     Proc1  18  0  | 19 20 21  |  0
8044     -------------------------------
8045     Proc2  26 27  |  0  0 28  | 29
8046             0  0  | 31 32 33  |  0
8047 .ve
8048 
8049 
8050     Concepts: matrices^submatrices
8051 
8052 .seealso: MatCreateSubMatrices()
8053 @*/
8054 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8055 {
8056   PetscErrorCode ierr;
8057   PetscMPIInt    size;
8058   Mat            *local;
8059   IS             iscoltmp;
8060 
8061   PetscFunctionBegin;
8062   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8063   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8064   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8065   PetscValidPointer(newmat,5);
8066   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8067   PetscValidType(mat,1);
8068   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8069   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8070 
8071   MatCheckPreallocated(mat,1);
8072   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8073 
8074   if (!iscol || isrow == iscol) {
8075     PetscBool   stride;
8076     PetscMPIInt grabentirematrix = 0,grab;
8077     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8078     if (stride) {
8079       PetscInt first,step,n,rstart,rend;
8080       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8081       if (step == 1) {
8082         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8083         if (rstart == first) {
8084           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8085           if (n == rend-rstart) {
8086             grabentirematrix = 1;
8087           }
8088         }
8089       }
8090     }
8091     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8092     if (grab) {
8093       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8094       if (cll == MAT_INITIAL_MATRIX) {
8095         *newmat = mat;
8096         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8097       }
8098       PetscFunctionReturn(0);
8099     }
8100   }
8101 
8102   if (!iscol) {
8103     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8104   } else {
8105     iscoltmp = iscol;
8106   }
8107 
8108   /* if original matrix is on just one processor then use submatrix generated */
8109   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8110     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8111     goto setproperties;
8112   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8113     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8114     *newmat = *local;
8115     ierr    = PetscFree(local);CHKERRQ(ierr);
8116     goto setproperties;
8117   } else if (!mat->ops->createsubmatrix) {
8118     /* Create a new matrix type that implements the operation using the full matrix */
8119     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8120     switch (cll) {
8121     case MAT_INITIAL_MATRIX:
8122       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8123       break;
8124     case MAT_REUSE_MATRIX:
8125       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8126       break;
8127     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8128     }
8129     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8130     goto setproperties;
8131   }
8132 
8133   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8134   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8135   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8136   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8137 
8138   /* Propagate symmetry information for diagonal blocks */
8139 setproperties:
8140   if (isrow == iscoltmp) {
8141     if (mat->symmetric_set && mat->symmetric) {
8142       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8143     }
8144     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8145       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8146     }
8147     if (mat->hermitian_set && mat->hermitian) {
8148       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8149     }
8150     if (mat->spd_set && mat->spd) {
8151       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8152     }
8153   }
8154 
8155   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8156   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8157   PetscFunctionReturn(0);
8158 }
8159 
8160 /*@
8161    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8162    used during the assembly process to store values that belong to
8163    other processors.
8164 
8165    Not Collective
8166 
8167    Input Parameters:
8168 +  mat   - the matrix
8169 .  size  - the initial size of the stash.
8170 -  bsize - the initial size of the block-stash(if used).
8171 
8172    Options Database Keys:
8173 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8174 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8175 
8176    Level: intermediate
8177 
8178    Notes:
8179      The block-stash is used for values set with MatSetValuesBlocked() while
8180      the stash is used for values set with MatSetValues()
8181 
8182      Run with the option -info and look for output of the form
8183      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8184      to determine the appropriate value, MM, to use for size and
8185      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8186      to determine the value, BMM to use for bsize
8187 
8188    Concepts: stash^setting matrix size
8189    Concepts: matrices^stash
8190 
8191 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8192 
8193 @*/
8194 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8195 {
8196   PetscErrorCode ierr;
8197 
8198   PetscFunctionBegin;
8199   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8200   PetscValidType(mat,1);
8201   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8202   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8203   PetscFunctionReturn(0);
8204 }
8205 
8206 /*@
8207    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8208      the matrix
8209 
8210    Neighbor-wise Collective on Mat
8211 
8212    Input Parameters:
8213 +  mat   - the matrix
8214 .  x,y - the vectors
8215 -  w - where the result is stored
8216 
8217    Level: intermediate
8218 
8219    Notes:
8220     w may be the same vector as y.
8221 
8222     This allows one to use either the restriction or interpolation (its transpose)
8223     matrix to do the interpolation
8224 
8225     Concepts: interpolation
8226 
8227 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8228 
8229 @*/
8230 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8231 {
8232   PetscErrorCode ierr;
8233   PetscInt       M,N,Ny;
8234 
8235   PetscFunctionBegin;
8236   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8237   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8238   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8239   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8240   PetscValidType(A,1);
8241   MatCheckPreallocated(A,1);
8242   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8243   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8244   if (M == Ny) {
8245     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8246   } else {
8247     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8248   }
8249   PetscFunctionReturn(0);
8250 }
8251 
8252 /*@
8253    MatInterpolate - y = A*x or A'*x depending on the shape of
8254      the matrix
8255 
8256    Neighbor-wise Collective on Mat
8257 
8258    Input Parameters:
8259 +  mat   - the matrix
8260 -  x,y - the vectors
8261 
8262    Level: intermediate
8263 
8264    Notes:
8265     This allows one to use either the restriction or interpolation (its transpose)
8266     matrix to do the interpolation
8267 
8268    Concepts: matrices^interpolation
8269 
8270 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8271 
8272 @*/
8273 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8274 {
8275   PetscErrorCode ierr;
8276   PetscInt       M,N,Ny;
8277 
8278   PetscFunctionBegin;
8279   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8280   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8281   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8282   PetscValidType(A,1);
8283   MatCheckPreallocated(A,1);
8284   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8285   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8286   if (M == Ny) {
8287     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8288   } else {
8289     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8290   }
8291   PetscFunctionReturn(0);
8292 }
8293 
8294 /*@
8295    MatRestrict - y = A*x or A'*x
8296 
8297    Neighbor-wise Collective on Mat
8298 
8299    Input Parameters:
8300 +  mat   - the matrix
8301 -  x,y - the vectors
8302 
8303    Level: intermediate
8304 
8305    Notes:
8306     This allows one to use either the restriction or interpolation (its transpose)
8307     matrix to do the restriction
8308 
8309    Concepts: matrices^restriction
8310 
8311 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8312 
8313 @*/
8314 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8315 {
8316   PetscErrorCode ierr;
8317   PetscInt       M,N,Ny;
8318 
8319   PetscFunctionBegin;
8320   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8321   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8322   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8323   PetscValidType(A,1);
8324   MatCheckPreallocated(A,1);
8325 
8326   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8327   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8328   if (M == Ny) {
8329     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8330   } else {
8331     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8332   }
8333   PetscFunctionReturn(0);
8334 }
8335 
8336 /*@
8337    MatGetNullSpace - retrieves the null space of a matrix.
8338 
8339    Logically Collective on Mat and MatNullSpace
8340 
8341    Input Parameters:
8342 +  mat - the matrix
8343 -  nullsp - the null space object
8344 
8345    Level: developer
8346 
8347    Concepts: null space^attaching to matrix
8348 
8349 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8350 @*/
8351 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8352 {
8353   PetscFunctionBegin;
8354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8355   PetscValidPointer(nullsp,2);
8356   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8357   PetscFunctionReturn(0);
8358 }
8359 
8360 /*@
8361    MatSetNullSpace - attaches a null space to a matrix.
8362 
8363    Logically Collective on Mat and MatNullSpace
8364 
8365    Input Parameters:
8366 +  mat - the matrix
8367 -  nullsp - the null space object
8368 
8369    Level: advanced
8370 
8371    Notes:
8372       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8373 
8374       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8375       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8376 
8377       You can remove the null space by calling this routine with an nullsp of NULL
8378 
8379 
8380       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8381    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).
8382    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
8383    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
8384    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).
8385 
8386       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8387 
8388     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
8389     routine also automatically calls MatSetTransposeNullSpace().
8390 
8391    Concepts: null space^attaching to matrix
8392 
8393 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8394 @*/
8395 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8396 {
8397   PetscErrorCode ierr;
8398 
8399   PetscFunctionBegin;
8400   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8401   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8402   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8403   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8404   mat->nullsp = nullsp;
8405   if (mat->symmetric_set && mat->symmetric) {
8406     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8407   }
8408   PetscFunctionReturn(0);
8409 }
8410 
8411 /*@
8412    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8413 
8414    Logically Collective on Mat and MatNullSpace
8415 
8416    Input Parameters:
8417 +  mat - the matrix
8418 -  nullsp - the null space object
8419 
8420    Level: developer
8421 
8422    Concepts: null space^attaching to matrix
8423 
8424 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8425 @*/
8426 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8427 {
8428   PetscFunctionBegin;
8429   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8430   PetscValidType(mat,1);
8431   PetscValidPointer(nullsp,2);
8432   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8433   PetscFunctionReturn(0);
8434 }
8435 
8436 /*@
8437    MatSetTransposeNullSpace - attaches a null space to a matrix.
8438 
8439    Logically Collective on Mat and MatNullSpace
8440 
8441    Input Parameters:
8442 +  mat - the matrix
8443 -  nullsp - the null space object
8444 
8445    Level: advanced
8446 
8447    Notes:
8448       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.
8449       You must also call MatSetNullSpace()
8450 
8451 
8452       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8453    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).
8454    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
8455    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
8456    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).
8457 
8458       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8459 
8460    Concepts: null space^attaching to matrix
8461 
8462 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8463 @*/
8464 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8465 {
8466   PetscErrorCode ierr;
8467 
8468   PetscFunctionBegin;
8469   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8470   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8471   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8472   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8473   mat->transnullsp = nullsp;
8474   PetscFunctionReturn(0);
8475 }
8476 
8477 /*@
8478    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8479         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8480 
8481    Logically Collective on Mat and MatNullSpace
8482 
8483    Input Parameters:
8484 +  mat - the matrix
8485 -  nullsp - the null space object
8486 
8487    Level: advanced
8488 
8489    Notes:
8490       Overwrites any previous near null space that may have been attached
8491 
8492       You can remove the null space by calling this routine with an nullsp of NULL
8493 
8494    Concepts: null space^attaching to matrix
8495 
8496 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8497 @*/
8498 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8499 {
8500   PetscErrorCode ierr;
8501 
8502   PetscFunctionBegin;
8503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8504   PetscValidType(mat,1);
8505   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8506   MatCheckPreallocated(mat,1);
8507   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8508   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8509   mat->nearnullsp = nullsp;
8510   PetscFunctionReturn(0);
8511 }
8512 
8513 /*@
8514    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8515 
8516    Not Collective
8517 
8518    Input Parameters:
8519 .  mat - the matrix
8520 
8521    Output Parameters:
8522 .  nullsp - the null space object, NULL if not set
8523 
8524    Level: developer
8525 
8526    Concepts: null space^attaching to matrix
8527 
8528 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8529 @*/
8530 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8531 {
8532   PetscFunctionBegin;
8533   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8534   PetscValidType(mat,1);
8535   PetscValidPointer(nullsp,2);
8536   MatCheckPreallocated(mat,1);
8537   *nullsp = mat->nearnullsp;
8538   PetscFunctionReturn(0);
8539 }
8540 
8541 /*@C
8542    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8543 
8544    Collective on Mat
8545 
8546    Input Parameters:
8547 +  mat - the matrix
8548 .  row - row/column permutation
8549 .  fill - expected fill factor >= 1.0
8550 -  level - level of fill, for ICC(k)
8551 
8552    Notes:
8553    Probably really in-place only when level of fill is zero, otherwise allocates
8554    new space to store factored matrix and deletes previous memory.
8555 
8556    Most users should employ the simplified KSP interface for linear solvers
8557    instead of working directly with matrix algebra routines such as this.
8558    See, e.g., KSPCreate().
8559 
8560    Level: developer
8561 
8562    Concepts: matrices^incomplete Cholesky factorization
8563    Concepts: Cholesky factorization
8564 
8565 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8566 
8567     Developer Note: fortran interface is not autogenerated as the f90
8568     interface defintion cannot be generated correctly [due to MatFactorInfo]
8569 
8570 @*/
8571 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8572 {
8573   PetscErrorCode ierr;
8574 
8575   PetscFunctionBegin;
8576   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8577   PetscValidType(mat,1);
8578   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8579   PetscValidPointer(info,3);
8580   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8581   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8582   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8583   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8584   MatCheckPreallocated(mat,1);
8585   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8586   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8587   PetscFunctionReturn(0);
8588 }
8589 
8590 /*@
8591    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8592          ghosted ones.
8593 
8594    Not Collective
8595 
8596    Input Parameters:
8597 +  mat - the matrix
8598 -  diag = the diagonal values, including ghost ones
8599 
8600    Level: developer
8601 
8602    Notes:
8603     Works only for MPIAIJ and MPIBAIJ matrices
8604 
8605 .seealso: MatDiagonalScale()
8606 @*/
8607 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8608 {
8609   PetscErrorCode ierr;
8610   PetscMPIInt    size;
8611 
8612   PetscFunctionBegin;
8613   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8614   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8615   PetscValidType(mat,1);
8616 
8617   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8618   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8619   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8620   if (size == 1) {
8621     PetscInt n,m;
8622     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8623     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8624     if (m == n) {
8625       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8626     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8627   } else {
8628     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8629   }
8630   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8631   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8632   PetscFunctionReturn(0);
8633 }
8634 
8635 /*@
8636    MatGetInertia - Gets the inertia from a factored matrix
8637 
8638    Collective on Mat
8639 
8640    Input Parameter:
8641 .  mat - the matrix
8642 
8643    Output Parameters:
8644 +   nneg - number of negative eigenvalues
8645 .   nzero - number of zero eigenvalues
8646 -   npos - number of positive eigenvalues
8647 
8648    Level: advanced
8649 
8650    Notes:
8651     Matrix must have been factored by MatCholeskyFactor()
8652 
8653 
8654 @*/
8655 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8656 {
8657   PetscErrorCode ierr;
8658 
8659   PetscFunctionBegin;
8660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8661   PetscValidType(mat,1);
8662   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8663   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8664   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8665   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8666   PetscFunctionReturn(0);
8667 }
8668 
8669 /* ----------------------------------------------------------------*/
8670 /*@C
8671    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8672 
8673    Neighbor-wise Collective on Mat and Vecs
8674 
8675    Input Parameters:
8676 +  mat - the factored matrix
8677 -  b - the right-hand-side vectors
8678 
8679    Output Parameter:
8680 .  x - the result vectors
8681 
8682    Notes:
8683    The vectors b and x cannot be the same.  I.e., one cannot
8684    call MatSolves(A,x,x).
8685 
8686    Notes:
8687    Most users should employ the simplified KSP interface for linear solvers
8688    instead of working directly with matrix algebra routines such as this.
8689    See, e.g., KSPCreate().
8690 
8691    Level: developer
8692 
8693    Concepts: matrices^triangular solves
8694 
8695 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8696 @*/
8697 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8698 {
8699   PetscErrorCode ierr;
8700 
8701   PetscFunctionBegin;
8702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8703   PetscValidType(mat,1);
8704   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8705   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8706   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8707 
8708   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8709   MatCheckPreallocated(mat,1);
8710   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8711   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8712   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8713   PetscFunctionReturn(0);
8714 }
8715 
8716 /*@
8717    MatIsSymmetric - Test whether a matrix is symmetric
8718 
8719    Collective on Mat
8720 
8721    Input Parameter:
8722 +  A - the matrix to test
8723 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8724 
8725    Output Parameters:
8726 .  flg - the result
8727 
8728    Notes:
8729     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8730 
8731    Level: intermediate
8732 
8733    Concepts: matrix^symmetry
8734 
8735 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8736 @*/
8737 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8738 {
8739   PetscErrorCode ierr;
8740 
8741   PetscFunctionBegin;
8742   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8743   PetscValidPointer(flg,2);
8744 
8745   if (!A->symmetric_set) {
8746     if (!A->ops->issymmetric) {
8747       MatType mattype;
8748       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8749       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8750     }
8751     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8752     if (!tol) {
8753       A->symmetric_set = PETSC_TRUE;
8754       A->symmetric     = *flg;
8755       if (A->symmetric) {
8756         A->structurally_symmetric_set = PETSC_TRUE;
8757         A->structurally_symmetric     = PETSC_TRUE;
8758       }
8759     }
8760   } else if (A->symmetric) {
8761     *flg = PETSC_TRUE;
8762   } else if (!tol) {
8763     *flg = PETSC_FALSE;
8764   } else {
8765     if (!A->ops->issymmetric) {
8766       MatType mattype;
8767       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8768       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8769     }
8770     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8771   }
8772   PetscFunctionReturn(0);
8773 }
8774 
8775 /*@
8776    MatIsHermitian - Test whether a matrix is Hermitian
8777 
8778    Collective on Mat
8779 
8780    Input Parameter:
8781 +  A - the matrix to test
8782 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8783 
8784    Output Parameters:
8785 .  flg - the result
8786 
8787    Level: intermediate
8788 
8789    Concepts: matrix^symmetry
8790 
8791 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8792           MatIsSymmetricKnown(), MatIsSymmetric()
8793 @*/
8794 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8795 {
8796   PetscErrorCode ierr;
8797 
8798   PetscFunctionBegin;
8799   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8800   PetscValidPointer(flg,2);
8801 
8802   if (!A->hermitian_set) {
8803     if (!A->ops->ishermitian) {
8804       MatType mattype;
8805       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8806       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8807     }
8808     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8809     if (!tol) {
8810       A->hermitian_set = PETSC_TRUE;
8811       A->hermitian     = *flg;
8812       if (A->hermitian) {
8813         A->structurally_symmetric_set = PETSC_TRUE;
8814         A->structurally_symmetric     = PETSC_TRUE;
8815       }
8816     }
8817   } else if (A->hermitian) {
8818     *flg = PETSC_TRUE;
8819   } else if (!tol) {
8820     *flg = PETSC_FALSE;
8821   } else {
8822     if (!A->ops->ishermitian) {
8823       MatType mattype;
8824       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8825       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8826     }
8827     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8828   }
8829   PetscFunctionReturn(0);
8830 }
8831 
8832 /*@
8833    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8834 
8835    Not Collective
8836 
8837    Input Parameter:
8838 .  A - the matrix to check
8839 
8840    Output Parameters:
8841 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8842 -  flg - the result
8843 
8844    Level: advanced
8845 
8846    Concepts: matrix^symmetry
8847 
8848    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8849          if you want it explicitly checked
8850 
8851 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8852 @*/
8853 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8854 {
8855   PetscFunctionBegin;
8856   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8857   PetscValidPointer(set,2);
8858   PetscValidPointer(flg,3);
8859   if (A->symmetric_set) {
8860     *set = PETSC_TRUE;
8861     *flg = A->symmetric;
8862   } else {
8863     *set = PETSC_FALSE;
8864   }
8865   PetscFunctionReturn(0);
8866 }
8867 
8868 /*@
8869    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8870 
8871    Not Collective
8872 
8873    Input Parameter:
8874 .  A - the matrix to check
8875 
8876    Output Parameters:
8877 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8878 -  flg - the result
8879 
8880    Level: advanced
8881 
8882    Concepts: matrix^symmetry
8883 
8884    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8885          if you want it explicitly checked
8886 
8887 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8888 @*/
8889 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8890 {
8891   PetscFunctionBegin;
8892   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8893   PetscValidPointer(set,2);
8894   PetscValidPointer(flg,3);
8895   if (A->hermitian_set) {
8896     *set = PETSC_TRUE;
8897     *flg = A->hermitian;
8898   } else {
8899     *set = PETSC_FALSE;
8900   }
8901   PetscFunctionReturn(0);
8902 }
8903 
8904 /*@
8905    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8906 
8907    Collective on Mat
8908 
8909    Input Parameter:
8910 .  A - the matrix to test
8911 
8912    Output Parameters:
8913 .  flg - the result
8914 
8915    Level: intermediate
8916 
8917    Concepts: matrix^symmetry
8918 
8919 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8920 @*/
8921 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8922 {
8923   PetscErrorCode ierr;
8924 
8925   PetscFunctionBegin;
8926   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8927   PetscValidPointer(flg,2);
8928   if (!A->structurally_symmetric_set) {
8929     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8930     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8931 
8932     A->structurally_symmetric_set = PETSC_TRUE;
8933   }
8934   *flg = A->structurally_symmetric;
8935   PetscFunctionReturn(0);
8936 }
8937 
8938 /*@
8939    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8940        to be communicated to other processors during the MatAssemblyBegin/End() process
8941 
8942     Not collective
8943 
8944    Input Parameter:
8945 .   vec - the vector
8946 
8947    Output Parameters:
8948 +   nstash   - the size of the stash
8949 .   reallocs - the number of additional mallocs incurred.
8950 .   bnstash   - the size of the block stash
8951 -   breallocs - the number of additional mallocs incurred.in the block stash
8952 
8953    Level: advanced
8954 
8955 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8956 
8957 @*/
8958 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8959 {
8960   PetscErrorCode ierr;
8961 
8962   PetscFunctionBegin;
8963   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8964   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8965   PetscFunctionReturn(0);
8966 }
8967 
8968 /*@C
8969    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8970      parallel layout
8971 
8972    Collective on Mat
8973 
8974    Input Parameter:
8975 .  mat - the matrix
8976 
8977    Output Parameter:
8978 +   right - (optional) vector that the matrix can be multiplied against
8979 -   left - (optional) vector that the matrix vector product can be stored in
8980 
8981    Notes:
8982     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().
8983 
8984   Notes:
8985     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8986 
8987   Level: advanced
8988 
8989 .seealso: MatCreate(), VecDestroy()
8990 @*/
8991 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8992 {
8993   PetscErrorCode ierr;
8994 
8995   PetscFunctionBegin;
8996   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8997   PetscValidType(mat,1);
8998   if (mat->ops->getvecs) {
8999     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
9000   } else {
9001     PetscInt rbs,cbs;
9002     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
9003     if (right) {
9004       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
9005       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
9006       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9007       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
9008       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
9009       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
9010     }
9011     if (left) {
9012       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9013       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
9014       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9015       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9016       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9017       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9018     }
9019   }
9020   PetscFunctionReturn(0);
9021 }
9022 
9023 /*@C
9024    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9025      with default values.
9026 
9027    Not Collective
9028 
9029    Input Parameters:
9030 .    info - the MatFactorInfo data structure
9031 
9032 
9033    Notes:
9034     The solvers are generally used through the KSP and PC objects, for example
9035           PCLU, PCILU, PCCHOLESKY, PCICC
9036 
9037    Level: developer
9038 
9039 .seealso: MatFactorInfo
9040 
9041     Developer Note: fortran interface is not autogenerated as the f90
9042     interface defintion cannot be generated correctly [due to MatFactorInfo]
9043 
9044 @*/
9045 
9046 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9047 {
9048   PetscErrorCode ierr;
9049 
9050   PetscFunctionBegin;
9051   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9052   PetscFunctionReturn(0);
9053 }
9054 
9055 /*@
9056    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9057 
9058    Collective on Mat
9059 
9060    Input Parameters:
9061 +  mat - the factored matrix
9062 -  is - the index set defining the Schur indices (0-based)
9063 
9064    Notes:
9065     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9066 
9067    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9068 
9069    Level: developer
9070 
9071    Concepts:
9072 
9073 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9074           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9075 
9076 @*/
9077 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9078 {
9079   PetscErrorCode ierr,(*f)(Mat,IS);
9080 
9081   PetscFunctionBegin;
9082   PetscValidType(mat,1);
9083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9084   PetscValidType(is,2);
9085   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9086   PetscCheckSameComm(mat,1,is,2);
9087   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9088   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9089   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");
9090   if (mat->schur) {
9091     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9092   }
9093   ierr = (*f)(mat,is);CHKERRQ(ierr);
9094   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9095   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9096   PetscFunctionReturn(0);
9097 }
9098 
9099 /*@
9100   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9101 
9102    Logically Collective on Mat
9103 
9104    Input Parameters:
9105 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9106 .  S - location where to return the Schur complement, can be NULL
9107 -  status - the status of the Schur complement matrix, can be NULL
9108 
9109    Notes:
9110    You must call MatFactorSetSchurIS() before calling this routine.
9111 
9112    The routine provides a copy of the Schur matrix stored within the solver data structures.
9113    The caller must destroy the object when it is no longer needed.
9114    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9115 
9116    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)
9117 
9118    Developer Notes:
9119     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9120    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9121 
9122    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9123 
9124    Level: advanced
9125 
9126    References:
9127 
9128 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9129 @*/
9130 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9131 {
9132   PetscErrorCode ierr;
9133 
9134   PetscFunctionBegin;
9135   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9136   if (S) PetscValidPointer(S,2);
9137   if (status) PetscValidPointer(status,3);
9138   if (S) {
9139     PetscErrorCode (*f)(Mat,Mat*);
9140 
9141     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9142     if (f) {
9143       ierr = (*f)(F,S);CHKERRQ(ierr);
9144     } else {
9145       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9146     }
9147   }
9148   if (status) *status = F->schur_status;
9149   PetscFunctionReturn(0);
9150 }
9151 
9152 /*@
9153   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9154 
9155    Logically Collective on Mat
9156 
9157    Input Parameters:
9158 +  F - the factored matrix obtained by calling MatGetFactor()
9159 .  *S - location where to return the Schur complement, can be NULL
9160 -  status - the status of the Schur complement matrix, can be NULL
9161 
9162    Notes:
9163    You must call MatFactorSetSchurIS() before calling this routine.
9164 
9165    Schur complement mode is currently implemented for sequential matrices.
9166    The routine returns a the Schur Complement stored within the data strutures of the solver.
9167    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9168    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9169 
9170    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9171 
9172    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9173 
9174    Level: advanced
9175 
9176    References:
9177 
9178 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9179 @*/
9180 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9181 {
9182   PetscFunctionBegin;
9183   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9184   if (S) PetscValidPointer(S,2);
9185   if (status) PetscValidPointer(status,3);
9186   if (S) *S = F->schur;
9187   if (status) *status = F->schur_status;
9188   PetscFunctionReturn(0);
9189 }
9190 
9191 /*@
9192   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9193 
9194    Logically Collective on Mat
9195 
9196    Input Parameters:
9197 +  F - the factored matrix obtained by calling MatGetFactor()
9198 .  *S - location where the Schur complement is stored
9199 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9200 
9201    Notes:
9202 
9203    Level: advanced
9204 
9205    References:
9206 
9207 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9208 @*/
9209 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9210 {
9211   PetscErrorCode ierr;
9212 
9213   PetscFunctionBegin;
9214   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9215   if (S) {
9216     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9217     *S = NULL;
9218   }
9219   F->schur_status = status;
9220   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9221   PetscFunctionReturn(0);
9222 }
9223 
9224 /*@
9225   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9226 
9227    Logically Collective on Mat
9228 
9229    Input Parameters:
9230 +  F - the factored matrix obtained by calling MatGetFactor()
9231 .  rhs - location where the right hand side of the Schur complement system is stored
9232 -  sol - location where the solution of the Schur complement system has to be returned
9233 
9234    Notes:
9235    The sizes of the vectors should match the size of the Schur complement
9236 
9237    Must be called after MatFactorSetSchurIS()
9238 
9239    Level: advanced
9240 
9241    References:
9242 
9243 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9244 @*/
9245 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9246 {
9247   PetscErrorCode ierr;
9248 
9249   PetscFunctionBegin;
9250   PetscValidType(F,1);
9251   PetscValidType(rhs,2);
9252   PetscValidType(sol,3);
9253   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9254   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9255   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9256   PetscCheckSameComm(F,1,rhs,2);
9257   PetscCheckSameComm(F,1,sol,3);
9258   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9259   switch (F->schur_status) {
9260   case MAT_FACTOR_SCHUR_FACTORED:
9261     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9262     break;
9263   case MAT_FACTOR_SCHUR_INVERTED:
9264     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9265     break;
9266   default:
9267     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9268     break;
9269   }
9270   PetscFunctionReturn(0);
9271 }
9272 
9273 /*@
9274   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9275 
9276    Logically Collective on Mat
9277 
9278    Input Parameters:
9279 +  F - the factored matrix obtained by calling MatGetFactor()
9280 .  rhs - location where the right hand side of the Schur complement system is stored
9281 -  sol - location where the solution of the Schur complement system has to be returned
9282 
9283    Notes:
9284    The sizes of the vectors should match the size of the Schur complement
9285 
9286    Must be called after MatFactorSetSchurIS()
9287 
9288    Level: advanced
9289 
9290    References:
9291 
9292 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9293 @*/
9294 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9295 {
9296   PetscErrorCode ierr;
9297 
9298   PetscFunctionBegin;
9299   PetscValidType(F,1);
9300   PetscValidType(rhs,2);
9301   PetscValidType(sol,3);
9302   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9303   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9304   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9305   PetscCheckSameComm(F,1,rhs,2);
9306   PetscCheckSameComm(F,1,sol,3);
9307   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9308   switch (F->schur_status) {
9309   case MAT_FACTOR_SCHUR_FACTORED:
9310     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9311     break;
9312   case MAT_FACTOR_SCHUR_INVERTED:
9313     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9314     break;
9315   default:
9316     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9317     break;
9318   }
9319   PetscFunctionReturn(0);
9320 }
9321 
9322 /*@
9323   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9324 
9325    Logically Collective on Mat
9326 
9327    Input Parameters:
9328 +  F - the factored matrix obtained by calling MatGetFactor()
9329 
9330    Notes:
9331     Must be called after MatFactorSetSchurIS().
9332 
9333    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9334 
9335    Level: advanced
9336 
9337    References:
9338 
9339 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9340 @*/
9341 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9342 {
9343   PetscErrorCode ierr;
9344 
9345   PetscFunctionBegin;
9346   PetscValidType(F,1);
9347   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9348   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9349   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9350   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9351   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9352   PetscFunctionReturn(0);
9353 }
9354 
9355 /*@
9356   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9357 
9358    Logically Collective on Mat
9359 
9360    Input Parameters:
9361 +  F - the factored matrix obtained by calling MatGetFactor()
9362 
9363    Notes:
9364     Must be called after MatFactorSetSchurIS().
9365 
9366    Level: advanced
9367 
9368    References:
9369 
9370 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9371 @*/
9372 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9373 {
9374   PetscErrorCode ierr;
9375 
9376   PetscFunctionBegin;
9377   PetscValidType(F,1);
9378   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9379   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9380   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9381   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9382   PetscFunctionReturn(0);
9383 }
9384 
9385 /*@
9386    MatPtAP - Creates the matrix product C = P^T * A * P
9387 
9388    Neighbor-wise Collective on Mat
9389 
9390    Input Parameters:
9391 +  A - the matrix
9392 .  P - the projection matrix
9393 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9394 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9395           if the result is a dense matrix this is irrelevent
9396 
9397    Output Parameters:
9398 .  C - the product matrix
9399 
9400    Notes:
9401    C will be created and must be destroyed by the user with MatDestroy().
9402 
9403    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9404    which inherit from AIJ.
9405 
9406    Level: intermediate
9407 
9408 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9409 @*/
9410 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9411 {
9412   PetscErrorCode ierr;
9413   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9414   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9415   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9416   PetscBool      sametype;
9417 
9418   PetscFunctionBegin;
9419   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9420   PetscValidType(A,1);
9421   MatCheckPreallocated(A,1);
9422   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9423   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9424   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9425   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9426   PetscValidType(P,2);
9427   MatCheckPreallocated(P,2);
9428   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9429   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9430 
9431   if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N);
9432   if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9433   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9434   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9435 
9436   if (scall == MAT_REUSE_MATRIX) {
9437     PetscValidPointer(*C,5);
9438     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9439 
9440     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9441     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9442     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9443     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9444     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9445     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9446     PetscFunctionReturn(0);
9447   }
9448 
9449   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9450   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9451 
9452   fA = A->ops->ptap;
9453   fP = P->ops->ptap;
9454   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9455   if (fP == fA && sametype) {
9456     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9457     ptap = fA;
9458   } else {
9459     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9460     char ptapname[256];
9461     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9462     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9463     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9464     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9465     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9466     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9467     if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname);
9468   }
9469 
9470   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9471   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9472   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9473   if (A->symmetric_set && A->symmetric) {
9474     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9475   }
9476   PetscFunctionReturn(0);
9477 }
9478 
9479 /*@
9480    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9481 
9482    Neighbor-wise Collective on Mat
9483 
9484    Input Parameters:
9485 +  A - the matrix
9486 -  P - the projection matrix
9487 
9488    Output Parameters:
9489 .  C - the product matrix
9490 
9491    Notes:
9492    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9493    the user using MatDeatroy().
9494 
9495    This routine is currently only implemented for pairs of AIJ matrices and classes
9496    which inherit from AIJ.  C will be of type MATAIJ.
9497 
9498    Level: intermediate
9499 
9500 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9501 @*/
9502 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9503 {
9504   PetscErrorCode ierr;
9505 
9506   PetscFunctionBegin;
9507   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9508   PetscValidType(A,1);
9509   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9510   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9511   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9512   PetscValidType(P,2);
9513   MatCheckPreallocated(P,2);
9514   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9515   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9516   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9517   PetscValidType(C,3);
9518   MatCheckPreallocated(C,3);
9519   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9520   if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
9521   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9522   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9523   if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
9524   MatCheckPreallocated(A,1);
9525 
9526   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9527   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9528   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9529   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9530   PetscFunctionReturn(0);
9531 }
9532 
9533 /*@
9534    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9535 
9536    Neighbor-wise Collective on Mat
9537 
9538    Input Parameters:
9539 +  A - the matrix
9540 -  P - the projection matrix
9541 
9542    Output Parameters:
9543 .  C - the (i,j) structure of the product matrix
9544 
9545    Notes:
9546    C will be created and must be destroyed by the user with MatDestroy().
9547 
9548    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9549    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9550    this (i,j) structure by calling MatPtAPNumeric().
9551 
9552    Level: intermediate
9553 
9554 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9555 @*/
9556 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9557 {
9558   PetscErrorCode ierr;
9559 
9560   PetscFunctionBegin;
9561   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9562   PetscValidType(A,1);
9563   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9564   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9565   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9566   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9567   PetscValidType(P,2);
9568   MatCheckPreallocated(P,2);
9569   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9570   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9571   PetscValidPointer(C,3);
9572 
9573   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
9574   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9575   MatCheckPreallocated(A,1);
9576 
9577   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9578   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9579   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9580   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9581 
9582   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9583   PetscFunctionReturn(0);
9584 }
9585 
9586 /*@
9587    MatRARt - Creates the matrix product C = R * A * R^T
9588 
9589    Neighbor-wise Collective on Mat
9590 
9591    Input Parameters:
9592 +  A - the matrix
9593 .  R - the projection matrix
9594 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9595 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9596           if the result is a dense matrix this is irrelevent
9597 
9598    Output Parameters:
9599 .  C - the product matrix
9600 
9601    Notes:
9602    C will be created and must be destroyed by the user with MatDestroy().
9603 
9604    This routine is currently only implemented for pairs of AIJ matrices and classes
9605    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9606    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9607    We recommend using MatPtAP().
9608 
9609    Level: intermediate
9610 
9611 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9612 @*/
9613 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9614 {
9615   PetscErrorCode ierr;
9616 
9617   PetscFunctionBegin;
9618   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9619   PetscValidType(A,1);
9620   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9621   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9622   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9623   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9624   PetscValidType(R,2);
9625   MatCheckPreallocated(R,2);
9626   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9627   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9628   PetscValidPointer(C,3);
9629   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9630 
9631   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9632   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9633   MatCheckPreallocated(A,1);
9634 
9635   if (!A->ops->rart) {
9636     Mat Rt;
9637     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9638     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9639     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9640     PetscFunctionReturn(0);
9641   }
9642   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9643   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9644   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9645   PetscFunctionReturn(0);
9646 }
9647 
9648 /*@
9649    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9650 
9651    Neighbor-wise Collective on Mat
9652 
9653    Input Parameters:
9654 +  A - the matrix
9655 -  R - the projection matrix
9656 
9657    Output Parameters:
9658 .  C - the product matrix
9659 
9660    Notes:
9661    C must have been created by calling MatRARtSymbolic and must be destroyed by
9662    the user using MatDestroy().
9663 
9664    This routine is currently only implemented for pairs of AIJ matrices and classes
9665    which inherit from AIJ.  C will be of type MATAIJ.
9666 
9667    Level: intermediate
9668 
9669 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9670 @*/
9671 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9672 {
9673   PetscErrorCode ierr;
9674 
9675   PetscFunctionBegin;
9676   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9677   PetscValidType(A,1);
9678   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9679   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9680   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9681   PetscValidType(R,2);
9682   MatCheckPreallocated(R,2);
9683   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9684   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9685   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9686   PetscValidType(C,3);
9687   MatCheckPreallocated(C,3);
9688   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9689   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
9690   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9691   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9692   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
9693   MatCheckPreallocated(A,1);
9694 
9695   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9696   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9697   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9698   PetscFunctionReturn(0);
9699 }
9700 
9701 /*@
9702    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9703 
9704    Neighbor-wise Collective on Mat
9705 
9706    Input Parameters:
9707 +  A - the matrix
9708 -  R - the projection matrix
9709 
9710    Output Parameters:
9711 .  C - the (i,j) structure of the product matrix
9712 
9713    Notes:
9714    C will be created and must be destroyed by the user with MatDestroy().
9715 
9716    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9717    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9718    this (i,j) structure by calling MatRARtNumeric().
9719 
9720    Level: intermediate
9721 
9722 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9723 @*/
9724 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9725 {
9726   PetscErrorCode ierr;
9727 
9728   PetscFunctionBegin;
9729   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9730   PetscValidType(A,1);
9731   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9732   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9733   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9734   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9735   PetscValidType(R,2);
9736   MatCheckPreallocated(R,2);
9737   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9738   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9739   PetscValidPointer(C,3);
9740 
9741   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
9742   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9743   MatCheckPreallocated(A,1);
9744   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9745   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9746   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9747 
9748   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9749   PetscFunctionReturn(0);
9750 }
9751 
9752 /*@
9753    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9754 
9755    Neighbor-wise Collective on Mat
9756 
9757    Input Parameters:
9758 +  A - the left matrix
9759 .  B - the right matrix
9760 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9761 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9762           if the result is a dense matrix this is irrelevent
9763 
9764    Output Parameters:
9765 .  C - the product matrix
9766 
9767    Notes:
9768    Unless scall is MAT_REUSE_MATRIX C will be created.
9769 
9770    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
9771    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9772 
9773    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9774    actually needed.
9775 
9776    If you have many matrices with the same non-zero structure to multiply, you
9777    should either
9778 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9779 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9780    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
9781    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9782 
9783    Level: intermediate
9784 
9785 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9786 @*/
9787 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9788 {
9789   PetscErrorCode ierr;
9790   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9791   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9792   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9793 
9794   PetscFunctionBegin;
9795   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9796   PetscValidType(A,1);
9797   MatCheckPreallocated(A,1);
9798   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9799   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9800   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9801   PetscValidType(B,2);
9802   MatCheckPreallocated(B,2);
9803   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9804   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9805   PetscValidPointer(C,3);
9806   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9807   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9808   if (scall == MAT_REUSE_MATRIX) {
9809     PetscValidPointer(*C,5);
9810     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9811     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9812     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9813     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9814     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9815     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9816     PetscFunctionReturn(0);
9817   }
9818   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9819   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9820 
9821   fA = A->ops->matmult;
9822   fB = B->ops->matmult;
9823   if (fB == fA) {
9824     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9825     mult = fB;
9826   } else {
9827     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9828     char multname[256];
9829     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9830     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9831     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9832     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9833     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9834     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9835     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9836   }
9837   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9838   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9839   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9840   PetscFunctionReturn(0);
9841 }
9842 
9843 /*@
9844    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9845    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9846 
9847    Neighbor-wise Collective on Mat
9848 
9849    Input Parameters:
9850 +  A - the left matrix
9851 .  B - the right matrix
9852 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9853       if C is a dense matrix this is irrelevent
9854 
9855    Output Parameters:
9856 .  C - the product matrix
9857 
9858    Notes:
9859    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9860    actually needed.
9861 
9862    This routine is currently implemented for
9863     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9864     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9865     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9866 
9867    Level: intermediate
9868 
9869    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173
9870      We should incorporate them into PETSc.
9871 
9872 .seealso: MatMatMult(), MatMatMultNumeric()
9873 @*/
9874 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9875 {
9876   PetscErrorCode ierr;
9877   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9878   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9879   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9880 
9881   PetscFunctionBegin;
9882   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9883   PetscValidType(A,1);
9884   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9885   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9886 
9887   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9888   PetscValidType(B,2);
9889   MatCheckPreallocated(B,2);
9890   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9891   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9892   PetscValidPointer(C,3);
9893 
9894   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
9895   if (fill == PETSC_DEFAULT) fill = 2.0;
9896   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9897   MatCheckPreallocated(A,1);
9898 
9899   Asymbolic = A->ops->matmultsymbolic;
9900   Bsymbolic = B->ops->matmultsymbolic;
9901   if (Asymbolic == Bsymbolic) {
9902     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9903     symbolic = Bsymbolic;
9904   } else { /* dispatch based on the type of A and B */
9905     char symbolicname[256];
9906     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9907     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9908     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9909     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9910     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9911     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9912     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
9913   }
9914   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9915   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9916   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9917   PetscFunctionReturn(0);
9918 }
9919 
9920 /*@
9921    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9922    Call this routine after first calling MatMatMultSymbolic().
9923 
9924    Neighbor-wise Collective on Mat
9925 
9926    Input Parameters:
9927 +  A - the left matrix
9928 -  B - the right matrix
9929 
9930    Output Parameters:
9931 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9932 
9933    Notes:
9934    C must have been created with MatMatMultSymbolic().
9935 
9936    This routine is currently implemented for
9937     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9938     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9939     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9940 
9941    Level: intermediate
9942 
9943 .seealso: MatMatMult(), MatMatMultSymbolic()
9944 @*/
9945 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9946 {
9947   PetscErrorCode ierr;
9948 
9949   PetscFunctionBegin;
9950   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9951   PetscFunctionReturn(0);
9952 }
9953 
9954 /*@
9955    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9956 
9957    Neighbor-wise Collective on Mat
9958 
9959    Input Parameters:
9960 +  A - the left matrix
9961 .  B - the right matrix
9962 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9963 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9964 
9965    Output Parameters:
9966 .  C - the product matrix
9967 
9968    Notes:
9969    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9970 
9971    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9972 
9973   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9974    actually needed.
9975 
9976    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9977    and for pairs of MPIDense matrices.
9978 
9979    Options Database Keys:
9980 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9981                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9982                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9983 
9984    Level: intermediate
9985 
9986 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9987 @*/
9988 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9989 {
9990   PetscErrorCode ierr;
9991   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9992   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9993 
9994   PetscFunctionBegin;
9995   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9996   PetscValidType(A,1);
9997   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9998   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9999   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10000   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10001   PetscValidType(B,2);
10002   MatCheckPreallocated(B,2);
10003   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10004   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10005   PetscValidPointer(C,3);
10006   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
10007   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10008   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10009   MatCheckPreallocated(A,1);
10010 
10011   fA = A->ops->mattransposemult;
10012   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
10013   fB = B->ops->mattransposemult;
10014   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
10015   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
10016 
10017   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10018   if (scall == MAT_INITIAL_MATRIX) {
10019     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10020     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
10021     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10022   }
10023   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10024   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10025   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10026   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10027   PetscFunctionReturn(0);
10028 }
10029 
10030 /*@
10031    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10032 
10033    Neighbor-wise Collective on Mat
10034 
10035    Input Parameters:
10036 +  A - the left matrix
10037 .  B - the right matrix
10038 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10039 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10040 
10041    Output Parameters:
10042 .  C - the product matrix
10043 
10044    Notes:
10045    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10046 
10047    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10048 
10049   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10050    actually needed.
10051 
10052    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10053    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10054 
10055    Level: intermediate
10056 
10057 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10058 @*/
10059 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10060 {
10061   PetscErrorCode ierr;
10062   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10063   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10064   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10065 
10066   PetscFunctionBegin;
10067   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10068   PetscValidType(A,1);
10069   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10070   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10071   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10072   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10073   PetscValidType(B,2);
10074   MatCheckPreallocated(B,2);
10075   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10076   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10077   PetscValidPointer(C,3);
10078   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
10079   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10080   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10081   MatCheckPreallocated(A,1);
10082 
10083   fA = A->ops->transposematmult;
10084   fB = B->ops->transposematmult;
10085   if (fB==fA) {
10086     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10087     transposematmult = fA;
10088   } else {
10089     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10090     char multname[256];
10091     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10092     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10093     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10094     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10095     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10096     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10097     if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
10098   }
10099   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10100   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10101   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10102   PetscFunctionReturn(0);
10103 }
10104 
10105 /*@
10106    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10107 
10108    Neighbor-wise Collective on Mat
10109 
10110    Input Parameters:
10111 +  A - the left matrix
10112 .  B - the middle matrix
10113 .  C - the right matrix
10114 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10115 -  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
10116           if the result is a dense matrix this is irrelevent
10117 
10118    Output Parameters:
10119 .  D - the product matrix
10120 
10121    Notes:
10122    Unless scall is MAT_REUSE_MATRIX D will be created.
10123 
10124    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10125 
10126    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10127    actually needed.
10128 
10129    If you have many matrices with the same non-zero structure to multiply, you
10130    should use MAT_REUSE_MATRIX in all calls but the first or
10131 
10132    Level: intermediate
10133 
10134 .seealso: MatMatMult, MatPtAP()
10135 @*/
10136 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10137 {
10138   PetscErrorCode ierr;
10139   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10140   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10141   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10142   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10143 
10144   PetscFunctionBegin;
10145   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10146   PetscValidType(A,1);
10147   MatCheckPreallocated(A,1);
10148   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10149   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10150   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10151   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10152   PetscValidType(B,2);
10153   MatCheckPreallocated(B,2);
10154   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10155   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10156   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10157   PetscValidPointer(C,3);
10158   MatCheckPreallocated(C,3);
10159   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10160   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10161   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
10162   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
10163   if (scall == MAT_REUSE_MATRIX) {
10164     PetscValidPointer(*D,6);
10165     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10166     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10167     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10168     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10169     PetscFunctionReturn(0);
10170   }
10171   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10172   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10173 
10174   fA = A->ops->matmatmult;
10175   fB = B->ops->matmatmult;
10176   fC = C->ops->matmatmult;
10177   if (fA == fB && fA == fC) {
10178     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10179     mult = fA;
10180   } else {
10181     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10182     char multname[256];
10183     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10184     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10185     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10186     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10187     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10188     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10189     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10190     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10191     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
10192   }
10193   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10194   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10195   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10196   PetscFunctionReturn(0);
10197 }
10198 
10199 /*@
10200    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10201 
10202    Collective on Mat
10203 
10204    Input Parameters:
10205 +  mat - the matrix
10206 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10207 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10208 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10209 
10210    Output Parameter:
10211 .  matredundant - redundant matrix
10212 
10213    Notes:
10214    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10215    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10216 
10217    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10218    calling it.
10219 
10220    Level: advanced
10221 
10222    Concepts: subcommunicator
10223    Concepts: duplicate matrix
10224 
10225 .seealso: MatDestroy()
10226 @*/
10227 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10228 {
10229   PetscErrorCode ierr;
10230   MPI_Comm       comm;
10231   PetscMPIInt    size;
10232   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10233   Mat_Redundant  *redund=NULL;
10234   PetscSubcomm   psubcomm=NULL;
10235   MPI_Comm       subcomm_in=subcomm;
10236   Mat            *matseq;
10237   IS             isrow,iscol;
10238   PetscBool      newsubcomm=PETSC_FALSE;
10239 
10240   PetscFunctionBegin;
10241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10242   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10243     PetscValidPointer(*matredundant,5);
10244     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10245   }
10246 
10247   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10248   if (size == 1 || nsubcomm == 1) {
10249     if (reuse == MAT_INITIAL_MATRIX) {
10250       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10251     } else {
10252       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");
10253       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10254     }
10255     PetscFunctionReturn(0);
10256   }
10257 
10258   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10259   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10260   MatCheckPreallocated(mat,1);
10261 
10262   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10263   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10264     /* create psubcomm, then get subcomm */
10265     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10266     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10267     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10268 
10269     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10270     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10271     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10272     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10273     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10274     newsubcomm = PETSC_TRUE;
10275     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10276   }
10277 
10278   /* get isrow, iscol and a local sequential matrix matseq[0] */
10279   if (reuse == MAT_INITIAL_MATRIX) {
10280     mloc_sub = PETSC_DECIDE;
10281     nloc_sub = PETSC_DECIDE;
10282     if (bs < 1) {
10283       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10284       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10285     } else {
10286       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10287       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10288     }
10289     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10290     rstart = rend - mloc_sub;
10291     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10292     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10293   } else { /* reuse == MAT_REUSE_MATRIX */
10294     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");
10295     /* retrieve subcomm */
10296     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10297     redund = (*matredundant)->redundant;
10298     isrow  = redund->isrow;
10299     iscol  = redund->iscol;
10300     matseq = redund->matseq;
10301   }
10302   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10303 
10304   /* get matredundant over subcomm */
10305   if (reuse == MAT_INITIAL_MATRIX) {
10306     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10307 
10308     /* create a supporting struct and attach it to C for reuse */
10309     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10310     (*matredundant)->redundant = redund;
10311     redund->isrow              = isrow;
10312     redund->iscol              = iscol;
10313     redund->matseq             = matseq;
10314     if (newsubcomm) {
10315       redund->subcomm          = subcomm;
10316     } else {
10317       redund->subcomm          = MPI_COMM_NULL;
10318     }
10319   } else {
10320     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10321   }
10322   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10323   PetscFunctionReturn(0);
10324 }
10325 
10326 /*@C
10327    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10328    a given 'mat' object. Each submatrix can span multiple procs.
10329 
10330    Collective on Mat
10331 
10332    Input Parameters:
10333 +  mat - the matrix
10334 .  subcomm - the subcommunicator obtained by com_split(comm)
10335 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10336 
10337    Output Parameter:
10338 .  subMat - 'parallel submatrices each spans a given subcomm
10339 
10340   Notes:
10341   The submatrix partition across processors is dictated by 'subComm' a
10342   communicator obtained by com_split(comm). The comm_split
10343   is not restriced to be grouped with consecutive original ranks.
10344 
10345   Due the comm_split() usage, the parallel layout of the submatrices
10346   map directly to the layout of the original matrix [wrt the local
10347   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10348   into the 'DiagonalMat' of the subMat, hence it is used directly from
10349   the subMat. However the offDiagMat looses some columns - and this is
10350   reconstructed with MatSetValues()
10351 
10352   Level: advanced
10353 
10354   Concepts: subcommunicator
10355   Concepts: submatrices
10356 
10357 .seealso: MatCreateSubMatrices()
10358 @*/
10359 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10360 {
10361   PetscErrorCode ierr;
10362   PetscMPIInt    commsize,subCommSize;
10363 
10364   PetscFunctionBegin;
10365   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10366   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10367   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10368 
10369   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");
10370   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10371   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10372   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10373   PetscFunctionReturn(0);
10374 }
10375 
10376 /*@
10377    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10378 
10379    Not Collective
10380 
10381    Input Arguments:
10382    mat - matrix to extract local submatrix from
10383    isrow - local row indices for submatrix
10384    iscol - local column indices for submatrix
10385 
10386    Output Arguments:
10387    submat - the submatrix
10388 
10389    Level: intermediate
10390 
10391    Notes:
10392    The submat should be returned with MatRestoreLocalSubMatrix().
10393 
10394    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10395    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10396 
10397    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10398    MatSetValuesBlockedLocal() will also be implemented.
10399 
10400    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10401    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10402 
10403 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10404 @*/
10405 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10406 {
10407   PetscErrorCode ierr;
10408 
10409   PetscFunctionBegin;
10410   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10411   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10412   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10413   PetscCheckSameComm(isrow,2,iscol,3);
10414   PetscValidPointer(submat,4);
10415   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10416 
10417   if (mat->ops->getlocalsubmatrix) {
10418     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10419   } else {
10420     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10421   }
10422   PetscFunctionReturn(0);
10423 }
10424 
10425 /*@
10426    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10427 
10428    Not Collective
10429 
10430    Input Arguments:
10431    mat - matrix to extract local submatrix from
10432    isrow - local row indices for submatrix
10433    iscol - local column indices for submatrix
10434    submat - the submatrix
10435 
10436    Level: intermediate
10437 
10438 .seealso: MatGetLocalSubMatrix()
10439 @*/
10440 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10441 {
10442   PetscErrorCode ierr;
10443 
10444   PetscFunctionBegin;
10445   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10446   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10447   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10448   PetscCheckSameComm(isrow,2,iscol,3);
10449   PetscValidPointer(submat,4);
10450   if (*submat) {
10451     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10452   }
10453 
10454   if (mat->ops->restorelocalsubmatrix) {
10455     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10456   } else {
10457     ierr = MatDestroy(submat);CHKERRQ(ierr);
10458   }
10459   *submat = NULL;
10460   PetscFunctionReturn(0);
10461 }
10462 
10463 /* --------------------------------------------------------*/
10464 /*@
10465    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10466 
10467    Collective on Mat
10468 
10469    Input Parameter:
10470 .  mat - the matrix
10471 
10472    Output Parameter:
10473 .  is - if any rows have zero diagonals this contains the list of them
10474 
10475    Level: developer
10476 
10477    Concepts: matrix-vector product
10478 
10479 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10480 @*/
10481 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10482 {
10483   PetscErrorCode ierr;
10484 
10485   PetscFunctionBegin;
10486   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10487   PetscValidType(mat,1);
10488   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10489   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10490 
10491   if (!mat->ops->findzerodiagonals) {
10492     Vec                diag;
10493     const PetscScalar *a;
10494     PetscInt          *rows;
10495     PetscInt           rStart, rEnd, r, nrow = 0;
10496 
10497     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10498     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10499     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10500     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10501     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10502     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10503     nrow = 0;
10504     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10505     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10506     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10507     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10508   } else {
10509     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10510   }
10511   PetscFunctionReturn(0);
10512 }
10513 
10514 /*@
10515    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10516 
10517    Collective on Mat
10518 
10519    Input Parameter:
10520 .  mat - the matrix
10521 
10522    Output Parameter:
10523 .  is - contains the list of rows with off block diagonal entries
10524 
10525    Level: developer
10526 
10527    Concepts: matrix-vector product
10528 
10529 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10530 @*/
10531 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10532 {
10533   PetscErrorCode ierr;
10534 
10535   PetscFunctionBegin;
10536   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10537   PetscValidType(mat,1);
10538   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10539   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10540 
10541   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10542   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10543   PetscFunctionReturn(0);
10544 }
10545 
10546 /*@C
10547   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10548 
10549   Collective on Mat
10550 
10551   Input Parameters:
10552 . mat - the matrix
10553 
10554   Output Parameters:
10555 . values - the block inverses in column major order (FORTRAN-like)
10556 
10557    Note:
10558    This routine is not available from Fortran.
10559 
10560   Level: advanced
10561 
10562 .seealso: MatInvertBockDiagonalMat
10563 @*/
10564 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10565 {
10566   PetscErrorCode ierr;
10567 
10568   PetscFunctionBegin;
10569   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10570   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10571   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10572   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10573   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10574   PetscFunctionReturn(0);
10575 }
10576 
10577 /*@C
10578   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10579 
10580   Collective on Mat
10581 
10582   Input Parameters:
10583 + mat - the matrix
10584 . nblocks - the number of blocks
10585 - bsizes - the size of each block
10586 
10587   Output Parameters:
10588 . values - the block inverses in column major order (FORTRAN-like)
10589 
10590    Note:
10591    This routine is not available from Fortran.
10592 
10593   Level: advanced
10594 
10595 .seealso: MatInvertBockDiagonal()
10596 @*/
10597 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10598 {
10599   PetscErrorCode ierr;
10600 
10601   PetscFunctionBegin;
10602   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10603   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10604   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10605   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10606   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10607   PetscFunctionReturn(0);
10608 }
10609 
10610 /*@
10611   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10612 
10613   Collective on Mat
10614 
10615   Input Parameters:
10616 . A - the matrix
10617 
10618   Output Parameters:
10619 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10620 
10621   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10622 
10623   Level: advanced
10624 
10625 .seealso: MatInvertBockDiagonal()
10626 @*/
10627 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10628 {
10629   PetscErrorCode     ierr;
10630   const PetscScalar *vals;
10631   PetscInt          *dnnz;
10632   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10633 
10634   PetscFunctionBegin;
10635   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10636   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10637   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10638   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10639   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10640   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10641   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10642   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10643   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10644   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10645   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10646   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10647   for (i = rstart/bs; i < rend/bs; i++) {
10648     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10649   }
10650   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10651   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10652   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10653   PetscFunctionReturn(0);
10654 }
10655 
10656 /*@C
10657     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10658     via MatTransposeColoringCreate().
10659 
10660     Collective on MatTransposeColoring
10661 
10662     Input Parameter:
10663 .   c - coloring context
10664 
10665     Level: intermediate
10666 
10667 .seealso: MatTransposeColoringCreate()
10668 @*/
10669 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10670 {
10671   PetscErrorCode       ierr;
10672   MatTransposeColoring matcolor=*c;
10673 
10674   PetscFunctionBegin;
10675   if (!matcolor) PetscFunctionReturn(0);
10676   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10677 
10678   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10679   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10680   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10681   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10682   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10683   if (matcolor->brows>0) {
10684     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10685   }
10686   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10687   PetscFunctionReturn(0);
10688 }
10689 
10690 /*@C
10691     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10692     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10693     MatTransposeColoring to sparse B.
10694 
10695     Collective on MatTransposeColoring
10696 
10697     Input Parameters:
10698 +   B - sparse matrix B
10699 .   Btdense - symbolic dense matrix B^T
10700 -   coloring - coloring context created with MatTransposeColoringCreate()
10701 
10702     Output Parameter:
10703 .   Btdense - dense matrix B^T
10704 
10705     Level: advanced
10706 
10707      Notes:
10708     These are used internally for some implementations of MatRARt()
10709 
10710 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10711 
10712 .keywords: coloring
10713 @*/
10714 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10715 {
10716   PetscErrorCode ierr;
10717 
10718   PetscFunctionBegin;
10719   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10720   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10721   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10722 
10723   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10724   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10725   PetscFunctionReturn(0);
10726 }
10727 
10728 /*@C
10729     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10730     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10731     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10732     Csp from Cden.
10733 
10734     Collective on MatTransposeColoring
10735 
10736     Input Parameters:
10737 +   coloring - coloring context created with MatTransposeColoringCreate()
10738 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10739 
10740     Output Parameter:
10741 .   Csp - sparse matrix
10742 
10743     Level: advanced
10744 
10745      Notes:
10746     These are used internally for some implementations of MatRARt()
10747 
10748 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10749 
10750 .keywords: coloring
10751 @*/
10752 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10753 {
10754   PetscErrorCode ierr;
10755 
10756   PetscFunctionBegin;
10757   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10758   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10759   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10760 
10761   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10762   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10763   PetscFunctionReturn(0);
10764 }
10765 
10766 /*@C
10767    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10768 
10769    Collective on Mat
10770 
10771    Input Parameters:
10772 +  mat - the matrix product C
10773 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10774 
10775     Output Parameter:
10776 .   color - the new coloring context
10777 
10778     Level: intermediate
10779 
10780 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10781            MatTransColoringApplyDenToSp()
10782 @*/
10783 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10784 {
10785   MatTransposeColoring c;
10786   MPI_Comm             comm;
10787   PetscErrorCode       ierr;
10788 
10789   PetscFunctionBegin;
10790   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10791   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10792   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10793 
10794   c->ctype = iscoloring->ctype;
10795   if (mat->ops->transposecoloringcreate) {
10796     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10797   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10798 
10799   *color = c;
10800   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10801   PetscFunctionReturn(0);
10802 }
10803 
10804 /*@
10805       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10806         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10807         same, otherwise it will be larger
10808 
10809      Not Collective
10810 
10811   Input Parameter:
10812 .    A  - the matrix
10813 
10814   Output Parameter:
10815 .    state - the current state
10816 
10817   Notes:
10818     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10819          different matrices
10820 
10821   Level: intermediate
10822 
10823 @*/
10824 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10825 {
10826   PetscFunctionBegin;
10827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10828   *state = mat->nonzerostate;
10829   PetscFunctionReturn(0);
10830 }
10831 
10832 /*@
10833       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10834                  matrices from each processor
10835 
10836     Collective on MPI_Comm
10837 
10838    Input Parameters:
10839 +    comm - the communicators the parallel matrix will live on
10840 .    seqmat - the input sequential matrices
10841 .    n - number of local columns (or PETSC_DECIDE)
10842 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10843 
10844    Output Parameter:
10845 .    mpimat - the parallel matrix generated
10846 
10847     Level: advanced
10848 
10849    Notes:
10850     The number of columns of the matrix in EACH processor MUST be the same.
10851 
10852 @*/
10853 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10854 {
10855   PetscErrorCode ierr;
10856 
10857   PetscFunctionBegin;
10858   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10859   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");
10860 
10861   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10862   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10863   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10864   PetscFunctionReturn(0);
10865 }
10866 
10867 /*@
10868      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10869                  ranks' ownership ranges.
10870 
10871     Collective on A
10872 
10873    Input Parameters:
10874 +    A   - the matrix to create subdomains from
10875 -    N   - requested number of subdomains
10876 
10877 
10878    Output Parameters:
10879 +    n   - number of subdomains resulting on this rank
10880 -    iss - IS list with indices of subdomains on this rank
10881 
10882     Level: advanced
10883 
10884     Notes:
10885     number of subdomains must be smaller than the communicator size
10886 @*/
10887 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10888 {
10889   MPI_Comm        comm,subcomm;
10890   PetscMPIInt     size,rank,color;
10891   PetscInt        rstart,rend,k;
10892   PetscErrorCode  ierr;
10893 
10894   PetscFunctionBegin;
10895   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10896   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10897   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10898   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);
10899   *n = 1;
10900   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10901   color = rank/k;
10902   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10903   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10904   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10905   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10906   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10907   PetscFunctionReturn(0);
10908 }
10909 
10910 /*@
10911    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10912 
10913    If the interpolation and restriction operators are the same, uses MatPtAP.
10914    If they are not the same, use MatMatMatMult.
10915 
10916    Once the coarse grid problem is constructed, correct for interpolation operators
10917    that are not of full rank, which can legitimately happen in the case of non-nested
10918    geometric multigrid.
10919 
10920    Input Parameters:
10921 +  restrct - restriction operator
10922 .  dA - fine grid matrix
10923 .  interpolate - interpolation operator
10924 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10925 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10926 
10927    Output Parameters:
10928 .  A - the Galerkin coarse matrix
10929 
10930    Options Database Key:
10931 .  -pc_mg_galerkin <both,pmat,mat,none>
10932 
10933    Level: developer
10934 
10935 .keywords: MG, multigrid, Galerkin
10936 
10937 .seealso: MatPtAP(), MatMatMatMult()
10938 @*/
10939 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10940 {
10941   PetscErrorCode ierr;
10942   IS             zerorows;
10943   Vec            diag;
10944 
10945   PetscFunctionBegin;
10946   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10947   /* Construct the coarse grid matrix */
10948   if (interpolate == restrct) {
10949     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10950   } else {
10951     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10952   }
10953 
10954   /* If the interpolation matrix is not of full rank, A will have zero rows.
10955      This can legitimately happen in the case of non-nested geometric multigrid.
10956      In that event, we set the rows of the matrix to the rows of the identity,
10957      ignoring the equations (as the RHS will also be zero). */
10958 
10959   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10960 
10961   if (zerorows != NULL) { /* if there are any zero rows */
10962     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10963     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10964     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10965     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10966     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10967     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10968   }
10969   PetscFunctionReturn(0);
10970 }
10971 
10972 /*@C
10973     MatSetOperation - Allows user to set a matrix operation for any matrix type
10974 
10975    Logically Collective on Mat
10976 
10977     Input Parameters:
10978 +   mat - the matrix
10979 .   op - the name of the operation
10980 -   f - the function that provides the operation
10981 
10982    Level: developer
10983 
10984     Usage:
10985 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10986 $      ierr = MatCreateXXX(comm,...&A);
10987 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10988 
10989     Notes:
10990     See the file include/petscmat.h for a complete list of matrix
10991     operations, which all have the form MATOP_<OPERATION>, where
10992     <OPERATION> is the name (in all capital letters) of the
10993     user interface routine (e.g., MatMult() -> MATOP_MULT).
10994 
10995     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10996     sequence as the usual matrix interface routines, since they
10997     are intended to be accessed via the usual matrix interface
10998     routines, e.g.,
10999 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
11000 
11001     In particular each function MUST return an error code of 0 on success and
11002     nonzero on failure.
11003 
11004     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
11005 
11006 .keywords: matrix, set, operation
11007 
11008 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
11009 @*/
11010 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
11011 {
11012   PetscFunctionBegin;
11013   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11014   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
11015     mat->ops->viewnative = mat->ops->view;
11016   }
11017   (((void(**)(void))mat->ops)[op]) = f;
11018   PetscFunctionReturn(0);
11019 }
11020 
11021 /*@C
11022     MatGetOperation - Gets a matrix operation for any matrix type.
11023 
11024     Not Collective
11025 
11026     Input Parameters:
11027 +   mat - the matrix
11028 -   op - the name of the operation
11029 
11030     Output Parameter:
11031 .   f - the function that provides the operation
11032 
11033     Level: developer
11034 
11035     Usage:
11036 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11037 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11038 
11039     Notes:
11040     See the file include/petscmat.h for a complete list of matrix
11041     operations, which all have the form MATOP_<OPERATION>, where
11042     <OPERATION> is the name (in all capital letters) of the
11043     user interface routine (e.g., MatMult() -> MATOP_MULT).
11044 
11045     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11046 
11047 .keywords: matrix, get, operation
11048 
11049 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11050 @*/
11051 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11052 {
11053   PetscFunctionBegin;
11054   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11055   *f = (((void (**)(void))mat->ops)[op]);
11056   PetscFunctionReturn(0);
11057 }
11058 
11059 /*@
11060     MatHasOperation - Determines whether the given matrix supports the particular
11061     operation.
11062 
11063    Not Collective
11064 
11065    Input Parameters:
11066 +  mat - the matrix
11067 -  op - the operation, for example, MATOP_GET_DIAGONAL
11068 
11069    Output Parameter:
11070 .  has - either PETSC_TRUE or PETSC_FALSE
11071 
11072    Level: advanced
11073 
11074    Notes:
11075    See the file include/petscmat.h for a complete list of matrix
11076    operations, which all have the form MATOP_<OPERATION>, where
11077    <OPERATION> is the name (in all capital letters) of the
11078    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11079 
11080 .keywords: matrix, has, operation
11081 
11082 .seealso: MatCreateShell()
11083 @*/
11084 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11085 {
11086   PetscErrorCode ierr;
11087 
11088   PetscFunctionBegin;
11089   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11090   PetscValidType(mat,1);
11091   PetscValidPointer(has,3);
11092   if (mat->ops->hasoperation) {
11093     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11094   } else {
11095     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11096     else {
11097       *has = PETSC_FALSE;
11098       if (op == MATOP_CREATE_SUBMATRIX) {
11099         PetscMPIInt size;
11100 
11101         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11102         if (size == 1) {
11103           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11104         }
11105       }
11106     }
11107   }
11108   PetscFunctionReturn(0);
11109 }
11110 
11111 /*@
11112     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11113     of the matrix are congruent
11114 
11115    Collective on mat
11116 
11117    Input Parameters:
11118 .  mat - the matrix
11119 
11120    Output Parameter:
11121 .  cong - either PETSC_TRUE or PETSC_FALSE
11122 
11123    Level: beginner
11124 
11125    Notes:
11126 
11127 .keywords: matrix, has
11128 
11129 .seealso: MatCreate(), MatSetSizes()
11130 @*/
11131 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11132 {
11133   PetscErrorCode ierr;
11134 
11135   PetscFunctionBegin;
11136   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11137   PetscValidType(mat,1);
11138   PetscValidPointer(cong,2);
11139   if (!mat->rmap || !mat->cmap) {
11140     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11141     PetscFunctionReturn(0);
11142   }
11143   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11144     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11145     if (*cong) mat->congruentlayouts = 1;
11146     else       mat->congruentlayouts = 0;
11147   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11148   PetscFunctionReturn(0);
11149 }
11150 
11151 /*@
11152     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11153     e.g., matrx product of MatPtAP.
11154 
11155    Collective on mat
11156 
11157    Input Parameters:
11158 .  mat - the matrix
11159 
11160    Output Parameter:
11161 .  mat - the matrix with intermediate data structures released
11162 
11163    Level: advanced
11164 
11165    Notes:
11166 
11167 .keywords: matrix
11168 
11169 .seealso: MatPtAP(), MatMatMult()
11170 @*/
11171 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11172 {
11173   PetscErrorCode ierr;
11174 
11175   PetscFunctionBegin;
11176   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11177   PetscValidType(mat,1);
11178   if (mat->ops->freeintermediatedatastructures) {
11179     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11180   }
11181   PetscFunctionReturn(0);
11182 }
11183