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