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