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