xref: /petsc/src/mat/interface/matrix.c (revision bb046f40e70244212ea67d48e978f41dcab200d8)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
694   MatCheckPreallocated(mat,1);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
722   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
723   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
724   PetscFunctionReturn(0);
725 }
726 
727 /*@C
728    MatSetOptionsPrefix - Sets the prefix used for searching for all
729    Mat options in the database.
730 
731    Logically Collective on Mat
732 
733    Input Parameter:
734 +  A - the Mat context
735 -  prefix - the prefix to prepend to all option names
736 
737    Notes:
738    A hyphen (-) must NOT be given at the beginning of the prefix name.
739    The first character of all runtime options is AUTOMATICALLY the hyphen.
740 
741    Level: advanced
742 
743 .keywords: Mat, set, options, prefix, database
744 
745 .seealso: MatSetFromOptions()
746 @*/
747 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
748 {
749   PetscErrorCode ierr;
750 
751   PetscFunctionBegin;
752   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
753   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
754   PetscFunctionReturn(0);
755 }
756 
757 /*@C
758    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
759    Mat options in the database.
760 
761    Logically Collective on Mat
762 
763    Input Parameters:
764 +  A - the Mat context
765 -  prefix - the prefix to prepend to all option names
766 
767    Notes:
768    A hyphen (-) must NOT be given at the beginning of the prefix name.
769    The first character of all runtime options is AUTOMATICALLY the hyphen.
770 
771    Level: advanced
772 
773 .keywords: Mat, append, options, prefix, database
774 
775 .seealso: MatGetOptionsPrefix()
776 @*/
777 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
778 {
779   PetscErrorCode ierr;
780 
781   PetscFunctionBegin;
782   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
783   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
784   PetscFunctionReturn(0);
785 }
786 
787 /*@C
788    MatGetOptionsPrefix - Sets the prefix used for searching for all
789    Mat options in the database.
790 
791    Not Collective
792 
793    Input Parameter:
794 .  A - the Mat context
795 
796    Output Parameter:
797 .  prefix - pointer to the prefix string used
798 
799    Notes:
800     On the fortran side, the user should pass in a string 'prefix' of
801    sufficient length to hold the prefix.
802 
803    Level: advanced
804 
805 .keywords: Mat, get, options, prefix, database
806 
807 .seealso: MatAppendOptionsPrefix()
808 @*/
809 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
810 {
811   PetscErrorCode ierr;
812 
813   PetscFunctionBegin;
814   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
815   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
816   PetscFunctionReturn(0);
817 }
818 
819 /*@
820    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
821 
822    Collective on Mat
823 
824    Input Parameters:
825 .  A - the Mat context
826 
827    Notes:
828    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
829    Currently support MPIAIJ and SEQAIJ.
830 
831    Level: beginner
832 
833 .keywords: Mat, ResetPreallocation
834 
835 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
836 @*/
837 PetscErrorCode MatResetPreallocation(Mat A)
838 {
839   PetscErrorCode ierr;
840 
841   PetscFunctionBegin;
842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
843   PetscValidType(A,1);
844   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
845   PetscFunctionReturn(0);
846 }
847 
848 
849 /*@
850    MatSetUp - Sets up the internal matrix data structures for the later use.
851 
852    Collective on Mat
853 
854    Input Parameters:
855 .  A - the Mat context
856 
857    Notes:
858    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
859 
860    If a suitable preallocation routine is used, this function does not need to be called.
861 
862    See the Performance chapter of the PETSc users manual for how to preallocate matrices
863 
864    Level: beginner
865 
866 .keywords: Mat, setup
867 
868 .seealso: MatCreate(), MatDestroy()
869 @*/
870 PetscErrorCode MatSetUp(Mat A)
871 {
872   PetscMPIInt    size;
873   PetscErrorCode ierr;
874 
875   PetscFunctionBegin;
876   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
877   if (!((PetscObject)A)->type_name) {
878     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
879     if (size == 1) {
880       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
881     } else {
882       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
883     }
884   }
885   if (!A->preallocated && A->ops->setup) {
886     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
887     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
888   }
889   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
890   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
891   A->preallocated = PETSC_TRUE;
892   PetscFunctionReturn(0);
893 }
894 
895 #if defined(PETSC_HAVE_SAWS)
896 #include <petscviewersaws.h>
897 #endif
898 /*@C
899    MatView - Visualizes a matrix object.
900 
901    Collective on Mat
902 
903    Input Parameters:
904 +  mat - the matrix
905 -  viewer - visualization context
906 
907   Notes:
908   The available visualization contexts include
909 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
910 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
911 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
912 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
913 
914    The user can open alternative visualization contexts with
915 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
916 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
917          specified file; corresponding input uses MatLoad()
918 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
919          an X window display
920 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
921          Currently only the sequential dense and AIJ
922          matrix types support the Socket viewer.
923 
924    The user can call PetscViewerPushFormat() to specify the output
925    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
926    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
927 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
928 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
929 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
930 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
931          format common among all matrix types
932 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
933          format (which is in many cases the same as the default)
934 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
935          size and structure (not the matrix entries)
936 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
937          the matrix structure
938 
939    Options Database Keys:
940 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
941 .  -mat_view ::ascii_info_detail - Prints more detailed info
942 .  -mat_view - Prints matrix in ASCII format
943 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
944 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
945 .  -display <name> - Sets display name (default is host)
946 .  -draw_pause <sec> - Sets number of seconds to pause after display
947 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
948 .  -viewer_socket_machine <machine> -
949 .  -viewer_socket_port <port> -
950 .  -mat_view binary - save matrix to file in binary format
951 -  -viewer_binary_filename <name> -
952    Level: beginner
953 
954    Notes:
955     See the manual page for MatLoad() for the exact format of the binary file when the binary
956       viewer is used.
957 
958       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
959       viewer is used.
960 
961       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
962       and then use the following mouse functions.
963 + left mouse: zoom in
964 . middle mouse: zoom out
965 - right mouse: continue with the simulation
966 
967    Concepts: matrices^viewing
968    Concepts: matrices^plotting
969    Concepts: matrices^printing
970 
971 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
972           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
973 @*/
974 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
975 {
976   PetscErrorCode    ierr;
977   PetscInt          rows,cols,rbs,cbs;
978   PetscBool         iascii,ibinary;
979   PetscViewerFormat format;
980   PetscMPIInt       size;
981 #if defined(PETSC_HAVE_SAWS)
982   PetscBool         issaws;
983 #endif
984 
985   PetscFunctionBegin;
986   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
987   PetscValidType(mat,1);
988   if (!viewer) {
989     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
990   }
991   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
992   PetscCheckSameComm(mat,1,viewer,2);
993   MatCheckPreallocated(mat,1);
994   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
995   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
996   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
997   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
998   if (ibinary) {
999     PetscBool mpiio;
1000     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1001     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1002   }
1003 
1004   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1005   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1006   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1007     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1008   }
1009 
1010 #if defined(PETSC_HAVE_SAWS)
1011   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1012 #endif
1013   if (iascii) {
1014     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1015     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1016     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1017       MatNullSpace nullsp,transnullsp;
1018 
1019       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1020       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1021       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1022       if (rbs != 1 || cbs != 1) {
1023         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1024         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1025       } else {
1026         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1027       }
1028       if (mat->factortype) {
1029         MatSolverType solver;
1030         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1031         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1032       }
1033       if (mat->ops->getinfo) {
1034         MatInfo info;
1035         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1036         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1037         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1038       }
1039       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1040       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1041       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1042       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1043       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1044       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1045     }
1046 #if defined(PETSC_HAVE_SAWS)
1047   } else if (issaws) {
1048     PetscMPIInt rank;
1049 
1050     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1051     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1052     if (!((PetscObject)mat)->amsmem && !rank) {
1053       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1054     }
1055 #endif
1056   }
1057   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1058     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1059     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1060     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1061   } else if (mat->ops->view) {
1062     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1063     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1064     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1065   }
1066   if (iascii) {
1067     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1068     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1069       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1070     }
1071   }
1072   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1073   PetscFunctionReturn(0);
1074 }
1075 
1076 #if defined(PETSC_USE_DEBUG)
1077 #include <../src/sys/totalview/tv_data_display.h>
1078 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1079 {
1080   TV_add_row("Local rows", "int", &mat->rmap->n);
1081   TV_add_row("Local columns", "int", &mat->cmap->n);
1082   TV_add_row("Global rows", "int", &mat->rmap->N);
1083   TV_add_row("Global columns", "int", &mat->cmap->N);
1084   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1085   return TV_format_OK;
1086 }
1087 #endif
1088 
1089 /*@C
1090    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1091    with MatView().  The matrix format is determined from the options database.
1092    Generates a parallel MPI matrix if the communicator has more than one
1093    processor.  The default matrix type is AIJ.
1094 
1095    Collective on PetscViewer
1096 
1097    Input Parameters:
1098 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1099             or some related function before a call to MatLoad()
1100 -  viewer - binary/HDF5 file viewer
1101 
1102    Options Database Keys:
1103    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1104    block size
1105 .    -matload_block_size <bs>
1106 
1107    Level: beginner
1108 
1109    Notes:
1110    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1111    Mat before calling this routine if you wish to set it from the options database.
1112 
1113    MatLoad() automatically loads into the options database any options
1114    given in the file filename.info where filename is the name of the file
1115    that was passed to the PetscViewerBinaryOpen(). The options in the info
1116    file will be ignored if you use the -viewer_binary_skip_info option.
1117 
1118    If the type or size of newmat is not set before a call to MatLoad, PETSc
1119    sets the default matrix type AIJ and sets the local and global sizes.
1120    If type and/or size is already set, then the same are used.
1121 
1122    In parallel, each processor can load a subset of rows (or the
1123    entire matrix).  This routine is especially useful when a large
1124    matrix is stored on disk and only part of it is desired on each
1125    processor.  For example, a parallel solver may access only some of
1126    the rows from each processor.  The algorithm used here reads
1127    relatively small blocks of data rather than reading the entire
1128    matrix and then subsetting it.
1129 
1130    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1131    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1132    or the sequence like
1133 $    PetscViewer v;
1134 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1135 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1136 $    PetscViewerSetFromOptions(v);
1137 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1138 $    PetscViewerFileSetName(v,"datafile");
1139    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1140 $ -viewer_type {binary,hdf5}
1141 
1142    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1143    and src/mat/examples/tutorials/ex10.c with the second approach.
1144 
1145    Notes about the PETSc binary format:
1146    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1147    is read onto rank 0 and then shipped to its destination rank, one after another.
1148    Multiple objects, both matrices and vectors, can be stored within the same file.
1149    Their PetscObject name is ignored; they are loaded in the order of their storage.
1150 
1151    Most users should not need to know the details of the binary storage
1152    format, since MatLoad() and MatView() completely hide these details.
1153    But for anyone who's interested, the standard binary matrix storage
1154    format is
1155 
1156 $    int    MAT_FILE_CLASSID
1157 $    int    number of rows
1158 $    int    number of columns
1159 $    int    total number of nonzeros
1160 $    int    *number nonzeros in each row
1161 $    int    *column indices of all nonzeros (starting index is zero)
1162 $    PetscScalar *values of all nonzeros
1163 
1164    PETSc automatically does the byte swapping for
1165 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1166 linux, Windows and the paragon; thus if you write your own binary
1167 read/write routines you have to swap the bytes; see PetscBinaryRead()
1168 and PetscBinaryWrite() to see how this may be done.
1169 
1170    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1171    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1172    Each processor's chunk is loaded independently by its owning rank.
1173    Multiple objects, both matrices and vectors, can be stored within the same file.
1174    They are looked up by their PetscObject name.
1175 
1176    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1177    by default the same structure and naming of the AIJ arrays and column count
1178    (see PetscViewerHDF5SetAIJNames())
1179    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1180 $    save example.mat A b -v7.3
1181    can be directly read by this routine (see Reference 1 for details).
1182    Note that depending on your MATLAB version, this format might be a default,
1183    otherwise you can set it as default in Preferences.
1184 
1185    Unless -nocompression flag is used to save the file in MATLAB,
1186    PETSc must be configured with ZLIB package.
1187 
1188    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1189 
1190    Current HDF5 (MAT-File) limitations:
1191    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1192 
1193    Corresponding MatView() is not yet implemented.
1194 
1195    The loaded matrix is actually a transpose of the original one in MATLAB,
1196    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1197    With this format, matrix is automatically transposed by PETSc,
1198    unless the matrix is marked as SPD or symmetric
1199    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1200 
1201    References:
1202 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1203 
1204 .keywords: matrix, load, binary, input, HDF5
1205 
1206 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad()
1207 
1208  @*/
1209 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1210 {
1211   PetscErrorCode ierr;
1212   PetscBool      flg;
1213 
1214   PetscFunctionBegin;
1215   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1216   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1217 
1218   if (!((PetscObject)newmat)->type_name) {
1219     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1220   }
1221 
1222   flg  = PETSC_FALSE;
1223   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1224   if (flg) {
1225     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1226     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1227   }
1228   flg  = PETSC_FALSE;
1229   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1230   if (flg) {
1231     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1232   }
1233 
1234   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1235   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1236   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1237   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1238   PetscFunctionReturn(0);
1239 }
1240 
1241 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1242 {
1243   PetscErrorCode ierr;
1244   Mat_Redundant  *redund = *redundant;
1245   PetscInt       i;
1246 
1247   PetscFunctionBegin;
1248   if (redund){
1249     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1250       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1251       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1252       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1253     } else {
1254       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1255       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1256       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1257       for (i=0; i<redund->nrecvs; i++) {
1258         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1259         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1260       }
1261       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1262     }
1263 
1264     if (redund->subcomm) {
1265       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1266     }
1267     ierr = PetscFree(redund);CHKERRQ(ierr);
1268   }
1269   PetscFunctionReturn(0);
1270 }
1271 
1272 /*@
1273    MatDestroy - Frees space taken by a matrix.
1274 
1275    Collective on Mat
1276 
1277    Input Parameter:
1278 .  A - the matrix
1279 
1280    Level: beginner
1281 
1282 @*/
1283 PetscErrorCode MatDestroy(Mat *A)
1284 {
1285   PetscErrorCode ierr;
1286 
1287   PetscFunctionBegin;
1288   if (!*A) PetscFunctionReturn(0);
1289   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1290   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1291 
1292   /* if memory was published with SAWs then destroy it */
1293   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1294   if ((*A)->ops->destroy) {
1295     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1296   }
1297 
1298   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1299   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1300   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1301   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1302   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1303   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1304   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1305   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1306   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1307   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1308   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1309   PetscFunctionReturn(0);
1310 }
1311 
1312 /*@C
1313    MatSetValues - Inserts or adds a block of values into a matrix.
1314    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1315    MUST be called after all calls to MatSetValues() have been completed.
1316 
1317    Not Collective
1318 
1319    Input Parameters:
1320 +  mat - the matrix
1321 .  v - a logically two-dimensional array of values
1322 .  m, idxm - the number of rows and their global indices
1323 .  n, idxn - the number of columns and their global indices
1324 -  addv - either ADD_VALUES or INSERT_VALUES, where
1325    ADD_VALUES adds values to any existing entries, and
1326    INSERT_VALUES replaces existing entries with new values
1327 
1328    Notes:
1329    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1330       MatSetUp() before using this routine
1331 
1332    By default the values, v, are row-oriented. See MatSetOption() for other options.
1333 
1334    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1335    options cannot be mixed without intervening calls to the assembly
1336    routines.
1337 
1338    MatSetValues() uses 0-based row and column numbers in Fortran
1339    as well as in C.
1340 
1341    Negative indices may be passed in idxm and idxn, these rows and columns are
1342    simply ignored. This allows easily inserting element stiffness matrices
1343    with homogeneous Dirchlet boundary conditions that you don't want represented
1344    in the matrix.
1345 
1346    Efficiency Alert:
1347    The routine MatSetValuesBlocked() may offer much better efficiency
1348    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1349 
1350    Level: beginner
1351 
1352    Developer Notes:
1353     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1354                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1355 
1356    Concepts: matrices^putting entries in
1357 
1358 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1359           InsertMode, INSERT_VALUES, ADD_VALUES
1360 @*/
1361 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1362 {
1363   PetscErrorCode ierr;
1364 #if defined(PETSC_USE_DEBUG)
1365   PetscInt       i,j;
1366 #endif
1367 
1368   PetscFunctionBeginHot;
1369   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1370   PetscValidType(mat,1);
1371   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1372   PetscValidIntPointer(idxm,3);
1373   PetscValidIntPointer(idxn,5);
1374   PetscValidScalarPointer(v,6);
1375   MatCheckPreallocated(mat,1);
1376   if (mat->insertmode == NOT_SET_VALUES) {
1377     mat->insertmode = addv;
1378   }
1379 #if defined(PETSC_USE_DEBUG)
1380   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1381   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1382   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1383 
1384   for (i=0; i<m; i++) {
1385     for (j=0; j<n; j++) {
1386       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1387 #if defined(PETSC_USE_COMPLEX)
1388         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1389 #else
1390         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1391 #endif
1392     }
1393   }
1394 #endif
1395 
1396   if (mat->assembled) {
1397     mat->was_assembled = PETSC_TRUE;
1398     mat->assembled     = PETSC_FALSE;
1399   }
1400   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1401   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1402   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1403 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1404   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1405     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1406   }
1407 #endif
1408   PetscFunctionReturn(0);
1409 }
1410 
1411 
1412 /*@
1413    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1414         values into a matrix
1415 
1416    Not Collective
1417 
1418    Input Parameters:
1419 +  mat - the matrix
1420 .  row - the (block) row to set
1421 -  v - a logically two-dimensional array of values
1422 
1423    Notes:
1424    By the values, v, are column-oriented (for the block version) and sorted
1425 
1426    All the nonzeros in the row must be provided
1427 
1428    The matrix must have previously had its column indices set
1429 
1430    The row must belong to this process
1431 
1432    Level: intermediate
1433 
1434    Concepts: matrices^putting entries in
1435 
1436 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1437           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1438 @*/
1439 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1440 {
1441   PetscErrorCode ierr;
1442   PetscInt       globalrow;
1443 
1444   PetscFunctionBegin;
1445   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1446   PetscValidType(mat,1);
1447   PetscValidScalarPointer(v,2);
1448   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1449   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1450 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1451   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1452     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1453   }
1454 #endif
1455   PetscFunctionReturn(0);
1456 }
1457 
1458 /*@
1459    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1460         values into a matrix
1461 
1462    Not Collective
1463 
1464    Input Parameters:
1465 +  mat - the matrix
1466 .  row - the (block) row to set
1467 -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values
1468 
1469    Notes:
1470    The values, v, are column-oriented for the block version.
1471 
1472    All the nonzeros in the row must be provided
1473 
1474    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1475 
1476    The row must belong to this process
1477 
1478    Level: advanced
1479 
1480    Concepts: matrices^putting entries in
1481 
1482 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1483           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1484 @*/
1485 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1486 {
1487   PetscErrorCode ierr;
1488 
1489   PetscFunctionBeginHot;
1490   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1491   PetscValidType(mat,1);
1492   MatCheckPreallocated(mat,1);
1493   PetscValidScalarPointer(v,2);
1494 #if defined(PETSC_USE_DEBUG)
1495   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1496   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1497 #endif
1498   mat->insertmode = INSERT_VALUES;
1499 
1500   if (mat->assembled) {
1501     mat->was_assembled = PETSC_TRUE;
1502     mat->assembled     = PETSC_FALSE;
1503   }
1504   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1505   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1506   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1507   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1508 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1509   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1510     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1511   }
1512 #endif
1513   PetscFunctionReturn(0);
1514 }
1515 
1516 /*@
1517    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1518      Using structured grid indexing
1519 
1520    Not Collective
1521 
1522    Input Parameters:
1523 +  mat - the matrix
1524 .  m - number of rows being entered
1525 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1526 .  n - number of columns being entered
1527 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1528 .  v - a logically two-dimensional array of values
1529 -  addv - either ADD_VALUES or INSERT_VALUES, where
1530    ADD_VALUES adds values to any existing entries, and
1531    INSERT_VALUES replaces existing entries with new values
1532 
1533    Notes:
1534    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1535 
1536    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1537    options cannot be mixed without intervening calls to the assembly
1538    routines.
1539 
1540    The grid coordinates are across the entire grid, not just the local portion
1541 
1542    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1543    as well as in C.
1544 
1545    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1546 
1547    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1548    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1549 
1550    The columns and rows in the stencil passed in MUST be contained within the
1551    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1552    if you create a DMDA with an overlap of one grid level and on a particular process its first
1553    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1554    first i index you can use in your column and row indices in MatSetStencil() is 5.
1555 
1556    In Fortran idxm and idxn should be declared as
1557 $     MatStencil idxm(4,m),idxn(4,n)
1558    and the values inserted using
1559 $    idxm(MatStencil_i,1) = i
1560 $    idxm(MatStencil_j,1) = j
1561 $    idxm(MatStencil_k,1) = k
1562 $    idxm(MatStencil_c,1) = c
1563    etc
1564 
1565    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1566    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1567    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1568    DM_BOUNDARY_PERIODIC boundary type.
1569 
1570    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1571    a single value per point) you can skip filling those indices.
1572 
1573    Inspired by the structured grid interface to the HYPRE package
1574    (http://www.llnl.gov/CASC/hypre)
1575 
1576    Efficiency Alert:
1577    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1578    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1579 
1580    Level: beginner
1581 
1582    Concepts: matrices^putting entries in
1583 
1584 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1585           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1586 @*/
1587 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1588 {
1589   PetscErrorCode ierr;
1590   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1591   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1592   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1593 
1594   PetscFunctionBegin;
1595   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1596   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1597   PetscValidType(mat,1);
1598   PetscValidIntPointer(idxm,3);
1599   PetscValidIntPointer(idxn,5);
1600   PetscValidScalarPointer(v,6);
1601 
1602   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1603     jdxm = buf; jdxn = buf+m;
1604   } else {
1605     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1606     jdxm = bufm; jdxn = bufn;
1607   }
1608   for (i=0; i<m; i++) {
1609     for (j=0; j<3-sdim; j++) dxm++;
1610     tmp = *dxm++ - starts[0];
1611     for (j=0; j<dim-1; j++) {
1612       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1613       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1614     }
1615     if (mat->stencil.noc) dxm++;
1616     jdxm[i] = tmp;
1617   }
1618   for (i=0; i<n; i++) {
1619     for (j=0; j<3-sdim; j++) dxn++;
1620     tmp = *dxn++ - starts[0];
1621     for (j=0; j<dim-1; j++) {
1622       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1623       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1624     }
1625     if (mat->stencil.noc) dxn++;
1626     jdxn[i] = tmp;
1627   }
1628   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1629   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1630   PetscFunctionReturn(0);
1631 }
1632 
1633 /*@
1634    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1635      Using structured grid indexing
1636 
1637    Not Collective
1638 
1639    Input Parameters:
1640 +  mat - the matrix
1641 .  m - number of rows being entered
1642 .  idxm - grid coordinates for matrix rows being entered
1643 .  n - number of columns being entered
1644 .  idxn - grid coordinates for matrix columns being entered
1645 .  v - a logically two-dimensional array of values
1646 -  addv - either ADD_VALUES or INSERT_VALUES, where
1647    ADD_VALUES adds values to any existing entries, and
1648    INSERT_VALUES replaces existing entries with new values
1649 
1650    Notes:
1651    By default the values, v, are row-oriented and unsorted.
1652    See MatSetOption() for other options.
1653 
1654    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1655    options cannot be mixed without intervening calls to the assembly
1656    routines.
1657 
1658    The grid coordinates are across the entire grid, not just the local portion
1659 
1660    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1661    as well as in C.
1662 
1663    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1664 
1665    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1666    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1667 
1668    The columns and rows in the stencil passed in MUST be contained within the
1669    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1670    if you create a DMDA with an overlap of one grid level and on a particular process its first
1671    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1672    first i index you can use in your column and row indices in MatSetStencil() is 5.
1673 
1674    In Fortran idxm and idxn should be declared as
1675 $     MatStencil idxm(4,m),idxn(4,n)
1676    and the values inserted using
1677 $    idxm(MatStencil_i,1) = i
1678 $    idxm(MatStencil_j,1) = j
1679 $    idxm(MatStencil_k,1) = k
1680    etc
1681 
1682    Negative indices may be passed in idxm and idxn, these rows and columns are
1683    simply ignored. This allows easily inserting element stiffness matrices
1684    with homogeneous Dirchlet boundary conditions that you don't want represented
1685    in the matrix.
1686 
1687    Inspired by the structured grid interface to the HYPRE package
1688    (http://www.llnl.gov/CASC/hypre)
1689 
1690    Level: beginner
1691 
1692    Concepts: matrices^putting entries in
1693 
1694 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1695           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1696           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1697 @*/
1698 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1699 {
1700   PetscErrorCode ierr;
1701   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1702   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1703   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1704 
1705   PetscFunctionBegin;
1706   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1708   PetscValidType(mat,1);
1709   PetscValidIntPointer(idxm,3);
1710   PetscValidIntPointer(idxn,5);
1711   PetscValidScalarPointer(v,6);
1712 
1713   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1714     jdxm = buf; jdxn = buf+m;
1715   } else {
1716     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1717     jdxm = bufm; jdxn = bufn;
1718   }
1719   for (i=0; i<m; i++) {
1720     for (j=0; j<3-sdim; j++) dxm++;
1721     tmp = *dxm++ - starts[0];
1722     for (j=0; j<sdim-1; j++) {
1723       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1724       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1725     }
1726     dxm++;
1727     jdxm[i] = tmp;
1728   }
1729   for (i=0; i<n; i++) {
1730     for (j=0; j<3-sdim; j++) dxn++;
1731     tmp = *dxn++ - starts[0];
1732     for (j=0; j<sdim-1; j++) {
1733       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1734       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1735     }
1736     dxn++;
1737     jdxn[i] = tmp;
1738   }
1739   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1740   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1741 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1742   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1743     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1744   }
1745 #endif
1746   PetscFunctionReturn(0);
1747 }
1748 
1749 /*@
1750    MatSetStencil - Sets the grid information for setting values into a matrix via
1751         MatSetValuesStencil()
1752 
1753    Not Collective
1754 
1755    Input Parameters:
1756 +  mat - the matrix
1757 .  dim - dimension of the grid 1, 2, or 3
1758 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1759 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1760 -  dof - number of degrees of freedom per node
1761 
1762 
1763    Inspired by the structured grid interface to the HYPRE package
1764    (www.llnl.gov/CASC/hyper)
1765 
1766    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1767    user.
1768 
1769    Level: beginner
1770 
1771    Concepts: matrices^putting entries in
1772 
1773 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1774           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1775 @*/
1776 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1777 {
1778   PetscInt i;
1779 
1780   PetscFunctionBegin;
1781   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1782   PetscValidIntPointer(dims,3);
1783   PetscValidIntPointer(starts,4);
1784 
1785   mat->stencil.dim = dim + (dof > 1);
1786   for (i=0; i<dim; i++) {
1787     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1788     mat->stencil.starts[i] = starts[dim-i-1];
1789   }
1790   mat->stencil.dims[dim]   = dof;
1791   mat->stencil.starts[dim] = 0;
1792   mat->stencil.noc         = (PetscBool)(dof == 1);
1793   PetscFunctionReturn(0);
1794 }
1795 
1796 /*@C
1797    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1798 
1799    Not Collective
1800 
1801    Input Parameters:
1802 +  mat - the matrix
1803 .  v - a logically two-dimensional array of values
1804 .  m, idxm - the number of block rows and their global block indices
1805 .  n, idxn - the number of block columns and their global block indices
1806 -  addv - either ADD_VALUES or INSERT_VALUES, where
1807    ADD_VALUES adds values to any existing entries, and
1808    INSERT_VALUES replaces existing entries with new values
1809 
1810    Notes:
1811    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1812    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1813 
1814    The m and n count the NUMBER of blocks in the row direction and column direction,
1815    NOT the total number of rows/columns; for example, if the block size is 2 and
1816    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1817    The values in idxm would be 1 2; that is the first index for each block divided by
1818    the block size.
1819 
1820    Note that you must call MatSetBlockSize() when constructing this matrix (before
1821    preallocating it).
1822 
1823    By default the values, v, are row-oriented, so the layout of
1824    v is the same as for MatSetValues(). See MatSetOption() for other options.
1825 
1826    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1827    options cannot be mixed without intervening calls to the assembly
1828    routines.
1829 
1830    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1831    as well as in C.
1832 
1833    Negative indices may be passed in idxm and idxn, these rows and columns are
1834    simply ignored. This allows easily inserting element stiffness matrices
1835    with homogeneous Dirchlet boundary conditions that you don't want represented
1836    in the matrix.
1837 
1838    Each time an entry is set within a sparse matrix via MatSetValues(),
1839    internal searching must be done to determine where to place the
1840    data in the matrix storage space.  By instead inserting blocks of
1841    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1842    reduced.
1843 
1844    Example:
1845 $   Suppose m=n=2 and block size(bs) = 2 The array is
1846 $
1847 $   1  2  | 3  4
1848 $   5  6  | 7  8
1849 $   - - - | - - -
1850 $   9  10 | 11 12
1851 $   13 14 | 15 16
1852 $
1853 $   v[] should be passed in like
1854 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1855 $
1856 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1857 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1858 
1859    Level: intermediate
1860 
1861    Concepts: matrices^putting entries in blocked
1862 
1863 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1864 @*/
1865 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1866 {
1867   PetscErrorCode ierr;
1868 
1869   PetscFunctionBeginHot;
1870   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1871   PetscValidType(mat,1);
1872   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1873   PetscValidIntPointer(idxm,3);
1874   PetscValidIntPointer(idxn,5);
1875   PetscValidScalarPointer(v,6);
1876   MatCheckPreallocated(mat,1);
1877   if (mat->insertmode == NOT_SET_VALUES) {
1878     mat->insertmode = addv;
1879   }
1880 #if defined(PETSC_USE_DEBUG)
1881   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1882   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1883   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1884 #endif
1885 
1886   if (mat->assembled) {
1887     mat->was_assembled = PETSC_TRUE;
1888     mat->assembled     = PETSC_FALSE;
1889   }
1890   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1891   if (mat->ops->setvaluesblocked) {
1892     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1893   } else {
1894     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1895     PetscInt i,j,bs,cbs;
1896     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1897     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1898       iidxm = buf; iidxn = buf + m*bs;
1899     } else {
1900       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1901       iidxm = bufr; iidxn = bufc;
1902     }
1903     for (i=0; i<m; i++) {
1904       for (j=0; j<bs; j++) {
1905         iidxm[i*bs+j] = bs*idxm[i] + j;
1906       }
1907     }
1908     for (i=0; i<n; i++) {
1909       for (j=0; j<cbs; j++) {
1910         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1911       }
1912     }
1913     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1914     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1915   }
1916   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1917 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1918   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1919     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1920   }
1921 #endif
1922   PetscFunctionReturn(0);
1923 }
1924 
1925 /*@
1926    MatGetValues - Gets a block of values from a matrix.
1927 
1928    Not Collective; currently only returns a local block
1929 
1930    Input Parameters:
1931 +  mat - the matrix
1932 .  v - a logically two-dimensional array for storing the values
1933 .  m, idxm - the number of rows and their global indices
1934 -  n, idxn - the number of columns and their global indices
1935 
1936    Notes:
1937    The user must allocate space (m*n PetscScalars) for the values, v.
1938    The values, v, are then returned in a row-oriented format,
1939    analogous to that used by default in MatSetValues().
1940 
1941    MatGetValues() uses 0-based row and column numbers in
1942    Fortran as well as in C.
1943 
1944    MatGetValues() requires that the matrix has been assembled
1945    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1946    MatSetValues() and MatGetValues() CANNOT be made in succession
1947    without intermediate matrix assembly.
1948 
1949    Negative row or column indices will be ignored and those locations in v[] will be
1950    left unchanged.
1951 
1952    Level: advanced
1953 
1954    Concepts: matrices^accessing values
1955 
1956 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1957 @*/
1958 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1959 {
1960   PetscErrorCode ierr;
1961 
1962   PetscFunctionBegin;
1963   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1964   PetscValidType(mat,1);
1965   if (!m || !n) PetscFunctionReturn(0);
1966   PetscValidIntPointer(idxm,3);
1967   PetscValidIntPointer(idxn,5);
1968   PetscValidScalarPointer(v,6);
1969   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1970   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1971   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1972   MatCheckPreallocated(mat,1);
1973 
1974   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1975   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1976   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1977   PetscFunctionReturn(0);
1978 }
1979 
1980 /*@
1981   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1982   the same size. Currently, this can only be called once and creates the given matrix.
1983 
1984   Not Collective
1985 
1986   Input Parameters:
1987 + mat - the matrix
1988 . nb - the number of blocks
1989 . bs - the number of rows (and columns) in each block
1990 . rows - a concatenation of the rows for each block
1991 - v - a concatenation of logically two-dimensional arrays of values
1992 
1993   Notes:
1994   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1995 
1996   Level: advanced
1997 
1998   Concepts: matrices^putting entries in
1999 
2000 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2001           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2002 @*/
2003 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2004 {
2005   PetscErrorCode ierr;
2006 
2007   PetscFunctionBegin;
2008   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2009   PetscValidType(mat,1);
2010   PetscValidScalarPointer(rows,4);
2011   PetscValidScalarPointer(v,5);
2012 #if defined(PETSC_USE_DEBUG)
2013   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2014 #endif
2015 
2016   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2017   if (mat->ops->setvaluesbatch) {
2018     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2019   } else {
2020     PetscInt b;
2021     for (b = 0; b < nb; ++b) {
2022       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2023     }
2024   }
2025   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2026   PetscFunctionReturn(0);
2027 }
2028 
2029 /*@
2030    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2031    the routine MatSetValuesLocal() to allow users to insert matrix entries
2032    using a local (per-processor) numbering.
2033 
2034    Not Collective
2035 
2036    Input Parameters:
2037 +  x - the matrix
2038 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2039 - cmapping - column mapping
2040 
2041    Level: intermediate
2042 
2043    Concepts: matrices^local to global mapping
2044    Concepts: local to global mapping^for matrices
2045 
2046 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2047 @*/
2048 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2049 {
2050   PetscErrorCode ierr;
2051 
2052   PetscFunctionBegin;
2053   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2054   PetscValidType(x,1);
2055   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2056   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2057 
2058   if (x->ops->setlocaltoglobalmapping) {
2059     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2060   } else {
2061     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2062     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2063   }
2064   PetscFunctionReturn(0);
2065 }
2066 
2067 
2068 /*@
2069    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2070 
2071    Not Collective
2072 
2073    Input Parameters:
2074 .  A - the matrix
2075 
2076    Output Parameters:
2077 + rmapping - row mapping
2078 - cmapping - column mapping
2079 
2080    Level: advanced
2081 
2082    Concepts: matrices^local to global mapping
2083    Concepts: local to global mapping^for matrices
2084 
2085 .seealso:  MatSetValuesLocal()
2086 @*/
2087 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2088 {
2089   PetscFunctionBegin;
2090   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2091   PetscValidType(A,1);
2092   if (rmapping) PetscValidPointer(rmapping,2);
2093   if (cmapping) PetscValidPointer(cmapping,3);
2094   if (rmapping) *rmapping = A->rmap->mapping;
2095   if (cmapping) *cmapping = A->cmap->mapping;
2096   PetscFunctionReturn(0);
2097 }
2098 
2099 /*@
2100    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2101 
2102    Not Collective
2103 
2104    Input Parameters:
2105 .  A - the matrix
2106 
2107    Output Parameters:
2108 + rmap - row layout
2109 - cmap - column layout
2110 
2111    Level: advanced
2112 
2113 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2114 @*/
2115 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2116 {
2117   PetscFunctionBegin;
2118   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2119   PetscValidType(A,1);
2120   if (rmap) PetscValidPointer(rmap,2);
2121   if (cmap) PetscValidPointer(cmap,3);
2122   if (rmap) *rmap = A->rmap;
2123   if (cmap) *cmap = A->cmap;
2124   PetscFunctionReturn(0);
2125 }
2126 
2127 /*@C
2128    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2129    using a local ordering of the nodes.
2130 
2131    Not Collective
2132 
2133    Input Parameters:
2134 +  mat - the matrix
2135 .  nrow, irow - number of rows and their local indices
2136 .  ncol, icol - number of columns and their local indices
2137 .  y -  a logically two-dimensional array of values
2138 -  addv - either INSERT_VALUES or ADD_VALUES, where
2139    ADD_VALUES adds values to any existing entries, and
2140    INSERT_VALUES replaces existing entries with new values
2141 
2142    Notes:
2143    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2144       MatSetUp() before using this routine
2145 
2146    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2147 
2148    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2149    options cannot be mixed without intervening calls to the assembly
2150    routines.
2151 
2152    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2153    MUST be called after all calls to MatSetValuesLocal() have been completed.
2154 
2155    Level: intermediate
2156 
2157    Concepts: matrices^putting entries in with local numbering
2158 
2159    Developer Notes:
2160     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2161                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2162 
2163 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2164            MatSetValueLocal()
2165 @*/
2166 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2167 {
2168   PetscErrorCode ierr;
2169 
2170   PetscFunctionBeginHot;
2171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2172   PetscValidType(mat,1);
2173   MatCheckPreallocated(mat,1);
2174   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2175   PetscValidIntPointer(irow,3);
2176   PetscValidIntPointer(icol,5);
2177   PetscValidScalarPointer(y,6);
2178   if (mat->insertmode == NOT_SET_VALUES) {
2179     mat->insertmode = addv;
2180   }
2181 #if defined(PETSC_USE_DEBUG)
2182   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2183   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2184   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2185 #endif
2186 
2187   if (mat->assembled) {
2188     mat->was_assembled = PETSC_TRUE;
2189     mat->assembled     = PETSC_FALSE;
2190   }
2191   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2192   if (mat->ops->setvalueslocal) {
2193     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2194   } else {
2195     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2196     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2197       irowm = buf; icolm = buf+nrow;
2198     } else {
2199       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2200       irowm = bufr; icolm = bufc;
2201     }
2202     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2203     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2204     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2205     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2206   }
2207   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2208 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2209   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2210     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2211   }
2212 #endif
2213   PetscFunctionReturn(0);
2214 }
2215 
2216 /*@C
2217    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2218    using a local ordering of the nodes a block at a time.
2219 
2220    Not Collective
2221 
2222    Input Parameters:
2223 +  x - the matrix
2224 .  nrow, irow - number of rows and their local indices
2225 .  ncol, icol - number of columns and their local indices
2226 .  y -  a logically two-dimensional array of values
2227 -  addv - either INSERT_VALUES or ADD_VALUES, where
2228    ADD_VALUES adds values to any existing entries, and
2229    INSERT_VALUES replaces existing entries with new values
2230 
2231    Notes:
2232    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2233       MatSetUp() before using this routine
2234 
2235    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2236       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2237 
2238    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2239    options cannot be mixed without intervening calls to the assembly
2240    routines.
2241 
2242    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2243    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2244 
2245    Level: intermediate
2246 
2247    Developer Notes:
2248     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2249                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2250 
2251    Concepts: matrices^putting blocked values in with local numbering
2252 
2253 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2254            MatSetValuesLocal(),  MatSetValuesBlocked()
2255 @*/
2256 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2257 {
2258   PetscErrorCode ierr;
2259 
2260   PetscFunctionBeginHot;
2261   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2262   PetscValidType(mat,1);
2263   MatCheckPreallocated(mat,1);
2264   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2265   PetscValidIntPointer(irow,3);
2266   PetscValidIntPointer(icol,5);
2267   PetscValidScalarPointer(y,6);
2268   if (mat->insertmode == NOT_SET_VALUES) {
2269     mat->insertmode = addv;
2270   }
2271 #if defined(PETSC_USE_DEBUG)
2272   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2273   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2274   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2275 #endif
2276 
2277   if (mat->assembled) {
2278     mat->was_assembled = PETSC_TRUE;
2279     mat->assembled     = PETSC_FALSE;
2280   }
2281   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2282   if (mat->ops->setvaluesblockedlocal) {
2283     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2284   } else {
2285     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2286     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2287       irowm = buf; icolm = buf + nrow;
2288     } else {
2289       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2290       irowm = bufr; icolm = bufc;
2291     }
2292     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2293     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2294     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2295     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2296   }
2297   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2298 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2299   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2300     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2301   }
2302 #endif
2303   PetscFunctionReturn(0);
2304 }
2305 
2306 /*@
2307    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2308 
2309    Collective on Mat and Vec
2310 
2311    Input Parameters:
2312 +  mat - the matrix
2313 -  x   - the vector to be multiplied
2314 
2315    Output Parameters:
2316 .  y - the result
2317 
2318    Notes:
2319    The vectors x and y cannot be the same.  I.e., one cannot
2320    call MatMult(A,y,y).
2321 
2322    Level: developer
2323 
2324    Concepts: matrix-vector product
2325 
2326 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2327 @*/
2328 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2329 {
2330   PetscErrorCode ierr;
2331 
2332   PetscFunctionBegin;
2333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2334   PetscValidType(mat,1);
2335   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2336   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2337 
2338   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2339   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2340   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2341   MatCheckPreallocated(mat,1);
2342 
2343   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2344   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2345   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2346   PetscFunctionReturn(0);
2347 }
2348 
2349 /* --------------------------------------------------------*/
2350 /*@
2351    MatMult - Computes the matrix-vector product, y = Ax.
2352 
2353    Neighbor-wise Collective on Mat and Vec
2354 
2355    Input Parameters:
2356 +  mat - the matrix
2357 -  x   - the vector to be multiplied
2358 
2359    Output Parameters:
2360 .  y - the result
2361 
2362    Notes:
2363    The vectors x and y cannot be the same.  I.e., one cannot
2364    call MatMult(A,y,y).
2365 
2366    Level: beginner
2367 
2368    Concepts: matrix-vector product
2369 
2370 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2371 @*/
2372 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2373 {
2374   PetscErrorCode ierr;
2375 
2376   PetscFunctionBegin;
2377   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2378   PetscValidType(mat,1);
2379   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2380   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2381   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2382   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2383   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2384 #if !defined(PETSC_HAVE_CONSTRAINTS)
2385   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);
2386   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);
2387   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);
2388 #endif
2389   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2390   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2391   MatCheckPreallocated(mat,1);
2392 
2393   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2394   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2395   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2396   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2397   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2398   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2399   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2400   PetscFunctionReturn(0);
2401 }
2402 
2403 /*@
2404    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2405 
2406    Neighbor-wise Collective on Mat and Vec
2407 
2408    Input Parameters:
2409 +  mat - the matrix
2410 -  x   - the vector to be multiplied
2411 
2412    Output Parameters:
2413 .  y - the result
2414 
2415    Notes:
2416    The vectors x and y cannot be the same.  I.e., one cannot
2417    call MatMultTranspose(A,y,y).
2418 
2419    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2420    use MatMultHermitianTranspose()
2421 
2422    Level: beginner
2423 
2424    Concepts: matrix vector product^transpose
2425 
2426 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2427 @*/
2428 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2429 {
2430   PetscErrorCode ierr;
2431 
2432   PetscFunctionBegin;
2433   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2434   PetscValidType(mat,1);
2435   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2436   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2437 
2438   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2439   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2440   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2441 #if !defined(PETSC_HAVE_CONSTRAINTS)
2442   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);
2443   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);
2444 #endif
2445   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2446   MatCheckPreallocated(mat,1);
2447 
2448   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2449   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2450   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2451   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2452   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2453   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2454   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2455   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2456   PetscFunctionReturn(0);
2457 }
2458 
2459 /*@
2460    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2461 
2462    Neighbor-wise Collective on Mat and Vec
2463 
2464    Input Parameters:
2465 +  mat - the matrix
2466 -  x   - the vector to be multilplied
2467 
2468    Output Parameters:
2469 .  y - the result
2470 
2471    Notes:
2472    The vectors x and y cannot be the same.  I.e., one cannot
2473    call MatMultHermitianTranspose(A,y,y).
2474 
2475    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2476 
2477    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2478 
2479    Level: beginner
2480 
2481    Concepts: matrix vector product^transpose
2482 
2483 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2484 @*/
2485 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2486 {
2487   PetscErrorCode ierr;
2488   Vec            w;
2489 
2490   PetscFunctionBegin;
2491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2492   PetscValidType(mat,1);
2493   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2494   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2495 
2496   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2497   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2498   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2499 #if !defined(PETSC_HAVE_CONSTRAINTS)
2500   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);
2501   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);
2502 #endif
2503   MatCheckPreallocated(mat,1);
2504 
2505   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2506   if (mat->ops->multhermitiantranspose) {
2507     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2508     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2509     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2510   } else {
2511     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2512     ierr = VecCopy(x,w);CHKERRQ(ierr);
2513     ierr = VecConjugate(w);CHKERRQ(ierr);
2514     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2515     ierr = VecDestroy(&w);CHKERRQ(ierr);
2516     ierr = VecConjugate(y);CHKERRQ(ierr);
2517   }
2518   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2519   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2520   PetscFunctionReturn(0);
2521 }
2522 
2523 /*@
2524     MatMultAdd -  Computes v3 = v2 + A * v1.
2525 
2526     Neighbor-wise Collective on Mat and Vec
2527 
2528     Input Parameters:
2529 +   mat - the matrix
2530 -   v1, v2 - the vectors
2531 
2532     Output Parameters:
2533 .   v3 - the result
2534 
2535     Notes:
2536     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2537     call MatMultAdd(A,v1,v2,v1).
2538 
2539     Level: beginner
2540 
2541     Concepts: matrix vector product^addition
2542 
2543 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2544 @*/
2545 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2546 {
2547   PetscErrorCode ierr;
2548 
2549   PetscFunctionBegin;
2550   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2551   PetscValidType(mat,1);
2552   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2553   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2554   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2555 
2556   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2557   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2558   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);
2559   /* 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);
2560      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); */
2561   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);
2562   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);
2563   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2564   MatCheckPreallocated(mat,1);
2565 
2566   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2567   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2568   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2569   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2570   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2571   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2572   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2573   PetscFunctionReturn(0);
2574 }
2575 
2576 /*@
2577    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2578 
2579    Neighbor-wise Collective on Mat and Vec
2580 
2581    Input Parameters:
2582 +  mat - the matrix
2583 -  v1, v2 - the vectors
2584 
2585    Output Parameters:
2586 .  v3 - the result
2587 
2588    Notes:
2589    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2590    call MatMultTransposeAdd(A,v1,v2,v1).
2591 
2592    Level: beginner
2593 
2594    Concepts: matrix vector product^transpose and addition
2595 
2596 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2597 @*/
2598 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2599 {
2600   PetscErrorCode ierr;
2601 
2602   PetscFunctionBegin;
2603   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2604   PetscValidType(mat,1);
2605   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2606   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2607   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2608 
2609   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2610   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2611   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2612   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2613   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);
2614   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);
2615   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);
2616   MatCheckPreallocated(mat,1);
2617 
2618   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2619   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2620   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2621   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2622   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2623   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2624   PetscFunctionReturn(0);
2625 }
2626 
2627 /*@
2628    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2629 
2630    Neighbor-wise Collective on Mat and Vec
2631 
2632    Input Parameters:
2633 +  mat - the matrix
2634 -  v1, v2 - the vectors
2635 
2636    Output Parameters:
2637 .  v3 - the result
2638 
2639    Notes:
2640    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2641    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2642 
2643    Level: beginner
2644 
2645    Concepts: matrix vector product^transpose and addition
2646 
2647 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2648 @*/
2649 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2650 {
2651   PetscErrorCode ierr;
2652 
2653   PetscFunctionBegin;
2654   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2655   PetscValidType(mat,1);
2656   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2657   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2658   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2659 
2660   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2661   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2662   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2663   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);
2664   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);
2665   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);
2666   MatCheckPreallocated(mat,1);
2667 
2668   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2669   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2670   if (mat->ops->multhermitiantransposeadd) {
2671     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2672   } else {
2673     Vec w,z;
2674     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2675     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2676     ierr = VecConjugate(w);CHKERRQ(ierr);
2677     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2678     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2679     ierr = VecDestroy(&w);CHKERRQ(ierr);
2680     ierr = VecConjugate(z);CHKERRQ(ierr);
2681     if (v2 != v3) {
2682       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2683     } else {
2684       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2685     }
2686     ierr = VecDestroy(&z);CHKERRQ(ierr);
2687   }
2688   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2689   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2690   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2691   PetscFunctionReturn(0);
2692 }
2693 
2694 /*@
2695    MatMultConstrained - The inner multiplication routine for a
2696    constrained matrix P^T A P.
2697 
2698    Neighbor-wise Collective on Mat and Vec
2699 
2700    Input Parameters:
2701 +  mat - the matrix
2702 -  x   - the vector to be multilplied
2703 
2704    Output Parameters:
2705 .  y - the result
2706 
2707    Notes:
2708    The vectors x and y cannot be the same.  I.e., one cannot
2709    call MatMult(A,y,y).
2710 
2711    Level: beginner
2712 
2713 .keywords: matrix, multiply, matrix-vector product, constraint
2714 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2715 @*/
2716 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2717 {
2718   PetscErrorCode ierr;
2719 
2720   PetscFunctionBegin;
2721   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2722   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2723   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2724   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2725   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2726   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2727   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);
2728   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);
2729   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);
2730 
2731   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2732   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2733   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2734   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2735   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2736   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2737   PetscFunctionReturn(0);
2738 }
2739 
2740 /*@
2741    MatMultTransposeConstrained - The inner multiplication routine for a
2742    constrained matrix P^T A^T P.
2743 
2744    Neighbor-wise Collective on Mat and Vec
2745 
2746    Input Parameters:
2747 +  mat - the matrix
2748 -  x   - the vector to be multilplied
2749 
2750    Output Parameters:
2751 .  y - the result
2752 
2753    Notes:
2754    The vectors x and y cannot be the same.  I.e., one cannot
2755    call MatMult(A,y,y).
2756 
2757    Level: beginner
2758 
2759 .keywords: matrix, multiply, matrix-vector product, constraint
2760 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2761 @*/
2762 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2763 {
2764   PetscErrorCode ierr;
2765 
2766   PetscFunctionBegin;
2767   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2768   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2769   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2770   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2771   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2772   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2773   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);
2774   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);
2775 
2776   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2777   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2778   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2779   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2780   PetscFunctionReturn(0);
2781 }
2782 
2783 /*@C
2784    MatGetFactorType - gets the type of factorization it is
2785 
2786    Not Collective
2787 
2788    Input Parameters:
2789 .  mat - the matrix
2790 
2791    Output Parameters:
2792 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2793 
2794    Level: intermediate
2795 
2796 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2797 @*/
2798 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2799 {
2800   PetscFunctionBegin;
2801   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2802   PetscValidType(mat,1);
2803   PetscValidPointer(t,2);
2804   *t = mat->factortype;
2805   PetscFunctionReturn(0);
2806 }
2807 
2808 /*@C
2809    MatSetFactorType - sets the type of factorization it is
2810 
2811    Logically Collective on Mat
2812 
2813    Input Parameters:
2814 +  mat - the matrix
2815 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2816 
2817    Level: intermediate
2818 
2819 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2820 @*/
2821 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2822 {
2823   PetscFunctionBegin;
2824   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2825   PetscValidType(mat,1);
2826   mat->factortype = t;
2827   PetscFunctionReturn(0);
2828 }
2829 
2830 /* ------------------------------------------------------------*/
2831 /*@C
2832    MatGetInfo - Returns information about matrix storage (number of
2833    nonzeros, memory, etc.).
2834 
2835    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2836 
2837    Input Parameters:
2838 .  mat - the matrix
2839 
2840    Output Parameters:
2841 +  flag - flag indicating the type of parameters to be returned
2842    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2843    MAT_GLOBAL_SUM - sum over all processors)
2844 -  info - matrix information context
2845 
2846    Notes:
2847    The MatInfo context contains a variety of matrix data, including
2848    number of nonzeros allocated and used, number of mallocs during
2849    matrix assembly, etc.  Additional information for factored matrices
2850    is provided (such as the fill ratio, number of mallocs during
2851    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2852    when using the runtime options
2853 $       -info -mat_view ::ascii_info
2854 
2855    Example for C/C++ Users:
2856    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2857    data within the MatInfo context.  For example,
2858 .vb
2859       MatInfo info;
2860       Mat     A;
2861       double  mal, nz_a, nz_u;
2862 
2863       MatGetInfo(A,MAT_LOCAL,&info);
2864       mal  = info.mallocs;
2865       nz_a = info.nz_allocated;
2866 .ve
2867 
2868    Example for Fortran Users:
2869    Fortran users should declare info as a double precision
2870    array of dimension MAT_INFO_SIZE, and then extract the parameters
2871    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2872    a complete list of parameter names.
2873 .vb
2874       double  precision info(MAT_INFO_SIZE)
2875       double  precision mal, nz_a
2876       Mat     A
2877       integer ierr
2878 
2879       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2880       mal = info(MAT_INFO_MALLOCS)
2881       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2882 .ve
2883 
2884     Level: intermediate
2885 
2886     Concepts: matrices^getting information on
2887 
2888     Developer Note: fortran interface is not autogenerated as the f90
2889     interface defintion cannot be generated correctly [due to MatInfo]
2890 
2891 .seealso: MatStashGetInfo()
2892 
2893 @*/
2894 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2895 {
2896   PetscErrorCode ierr;
2897 
2898   PetscFunctionBegin;
2899   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2900   PetscValidType(mat,1);
2901   PetscValidPointer(info,3);
2902   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2903   MatCheckPreallocated(mat,1);
2904   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2905   PetscFunctionReturn(0);
2906 }
2907 
2908 /*
2909    This is used by external packages where it is not easy to get the info from the actual
2910    matrix factorization.
2911 */
2912 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2913 {
2914   PetscErrorCode ierr;
2915 
2916   PetscFunctionBegin;
2917   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2918   PetscFunctionReturn(0);
2919 }
2920 
2921 /* ----------------------------------------------------------*/
2922 
2923 /*@C
2924    MatLUFactor - Performs in-place LU factorization of matrix.
2925 
2926    Collective on Mat
2927 
2928    Input Parameters:
2929 +  mat - the matrix
2930 .  row - row permutation
2931 .  col - column permutation
2932 -  info - options for factorization, includes
2933 $          fill - expected fill as ratio of original fill.
2934 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2935 $                   Run with the option -info to determine an optimal value to use
2936 
2937    Notes:
2938    Most users should employ the simplified KSP interface for linear solvers
2939    instead of working directly with matrix algebra routines such as this.
2940    See, e.g., KSPCreate().
2941 
2942    This changes the state of the matrix to a factored matrix; it cannot be used
2943    for example with MatSetValues() unless one first calls MatSetUnfactored().
2944 
2945    Level: developer
2946 
2947    Concepts: matrices^LU factorization
2948 
2949 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2950           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2951 
2952     Developer Note: fortran interface is not autogenerated as the f90
2953     interface defintion cannot be generated correctly [due to MatFactorInfo]
2954 
2955 @*/
2956 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2957 {
2958   PetscErrorCode ierr;
2959   MatFactorInfo  tinfo;
2960 
2961   PetscFunctionBegin;
2962   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2963   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2964   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2965   if (info) PetscValidPointer(info,4);
2966   PetscValidType(mat,1);
2967   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2968   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2969   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2970   MatCheckPreallocated(mat,1);
2971   if (!info) {
2972     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2973     info = &tinfo;
2974   }
2975 
2976   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2977   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2978   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2979   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2980   PetscFunctionReturn(0);
2981 }
2982 
2983 /*@C
2984    MatILUFactor - Performs in-place ILU factorization of matrix.
2985 
2986    Collective on Mat
2987 
2988    Input Parameters:
2989 +  mat - the matrix
2990 .  row - row permutation
2991 .  col - column permutation
2992 -  info - structure containing
2993 $      levels - number of levels of fill.
2994 $      expected fill - as ratio of original fill.
2995 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2996                 missing diagonal entries)
2997 
2998    Notes:
2999    Probably really in-place only when level of fill is zero, otherwise allocates
3000    new space to store factored matrix and deletes previous memory.
3001 
3002    Most users should employ the simplified KSP interface for linear solvers
3003    instead of working directly with matrix algebra routines such as this.
3004    See, e.g., KSPCreate().
3005 
3006    Level: developer
3007 
3008    Concepts: matrices^ILU factorization
3009 
3010 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3011 
3012     Developer Note: fortran interface is not autogenerated as the f90
3013     interface defintion cannot be generated correctly [due to MatFactorInfo]
3014 
3015 @*/
3016 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3017 {
3018   PetscErrorCode ierr;
3019 
3020   PetscFunctionBegin;
3021   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3022   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3023   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3024   PetscValidPointer(info,4);
3025   PetscValidType(mat,1);
3026   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3027   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3028   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3029   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3030   MatCheckPreallocated(mat,1);
3031 
3032   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3033   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3034   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3035   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3036   PetscFunctionReturn(0);
3037 }
3038 
3039 /*@C
3040    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3041    Call this routine before calling MatLUFactorNumeric().
3042 
3043    Collective on Mat
3044 
3045    Input Parameters:
3046 +  fact - the factor matrix obtained with MatGetFactor()
3047 .  mat - the matrix
3048 .  row, col - row and column permutations
3049 -  info - options for factorization, includes
3050 $          fill - expected fill as ratio of original fill.
3051 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3052 $                   Run with the option -info to determine an optimal value to use
3053 
3054 
3055    Notes:
3056     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3057 
3058    Most users should employ the simplified KSP interface for linear solvers
3059    instead of working directly with matrix algebra routines such as this.
3060    See, e.g., KSPCreate().
3061 
3062    Level: developer
3063 
3064    Concepts: matrices^LU symbolic factorization
3065 
3066 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3067 
3068     Developer Note: fortran interface is not autogenerated as the f90
3069     interface defintion cannot be generated correctly [due to MatFactorInfo]
3070 
3071 @*/
3072 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3073 {
3074   PetscErrorCode ierr;
3075 
3076   PetscFunctionBegin;
3077   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3078   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3079   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3080   if (info) PetscValidPointer(info,4);
3081   PetscValidType(mat,1);
3082   PetscValidPointer(fact,5);
3083   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3084   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3085   if (!(fact)->ops->lufactorsymbolic) {
3086     MatSolverType spackage;
3087     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3088     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3089   }
3090   MatCheckPreallocated(mat,2);
3091 
3092   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3093   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3094   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3095   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3096   PetscFunctionReturn(0);
3097 }
3098 
3099 /*@C
3100    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3101    Call this routine after first calling MatLUFactorSymbolic().
3102 
3103    Collective on Mat
3104 
3105    Input Parameters:
3106 +  fact - the factor matrix obtained with MatGetFactor()
3107 .  mat - the matrix
3108 -  info - options for factorization
3109 
3110    Notes:
3111    See MatLUFactor() for in-place factorization.  See
3112    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3113 
3114    Most users should employ the simplified KSP interface for linear solvers
3115    instead of working directly with matrix algebra routines such as this.
3116    See, e.g., KSPCreate().
3117 
3118    Level: developer
3119 
3120    Concepts: matrices^LU numeric factorization
3121 
3122 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3123 
3124     Developer Note: fortran interface is not autogenerated as the f90
3125     interface defintion cannot be generated correctly [due to MatFactorInfo]
3126 
3127 @*/
3128 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3129 {
3130   PetscErrorCode ierr;
3131 
3132   PetscFunctionBegin;
3133   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3134   PetscValidType(mat,1);
3135   PetscValidPointer(fact,2);
3136   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3137   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3138   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);
3139 
3140   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3141   MatCheckPreallocated(mat,2);
3142   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3143   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3144   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3145   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3146   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3147   PetscFunctionReturn(0);
3148 }
3149 
3150 /*@C
3151    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3152    symmetric matrix.
3153 
3154    Collective on Mat
3155 
3156    Input Parameters:
3157 +  mat - the matrix
3158 .  perm - row and column permutations
3159 -  f - expected fill as ratio of original fill
3160 
3161    Notes:
3162    See MatLUFactor() for the nonsymmetric case.  See also
3163    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3164 
3165    Most users should employ the simplified KSP interface for linear solvers
3166    instead of working directly with matrix algebra routines such as this.
3167    See, e.g., KSPCreate().
3168 
3169    Level: developer
3170 
3171    Concepts: matrices^Cholesky factorization
3172 
3173 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3174           MatGetOrdering()
3175 
3176     Developer Note: fortran interface is not autogenerated as the f90
3177     interface defintion cannot be generated correctly [due to MatFactorInfo]
3178 
3179 @*/
3180 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3181 {
3182   PetscErrorCode ierr;
3183 
3184   PetscFunctionBegin;
3185   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3186   PetscValidType(mat,1);
3187   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3188   if (info) PetscValidPointer(info,3);
3189   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3190   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3191   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3192   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);
3193   MatCheckPreallocated(mat,1);
3194 
3195   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3196   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3197   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3198   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3199   PetscFunctionReturn(0);
3200 }
3201 
3202 /*@C
3203    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3204    of a symmetric matrix.
3205 
3206    Collective on Mat
3207 
3208    Input Parameters:
3209 +  fact - the factor matrix obtained with MatGetFactor()
3210 .  mat - the matrix
3211 .  perm - row and column permutations
3212 -  info - options for factorization, includes
3213 $          fill - expected fill as ratio of original fill.
3214 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3215 $                   Run with the option -info to determine an optimal value to use
3216 
3217    Notes:
3218    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3219    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3220 
3221    Most users should employ the simplified KSP interface for linear solvers
3222    instead of working directly with matrix algebra routines such as this.
3223    See, e.g., KSPCreate().
3224 
3225    Level: developer
3226 
3227    Concepts: matrices^Cholesky symbolic factorization
3228 
3229 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3230           MatGetOrdering()
3231 
3232     Developer Note: fortran interface is not autogenerated as the f90
3233     interface defintion cannot be generated correctly [due to MatFactorInfo]
3234 
3235 @*/
3236 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3237 {
3238   PetscErrorCode ierr;
3239 
3240   PetscFunctionBegin;
3241   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3242   PetscValidType(mat,1);
3243   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3244   if (info) PetscValidPointer(info,3);
3245   PetscValidPointer(fact,4);
3246   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3247   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3248   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3249   if (!(fact)->ops->choleskyfactorsymbolic) {
3250     MatSolverType spackage;
3251     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3252     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3253   }
3254   MatCheckPreallocated(mat,2);
3255 
3256   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3257   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3258   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3259   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3260   PetscFunctionReturn(0);
3261 }
3262 
3263 /*@C
3264    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3265    of a symmetric matrix. Call this routine after first calling
3266    MatCholeskyFactorSymbolic().
3267 
3268    Collective on Mat
3269 
3270    Input Parameters:
3271 +  fact - the factor matrix obtained with MatGetFactor()
3272 .  mat - the initial matrix
3273 .  info - options for factorization
3274 -  fact - the symbolic factor of mat
3275 
3276 
3277    Notes:
3278    Most users should employ the simplified KSP interface for linear solvers
3279    instead of working directly with matrix algebra routines such as this.
3280    See, e.g., KSPCreate().
3281 
3282    Level: developer
3283 
3284    Concepts: matrices^Cholesky numeric factorization
3285 
3286 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3287 
3288     Developer Note: fortran interface is not autogenerated as the f90
3289     interface defintion cannot be generated correctly [due to MatFactorInfo]
3290 
3291 @*/
3292 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3293 {
3294   PetscErrorCode ierr;
3295 
3296   PetscFunctionBegin;
3297   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3298   PetscValidType(mat,1);
3299   PetscValidPointer(fact,2);
3300   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3301   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3302   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3303   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);
3304   MatCheckPreallocated(mat,2);
3305 
3306   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3307   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3308   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3309   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3310   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3311   PetscFunctionReturn(0);
3312 }
3313 
3314 /* ----------------------------------------------------------------*/
3315 /*@
3316    MatSolve - Solves A x = b, given a factored matrix.
3317 
3318    Neighbor-wise Collective on Mat and Vec
3319 
3320    Input Parameters:
3321 +  mat - the factored matrix
3322 -  b - the right-hand-side vector
3323 
3324    Output Parameter:
3325 .  x - the result vector
3326 
3327    Notes:
3328    The vectors b and x cannot be the same.  I.e., one cannot
3329    call MatSolve(A,x,x).
3330 
3331    Notes:
3332    Most users should employ the simplified KSP interface for linear solvers
3333    instead of working directly with matrix algebra routines such as this.
3334    See, e.g., KSPCreate().
3335 
3336    Level: developer
3337 
3338    Concepts: matrices^triangular solves
3339 
3340 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3341 @*/
3342 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3343 {
3344   PetscErrorCode ierr;
3345 
3346   PetscFunctionBegin;
3347   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3348   PetscValidType(mat,1);
3349   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3350   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3351   PetscCheckSameComm(mat,1,b,2);
3352   PetscCheckSameComm(mat,1,x,3);
3353   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3354   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);
3355   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);
3356   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);
3357   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3358   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3359   MatCheckPreallocated(mat,1);
3360 
3361   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3362   if (mat->factorerrortype) {
3363     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3364     ierr = VecSetInf(x);CHKERRQ(ierr);
3365   } else {
3366     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3367     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3368   }
3369   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3370   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3371   PetscFunctionReturn(0);
3372 }
3373 
3374 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3375 {
3376   PetscErrorCode ierr;
3377   Vec            b,x;
3378   PetscInt       m,N,i;
3379   PetscScalar    *bb,*xx;
3380   PetscBool      flg;
3381 
3382   PetscFunctionBegin;
3383   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3384   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3385   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3386   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3387 
3388   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3389   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3390   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3391   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3392   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3393   for (i=0; i<N; i++) {
3394     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3395     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3396     if (trans) {
3397       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3398     } else {
3399       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3400     }
3401     ierr = VecResetArray(x);CHKERRQ(ierr);
3402     ierr = VecResetArray(b);CHKERRQ(ierr);
3403   }
3404   ierr = VecDestroy(&b);CHKERRQ(ierr);
3405   ierr = VecDestroy(&x);CHKERRQ(ierr);
3406   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3407   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3408   PetscFunctionReturn(0);
3409 }
3410 
3411 /*@
3412    MatMatSolve - Solves A X = B, given a factored matrix.
3413 
3414    Neighbor-wise Collective on Mat
3415 
3416    Input Parameters:
3417 +  A - the factored matrix
3418 -  B - the right-hand-side matrix  (dense matrix)
3419 
3420    Output Parameter:
3421 .  X - the result matrix (dense matrix)
3422 
3423    Notes:
3424    The matrices b and x cannot be the same.  I.e., one cannot
3425    call MatMatSolve(A,x,x).
3426 
3427    Notes:
3428    Most users should usually employ the simplified KSP interface for linear solvers
3429    instead of working directly with matrix algebra routines such as this.
3430    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3431    at a time.
3432 
3433    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3434    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3435 
3436    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3437 
3438    Level: developer
3439 
3440    Concepts: matrices^triangular solves
3441 
3442 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3443 @*/
3444 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3445 {
3446   PetscErrorCode ierr;
3447 
3448   PetscFunctionBegin;
3449   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3450   PetscValidType(A,1);
3451   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3452   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3453   PetscCheckSameComm(A,1,B,2);
3454   PetscCheckSameComm(A,1,X,3);
3455   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3456   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);
3457   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);
3458   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");
3459   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3460   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3461   MatCheckPreallocated(A,1);
3462 
3463   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3464   if (!A->ops->matsolve) {
3465     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3466     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3467   } else {
3468     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3469   }
3470   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3471   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3472   PetscFunctionReturn(0);
3473 }
3474 
3475 /*@
3476    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3477 
3478    Neighbor-wise Collective on Mat
3479 
3480    Input Parameters:
3481 +  A - the factored matrix
3482 -  B - the right-hand-side matrix  (dense matrix)
3483 
3484    Output Parameter:
3485 .  X - the result matrix (dense matrix)
3486 
3487    Notes:
3488    The matrices B and X cannot be the same.  I.e., one cannot
3489    call MatMatSolveTranspose(A,X,X).
3490 
3491    Notes:
3492    Most users should usually employ the simplified KSP interface for linear solvers
3493    instead of working directly with matrix algebra routines such as this.
3494    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3495    at a time.
3496 
3497    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3498 
3499    Level: developer
3500 
3501    Concepts: matrices^triangular solves
3502 
3503 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3504 @*/
3505 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3506 {
3507   PetscErrorCode ierr;
3508 
3509   PetscFunctionBegin;
3510   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3511   PetscValidType(A,1);
3512   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3513   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3514   PetscCheckSameComm(A,1,B,2);
3515   PetscCheckSameComm(A,1,X,3);
3516   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3517   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);
3518   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);
3519   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);
3520   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");
3521   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3522   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3523   MatCheckPreallocated(A,1);
3524 
3525   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3526   if (!A->ops->matsolvetranspose) {
3527     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3528     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3529   } else {
3530     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3531   }
3532   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3533   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3534   PetscFunctionReturn(0);
3535 }
3536 
3537 /*@
3538    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3539 
3540    Neighbor-wise Collective on Mat
3541 
3542    Input Parameters:
3543 +  A - the factored matrix
3544 -  Bt - the transpose of right-hand-side matrix
3545 
3546    Output Parameter:
3547 .  X - the result matrix (dense matrix)
3548 
3549    Notes:
3550    Most users should usually employ the simplified KSP interface for linear solvers
3551    instead of working directly with matrix algebra routines such as this.
3552    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3553    at a time.
3554 
3555    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().
3556 
3557    Level: developer
3558 
3559    Concepts: matrices^triangular solves
3560 
3561 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3562 @*/
3563 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3564 {
3565   PetscErrorCode ierr;
3566 
3567   PetscFunctionBegin;
3568   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3569   PetscValidType(A,1);
3570   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3571   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3572   PetscCheckSameComm(A,1,Bt,2);
3573   PetscCheckSameComm(A,1,X,3);
3574 
3575   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3576   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);
3577   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);
3578   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");
3579   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3580   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3581   MatCheckPreallocated(A,1);
3582 
3583   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3584   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3585   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3586   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3587   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3588   PetscFunctionReturn(0);
3589 }
3590 
3591 /*@
3592    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3593                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3594 
3595    Neighbor-wise Collective on Mat and Vec
3596 
3597    Input Parameters:
3598 +  mat - the factored matrix
3599 -  b - the right-hand-side vector
3600 
3601    Output Parameter:
3602 .  x - the result vector
3603 
3604    Notes:
3605    MatSolve() should be used for most applications, as it performs
3606    a forward solve followed by a backward solve.
3607 
3608    The vectors b and x cannot be the same,  i.e., one cannot
3609    call MatForwardSolve(A,x,x).
3610 
3611    For matrix in seqsbaij format with block size larger than 1,
3612    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3613    MatForwardSolve() solves U^T*D y = b, and
3614    MatBackwardSolve() solves U x = y.
3615    Thus they do not provide a symmetric preconditioner.
3616 
3617    Most users should employ the simplified KSP interface for linear solvers
3618    instead of working directly with matrix algebra routines such as this.
3619    See, e.g., KSPCreate().
3620 
3621    Level: developer
3622 
3623    Concepts: matrices^forward solves
3624 
3625 .seealso: MatSolve(), MatBackwardSolve()
3626 @*/
3627 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3628 {
3629   PetscErrorCode ierr;
3630 
3631   PetscFunctionBegin;
3632   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3633   PetscValidType(mat,1);
3634   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3635   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3636   PetscCheckSameComm(mat,1,b,2);
3637   PetscCheckSameComm(mat,1,x,3);
3638   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3639   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);
3640   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);
3641   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);
3642   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3643   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3644   MatCheckPreallocated(mat,1);
3645 
3646   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3647   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3648   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3649   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3650   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3651   PetscFunctionReturn(0);
3652 }
3653 
3654 /*@
3655    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3656                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3657 
3658    Neighbor-wise Collective on Mat and Vec
3659 
3660    Input Parameters:
3661 +  mat - the factored matrix
3662 -  b - the right-hand-side vector
3663 
3664    Output Parameter:
3665 .  x - the result vector
3666 
3667    Notes:
3668    MatSolve() should be used for most applications, as it performs
3669    a forward solve followed by a backward solve.
3670 
3671    The vectors b and x cannot be the same.  I.e., one cannot
3672    call MatBackwardSolve(A,x,x).
3673 
3674    For matrix in seqsbaij format with block size larger than 1,
3675    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3676    MatForwardSolve() solves U^T*D y = b, and
3677    MatBackwardSolve() solves U x = y.
3678    Thus they do not provide a symmetric preconditioner.
3679 
3680    Most users should employ the simplified KSP interface for linear solvers
3681    instead of working directly with matrix algebra routines such as this.
3682    See, e.g., KSPCreate().
3683 
3684    Level: developer
3685 
3686    Concepts: matrices^backward solves
3687 
3688 .seealso: MatSolve(), MatForwardSolve()
3689 @*/
3690 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3691 {
3692   PetscErrorCode ierr;
3693 
3694   PetscFunctionBegin;
3695   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3696   PetscValidType(mat,1);
3697   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3698   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3699   PetscCheckSameComm(mat,1,b,2);
3700   PetscCheckSameComm(mat,1,x,3);
3701   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3702   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);
3703   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);
3704   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);
3705   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3706   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3707   MatCheckPreallocated(mat,1);
3708 
3709   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3710   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3711   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3712   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3713   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3714   PetscFunctionReturn(0);
3715 }
3716 
3717 /*@
3718    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3719 
3720    Neighbor-wise Collective on Mat and Vec
3721 
3722    Input Parameters:
3723 +  mat - the factored matrix
3724 .  b - the right-hand-side vector
3725 -  y - the vector to be added to
3726 
3727    Output Parameter:
3728 .  x - the result vector
3729 
3730    Notes:
3731    The vectors b and x cannot be the same.  I.e., one cannot
3732    call MatSolveAdd(A,x,y,x).
3733 
3734    Most users should employ the simplified KSP interface for linear solvers
3735    instead of working directly with matrix algebra routines such as this.
3736    See, e.g., KSPCreate().
3737 
3738    Level: developer
3739 
3740    Concepts: matrices^triangular solves
3741 
3742 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3743 @*/
3744 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3745 {
3746   PetscScalar    one = 1.0;
3747   Vec            tmp;
3748   PetscErrorCode ierr;
3749 
3750   PetscFunctionBegin;
3751   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3752   PetscValidType(mat,1);
3753   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3754   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3755   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3756   PetscCheckSameComm(mat,1,b,2);
3757   PetscCheckSameComm(mat,1,y,2);
3758   PetscCheckSameComm(mat,1,x,3);
3759   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3760   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);
3761   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);
3762   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);
3763   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);
3764   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);
3765   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3766   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3767   MatCheckPreallocated(mat,1);
3768 
3769   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3770   if (mat->ops->solveadd) {
3771     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3772   } else {
3773     /* do the solve then the add manually */
3774     if (x != y) {
3775       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3776       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3777     } else {
3778       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3779       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3780       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3781       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3782       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3783       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3784     }
3785   }
3786   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3787   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3788   PetscFunctionReturn(0);
3789 }
3790 
3791 /*@
3792    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3793 
3794    Neighbor-wise Collective on Mat and Vec
3795 
3796    Input Parameters:
3797 +  mat - the factored matrix
3798 -  b - the right-hand-side vector
3799 
3800    Output Parameter:
3801 .  x - the result vector
3802 
3803    Notes:
3804    The vectors b and x cannot be the same.  I.e., one cannot
3805    call MatSolveTranspose(A,x,x).
3806 
3807    Most users should employ the simplified KSP interface for linear solvers
3808    instead of working directly with matrix algebra routines such as this.
3809    See, e.g., KSPCreate().
3810 
3811    Level: developer
3812 
3813    Concepts: matrices^triangular solves
3814 
3815 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3816 @*/
3817 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3818 {
3819   PetscErrorCode ierr;
3820 
3821   PetscFunctionBegin;
3822   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3823   PetscValidType(mat,1);
3824   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3825   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3826   PetscCheckSameComm(mat,1,b,2);
3827   PetscCheckSameComm(mat,1,x,3);
3828   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3829   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);
3830   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);
3831   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3832   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3833   MatCheckPreallocated(mat,1);
3834   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3835   if (mat->factorerrortype) {
3836     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3837     ierr = VecSetInf(x);CHKERRQ(ierr);
3838   } else {
3839     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3840     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3841   }
3842   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3843   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3844   PetscFunctionReturn(0);
3845 }
3846 
3847 /*@
3848    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3849                       factored matrix.
3850 
3851    Neighbor-wise Collective on Mat and Vec
3852 
3853    Input Parameters:
3854 +  mat - the factored matrix
3855 .  b - the right-hand-side vector
3856 -  y - the vector to be added to
3857 
3858    Output Parameter:
3859 .  x - the result vector
3860 
3861    Notes:
3862    The vectors b and x cannot be the same.  I.e., one cannot
3863    call MatSolveTransposeAdd(A,x,y,x).
3864 
3865    Most users should employ the simplified KSP interface for linear solvers
3866    instead of working directly with matrix algebra routines such as this.
3867    See, e.g., KSPCreate().
3868 
3869    Level: developer
3870 
3871    Concepts: matrices^triangular solves
3872 
3873 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3874 @*/
3875 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3876 {
3877   PetscScalar    one = 1.0;
3878   PetscErrorCode ierr;
3879   Vec            tmp;
3880 
3881   PetscFunctionBegin;
3882   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3883   PetscValidType(mat,1);
3884   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3885   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3886   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3887   PetscCheckSameComm(mat,1,b,2);
3888   PetscCheckSameComm(mat,1,y,3);
3889   PetscCheckSameComm(mat,1,x,4);
3890   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3891   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);
3892   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);
3893   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);
3894   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);
3895   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3896   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3897   MatCheckPreallocated(mat,1);
3898 
3899   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3900   if (mat->ops->solvetransposeadd) {
3901     if (mat->factorerrortype) {
3902       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3903       ierr = VecSetInf(x);CHKERRQ(ierr);
3904     } else {
3905       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3906     }
3907   } else {
3908     /* do the solve then the add manually */
3909     if (x != y) {
3910       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3911       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3912     } else {
3913       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3914       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3915       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3916       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3917       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3918       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3919     }
3920   }
3921   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3922   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3923   PetscFunctionReturn(0);
3924 }
3925 /* ----------------------------------------------------------------*/
3926 
3927 /*@
3928    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3929 
3930    Neighbor-wise Collective on Mat and Vec
3931 
3932    Input Parameters:
3933 +  mat - the matrix
3934 .  b - the right hand side
3935 .  omega - the relaxation factor
3936 .  flag - flag indicating the type of SOR (see below)
3937 .  shift -  diagonal shift
3938 .  its - the number of iterations
3939 -  lits - the number of local iterations
3940 
3941    Output Parameters:
3942 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3943 
3944    SOR Flags:
3945 .     SOR_FORWARD_SWEEP - forward SOR
3946 .     SOR_BACKWARD_SWEEP - backward SOR
3947 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3948 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3949 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3950 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3951 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3952          upper/lower triangular part of matrix to
3953          vector (with omega)
3954 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3955 
3956    Notes:
3957    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3958    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3959    on each processor.
3960 
3961    Application programmers will not generally use MatSOR() directly,
3962    but instead will employ the KSP/PC interface.
3963 
3964    Notes:
3965     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3966 
3967    Notes for Advanced Users:
3968    The flags are implemented as bitwise inclusive or operations.
3969    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3970    to specify a zero initial guess for SSOR.
3971 
3972    Most users should employ the simplified KSP interface for linear solvers
3973    instead of working directly with matrix algebra routines such as this.
3974    See, e.g., KSPCreate().
3975 
3976    Vectors x and b CANNOT be the same
3977 
3978    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3979 
3980    Level: developer
3981 
3982    Concepts: matrices^relaxation
3983    Concepts: matrices^SOR
3984    Concepts: matrices^Gauss-Seidel
3985 
3986 @*/
3987 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3988 {
3989   PetscErrorCode ierr;
3990 
3991   PetscFunctionBegin;
3992   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3993   PetscValidType(mat,1);
3994   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3995   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
3996   PetscCheckSameComm(mat,1,b,2);
3997   PetscCheckSameComm(mat,1,x,8);
3998   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3999   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4000   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4001   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);
4002   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);
4003   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);
4004   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4005   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4006   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4007 
4008   MatCheckPreallocated(mat,1);
4009   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4010   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4011   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4012   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4013   PetscFunctionReturn(0);
4014 }
4015 
4016 /*
4017       Default matrix copy routine.
4018 */
4019 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4020 {
4021   PetscErrorCode    ierr;
4022   PetscInt          i,rstart = 0,rend = 0,nz;
4023   const PetscInt    *cwork;
4024   const PetscScalar *vwork;
4025 
4026   PetscFunctionBegin;
4027   if (B->assembled) {
4028     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4029   }
4030   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4031   for (i=rstart; i<rend; i++) {
4032     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4033     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4034     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4035   }
4036   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4037   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4038   PetscFunctionReturn(0);
4039 }
4040 
4041 /*@
4042    MatCopy - Copys a matrix to another matrix.
4043 
4044    Collective on Mat
4045 
4046    Input Parameters:
4047 +  A - the matrix
4048 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4049 
4050    Output Parameter:
4051 .  B - where the copy is put
4052 
4053    Notes:
4054    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4055    same nonzero pattern or the routine will crash.
4056 
4057    MatCopy() copies the matrix entries of a matrix to another existing
4058    matrix (after first zeroing the second matrix).  A related routine is
4059    MatConvert(), which first creates a new matrix and then copies the data.
4060 
4061    Level: intermediate
4062 
4063    Concepts: matrices^copying
4064 
4065 .seealso: MatConvert(), MatDuplicate()
4066 
4067 @*/
4068 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4069 {
4070   PetscErrorCode ierr;
4071   PetscInt       i;
4072 
4073   PetscFunctionBegin;
4074   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4075   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4076   PetscValidType(A,1);
4077   PetscValidType(B,2);
4078   PetscCheckSameComm(A,1,B,2);
4079   MatCheckPreallocated(B,2);
4080   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4081   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4082   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);
4083   MatCheckPreallocated(A,1);
4084   if (A == B) PetscFunctionReturn(0);
4085 
4086   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4087   if (A->ops->copy) {
4088     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4089   } else { /* generic conversion */
4090     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4091   }
4092 
4093   B->stencil.dim = A->stencil.dim;
4094   B->stencil.noc = A->stencil.noc;
4095   for (i=0; i<=A->stencil.dim; i++) {
4096     B->stencil.dims[i]   = A->stencil.dims[i];
4097     B->stencil.starts[i] = A->stencil.starts[i];
4098   }
4099 
4100   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4101   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4102   PetscFunctionReturn(0);
4103 }
4104 
4105 /*@C
4106    MatConvert - Converts a matrix to another matrix, either of the same
4107    or different type.
4108 
4109    Collective on Mat
4110 
4111    Input Parameters:
4112 +  mat - the matrix
4113 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4114    same type as the original matrix.
4115 -  reuse - denotes if the destination matrix is to be created or reused.
4116    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
4117    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).
4118 
4119    Output Parameter:
4120 .  M - pointer to place new matrix
4121 
4122    Notes:
4123    MatConvert() first creates a new matrix and then copies the data from
4124    the first matrix.  A related routine is MatCopy(), which copies the matrix
4125    entries of one matrix to another already existing matrix context.
4126 
4127    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4128    the MPI communicator of the generated matrix is always the same as the communicator
4129    of the input matrix.
4130 
4131    Level: intermediate
4132 
4133    Concepts: matrices^converting between storage formats
4134 
4135 .seealso: MatCopy(), MatDuplicate()
4136 @*/
4137 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4138 {
4139   PetscErrorCode ierr;
4140   PetscBool      sametype,issame,flg;
4141   char           convname[256],mtype[256];
4142   Mat            B;
4143 
4144   PetscFunctionBegin;
4145   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4146   PetscValidType(mat,1);
4147   PetscValidPointer(M,3);
4148   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4149   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4150   MatCheckPreallocated(mat,1);
4151 
4152   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4153   if (flg) {
4154     newtype = mtype;
4155   }
4156   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4157   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4158   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4159   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");
4160 
4161   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4162 
4163   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4164     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4165   } else {
4166     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4167     const char     *prefix[3] = {"seq","mpi",""};
4168     PetscInt       i;
4169     /*
4170        Order of precedence:
4171        0) See if newtype is a superclass of the current matrix.
4172        1) See if a specialized converter is known to the current matrix.
4173        2) See if a specialized converter is known to the desired matrix class.
4174        3) See if a good general converter is registered for the desired class
4175           (as of 6/27/03 only MATMPIADJ falls into this category).
4176        4) See if a good general converter is known for the current matrix.
4177        5) Use a really basic converter.
4178     */
4179 
4180     /* 0) See if newtype is a superclass of the current matrix.
4181           i.e mat is mpiaij and newtype is aij */
4182     for (i=0; i<2; i++) {
4183       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4184       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4185       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4186       if (flg) {
4187         if (reuse == MAT_INPLACE_MATRIX) {
4188           PetscFunctionReturn(0);
4189         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4190           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4191           PetscFunctionReturn(0);
4192         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4193           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4194           PetscFunctionReturn(0);
4195         }
4196       }
4197     }
4198     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4199     for (i=0; i<3; i++) {
4200       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4201       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4202       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4203       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4204       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4205       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4206       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4207       if (conv) goto foundconv;
4208     }
4209 
4210     /* 2)  See if a specialized converter is known to the desired matrix class. */
4211     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4212     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4213     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4214     for (i=0; i<3; i++) {
4215       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4216       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4217       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4218       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4219       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4220       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4221       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4222       if (conv) {
4223         ierr = MatDestroy(&B);CHKERRQ(ierr);
4224         goto foundconv;
4225       }
4226     }
4227 
4228     /* 3) See if a good general converter is registered for the desired class */
4229     conv = B->ops->convertfrom;
4230     ierr = MatDestroy(&B);CHKERRQ(ierr);
4231     if (conv) goto foundconv;
4232 
4233     /* 4) See if a good general converter is known for the current matrix */
4234     if (mat->ops->convert) {
4235       conv = mat->ops->convert;
4236     }
4237     if (conv) goto foundconv;
4238 
4239     /* 5) Use a really basic converter. */
4240     conv = MatConvert_Basic;
4241 
4242 foundconv:
4243     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4244     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4245     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4246       /* the block sizes must be same if the mappings are copied over */
4247       (*M)->rmap->bs = mat->rmap->bs;
4248       (*M)->cmap->bs = mat->cmap->bs;
4249       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4250       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4251       (*M)->rmap->mapping = mat->rmap->mapping;
4252       (*M)->cmap->mapping = mat->cmap->mapping;
4253     }
4254     (*M)->stencil.dim = mat->stencil.dim;
4255     (*M)->stencil.noc = mat->stencil.noc;
4256     for (i=0; i<=mat->stencil.dim; i++) {
4257       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4258       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4259     }
4260     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4261   }
4262   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4263 
4264   /* Copy Mat options */
4265   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4266   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4267   PetscFunctionReturn(0);
4268 }
4269 
4270 /*@C
4271    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4272 
4273    Not Collective
4274 
4275    Input Parameter:
4276 .  mat - the matrix, must be a factored matrix
4277 
4278    Output Parameter:
4279 .   type - the string name of the package (do not free this string)
4280 
4281    Notes:
4282       In Fortran you pass in a empty string and the package name will be copied into it.
4283     (Make sure the string is long enough)
4284 
4285    Level: intermediate
4286 
4287 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4288 @*/
4289 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4290 {
4291   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4292 
4293   PetscFunctionBegin;
4294   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4295   PetscValidType(mat,1);
4296   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4297   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4298   if (!conv) {
4299     *type = MATSOLVERPETSC;
4300   } else {
4301     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4302   }
4303   PetscFunctionReturn(0);
4304 }
4305 
4306 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4307 struct _MatSolverTypeForSpecifcType {
4308   MatType                        mtype;
4309   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4310   MatSolverTypeForSpecifcType next;
4311 };
4312 
4313 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4314 struct _MatSolverTypeHolder {
4315   char                           *name;
4316   MatSolverTypeForSpecifcType handlers;
4317   MatSolverTypeHolder         next;
4318 };
4319 
4320 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4321 
4322 /*@C
4323    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4324 
4325    Input Parameters:
4326 +    package - name of the package, for example petsc or superlu
4327 .    mtype - the matrix type that works with this package
4328 .    ftype - the type of factorization supported by the package
4329 -    getfactor - routine that will create the factored matrix ready to be used
4330 
4331     Level: intermediate
4332 
4333 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4334 @*/
4335 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4336 {
4337   PetscErrorCode              ierr;
4338   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4339   PetscBool                   flg;
4340   MatSolverTypeForSpecifcType inext,iprev = NULL;
4341 
4342   PetscFunctionBegin;
4343   ierr = MatInitializePackage();CHKERRQ(ierr);
4344   if (!next) {
4345     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4346     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4347     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4348     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4349     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4350     PetscFunctionReturn(0);
4351   }
4352   while (next) {
4353     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4354     if (flg) {
4355       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4356       inext = next->handlers;
4357       while (inext) {
4358         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4359         if (flg) {
4360           inext->getfactor[(int)ftype-1] = getfactor;
4361           PetscFunctionReturn(0);
4362         }
4363         iprev = inext;
4364         inext = inext->next;
4365       }
4366       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4367       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4368       iprev->next->getfactor[(int)ftype-1] = getfactor;
4369       PetscFunctionReturn(0);
4370     }
4371     prev = next;
4372     next = next->next;
4373   }
4374   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4375   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4376   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4377   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4378   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4379   PetscFunctionReturn(0);
4380 }
4381 
4382 /*@C
4383    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4384 
4385    Input Parameters:
4386 +    package - name of the package, for example petsc or superlu
4387 .    ftype - the type of factorization supported by the package
4388 -    mtype - the matrix type that works with this package
4389 
4390    Output Parameters:
4391 +   foundpackage - PETSC_TRUE if the package was registered
4392 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4393 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4394 
4395     Level: intermediate
4396 
4397 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4398 @*/
4399 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4400 {
4401   PetscErrorCode                 ierr;
4402   MatSolverTypeHolder         next = MatSolverTypeHolders;
4403   PetscBool                      flg;
4404   MatSolverTypeForSpecifcType inext;
4405 
4406   PetscFunctionBegin;
4407   if (foundpackage) *foundpackage = PETSC_FALSE;
4408   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4409   if (getfactor)    *getfactor    = NULL;
4410 
4411   if (package) {
4412     while (next) {
4413       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4414       if (flg) {
4415         if (foundpackage) *foundpackage = PETSC_TRUE;
4416         inext = next->handlers;
4417         while (inext) {
4418           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4419           if (flg) {
4420             if (foundmtype) *foundmtype = PETSC_TRUE;
4421             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4422             PetscFunctionReturn(0);
4423           }
4424           inext = inext->next;
4425         }
4426       }
4427       next = next->next;
4428     }
4429   } else {
4430     while (next) {
4431       inext = next->handlers;
4432       while (inext) {
4433         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4434         if (flg && inext->getfactor[(int)ftype-1]) {
4435           if (foundpackage) *foundpackage = PETSC_TRUE;
4436           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4437           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4438           PetscFunctionReturn(0);
4439         }
4440         inext = inext->next;
4441       }
4442       next = next->next;
4443     }
4444   }
4445   PetscFunctionReturn(0);
4446 }
4447 
4448 PetscErrorCode MatSolverTypeDestroy(void)
4449 {
4450   PetscErrorCode              ierr;
4451   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4452   MatSolverTypeForSpecifcType inext,iprev;
4453 
4454   PetscFunctionBegin;
4455   while (next) {
4456     ierr = PetscFree(next->name);CHKERRQ(ierr);
4457     inext = next->handlers;
4458     while (inext) {
4459       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4460       iprev = inext;
4461       inext = inext->next;
4462       ierr = PetscFree(iprev);CHKERRQ(ierr);
4463     }
4464     prev = next;
4465     next = next->next;
4466     ierr = PetscFree(prev);CHKERRQ(ierr);
4467   }
4468   MatSolverTypeHolders = NULL;
4469   PetscFunctionReturn(0);
4470 }
4471 
4472 /*@C
4473    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4474 
4475    Collective on Mat
4476 
4477    Input Parameters:
4478 +  mat - the matrix
4479 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4480 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4481 
4482    Output Parameters:
4483 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4484 
4485    Notes:
4486       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4487      such as pastix, superlu, mumps etc.
4488 
4489       PETSc must have been ./configure to use the external solver, using the option --download-package
4490 
4491    Level: intermediate
4492 
4493 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4494 @*/
4495 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4496 {
4497   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4498   PetscBool      foundpackage,foundmtype;
4499 
4500   PetscFunctionBegin;
4501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4502   PetscValidType(mat,1);
4503 
4504   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4505   MatCheckPreallocated(mat,1);
4506 
4507   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4508   if (!foundpackage) {
4509     if (type) {
4510       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4511     } else {
4512       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4513     }
4514   }
4515 
4516   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4517   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);
4518 
4519 #if defined(PETSC_USE_COMPLEX)
4520   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");
4521 #endif
4522 
4523   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4524   PetscFunctionReturn(0);
4525 }
4526 
4527 /*@C
4528    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4529 
4530    Not Collective
4531 
4532    Input Parameters:
4533 +  mat - the matrix
4534 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4535 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4536 
4537    Output Parameter:
4538 .    flg - PETSC_TRUE if the factorization is available
4539 
4540    Notes:
4541       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4542      such as pastix, superlu, mumps etc.
4543 
4544       PETSc must have been ./configure to use the external solver, using the option --download-package
4545 
4546    Level: intermediate
4547 
4548 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4549 @*/
4550 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4551 {
4552   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4553 
4554   PetscFunctionBegin;
4555   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4556   PetscValidType(mat,1);
4557 
4558   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4559   MatCheckPreallocated(mat,1);
4560 
4561   *flg = PETSC_FALSE;
4562   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4563   if (gconv) {
4564     *flg = PETSC_TRUE;
4565   }
4566   PetscFunctionReturn(0);
4567 }
4568 
4569 #include <petscdmtypes.h>
4570 
4571 /*@
4572    MatDuplicate - Duplicates a matrix including the non-zero structure.
4573 
4574    Collective on Mat
4575 
4576    Input Parameters:
4577 +  mat - the matrix
4578 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4579         See the manual page for MatDuplicateOption for an explanation of these options.
4580 
4581    Output Parameter:
4582 .  M - pointer to place new matrix
4583 
4584    Level: intermediate
4585 
4586    Concepts: matrices^duplicating
4587 
4588    Notes:
4589     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4590     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.
4591 
4592 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4593 @*/
4594 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4595 {
4596   PetscErrorCode ierr;
4597   Mat            B;
4598   PetscInt       i;
4599   DM             dm;
4600   void           (*viewf)(void);
4601 
4602   PetscFunctionBegin;
4603   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4604   PetscValidType(mat,1);
4605   PetscValidPointer(M,3);
4606   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4607   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4608   MatCheckPreallocated(mat,1);
4609 
4610   *M = 0;
4611   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4612   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4613   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4614   B    = *M;
4615 
4616   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4617   if (viewf) {
4618     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4619   }
4620 
4621   B->stencil.dim = mat->stencil.dim;
4622   B->stencil.noc = mat->stencil.noc;
4623   for (i=0; i<=mat->stencil.dim; i++) {
4624     B->stencil.dims[i]   = mat->stencil.dims[i];
4625     B->stencil.starts[i] = mat->stencil.starts[i];
4626   }
4627 
4628   B->nooffproczerorows = mat->nooffproczerorows;
4629   B->nooffprocentries  = mat->nooffprocentries;
4630 
4631   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4632   if (dm) {
4633     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4634   }
4635   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4636   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4637   PetscFunctionReturn(0);
4638 }
4639 
4640 /*@
4641    MatGetDiagonal - Gets the diagonal of a matrix.
4642 
4643    Logically Collective on Mat and Vec
4644 
4645    Input Parameters:
4646 +  mat - the matrix
4647 -  v - the vector for storing the diagonal
4648 
4649    Output Parameter:
4650 .  v - the diagonal of the matrix
4651 
4652    Level: intermediate
4653 
4654    Note:
4655    Currently only correct in parallel for square matrices.
4656 
4657    Concepts: matrices^accessing diagonals
4658 
4659 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4660 @*/
4661 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4662 {
4663   PetscErrorCode ierr;
4664 
4665   PetscFunctionBegin;
4666   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4667   PetscValidType(mat,1);
4668   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4669   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4670   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4671   MatCheckPreallocated(mat,1);
4672 
4673   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4674   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4675   PetscFunctionReturn(0);
4676 }
4677 
4678 /*@C
4679    MatGetRowMin - Gets the minimum value (of the real part) of each
4680         row of the matrix
4681 
4682    Logically Collective on Mat and Vec
4683 
4684    Input Parameters:
4685 .  mat - the matrix
4686 
4687    Output Parameter:
4688 +  v - the vector for storing the maximums
4689 -  idx - the indices of the column found for each row (optional)
4690 
4691    Level: intermediate
4692 
4693    Notes:
4694     The result of this call are the same as if one converted the matrix to dense format
4695       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4696 
4697     This code is only implemented for a couple of matrix formats.
4698 
4699    Concepts: matrices^getting row maximums
4700 
4701 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4702           MatGetRowMax()
4703 @*/
4704 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4705 {
4706   PetscErrorCode ierr;
4707 
4708   PetscFunctionBegin;
4709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4710   PetscValidType(mat,1);
4711   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4712   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4713   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4714   MatCheckPreallocated(mat,1);
4715 
4716   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4717   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4718   PetscFunctionReturn(0);
4719 }
4720 
4721 /*@C
4722    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4723         row of the matrix
4724 
4725    Logically Collective on Mat and Vec
4726 
4727    Input Parameters:
4728 .  mat - the matrix
4729 
4730    Output Parameter:
4731 +  v - the vector for storing the minimums
4732 -  idx - the indices of the column found for each row (or NULL if not needed)
4733 
4734    Level: intermediate
4735 
4736    Notes:
4737     if a row is completely empty or has only 0.0 values then the idx[] value for that
4738     row is 0 (the first column).
4739 
4740     This code is only implemented for a couple of matrix formats.
4741 
4742    Concepts: matrices^getting row maximums
4743 
4744 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4745 @*/
4746 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4747 {
4748   PetscErrorCode ierr;
4749 
4750   PetscFunctionBegin;
4751   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4752   PetscValidType(mat,1);
4753   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4754   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4755   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4756   MatCheckPreallocated(mat,1);
4757   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4758 
4759   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4760   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4761   PetscFunctionReturn(0);
4762 }
4763 
4764 /*@C
4765    MatGetRowMax - Gets the maximum value (of the real part) of each
4766         row of the matrix
4767 
4768    Logically Collective on Mat and Vec
4769 
4770    Input Parameters:
4771 .  mat - the matrix
4772 
4773    Output Parameter:
4774 +  v - the vector for storing the maximums
4775 -  idx - the indices of the column found for each row (optional)
4776 
4777    Level: intermediate
4778 
4779    Notes:
4780     The result of this call are the same as if one converted the matrix to dense format
4781       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4782 
4783     This code is only implemented for a couple of matrix formats.
4784 
4785    Concepts: matrices^getting row maximums
4786 
4787 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4788 @*/
4789 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4790 {
4791   PetscErrorCode ierr;
4792 
4793   PetscFunctionBegin;
4794   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4795   PetscValidType(mat,1);
4796   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4797   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4798   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4799   MatCheckPreallocated(mat,1);
4800 
4801   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4802   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4803   PetscFunctionReturn(0);
4804 }
4805 
4806 /*@C
4807    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4808         row of the matrix
4809 
4810    Logically Collective on Mat and Vec
4811 
4812    Input Parameters:
4813 .  mat - the matrix
4814 
4815    Output Parameter:
4816 +  v - the vector for storing the maximums
4817 -  idx - the indices of the column found for each row (or NULL if not needed)
4818 
4819    Level: intermediate
4820 
4821    Notes:
4822     if a row is completely empty or has only 0.0 values then the idx[] value for that
4823     row is 0 (the first column).
4824 
4825     This code is only implemented for a couple of matrix formats.
4826 
4827    Concepts: matrices^getting row maximums
4828 
4829 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4830 @*/
4831 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4832 {
4833   PetscErrorCode ierr;
4834 
4835   PetscFunctionBegin;
4836   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4837   PetscValidType(mat,1);
4838   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4839   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4840   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4841   MatCheckPreallocated(mat,1);
4842   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4843 
4844   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4845   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4846   PetscFunctionReturn(0);
4847 }
4848 
4849 /*@
4850    MatGetRowSum - Gets the sum of each row of the matrix
4851 
4852    Logically or Neighborhood Collective on Mat and Vec
4853 
4854    Input Parameters:
4855 .  mat - the matrix
4856 
4857    Output Parameter:
4858 .  v - the vector for storing the sum of rows
4859 
4860    Level: intermediate
4861 
4862    Notes:
4863     This code is slow since it is not currently specialized for different formats
4864 
4865    Concepts: matrices^getting row sums
4866 
4867 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4868 @*/
4869 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4870 {
4871   Vec            ones;
4872   PetscErrorCode ierr;
4873 
4874   PetscFunctionBegin;
4875   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4876   PetscValidType(mat,1);
4877   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4878   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4879   MatCheckPreallocated(mat,1);
4880   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4881   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4882   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4883   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4884   PetscFunctionReturn(0);
4885 }
4886 
4887 /*@
4888    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4889 
4890    Collective on Mat
4891 
4892    Input Parameter:
4893 +  mat - the matrix to transpose
4894 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4895 
4896    Output Parameters:
4897 .  B - the transpose
4898 
4899    Notes:
4900      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4901 
4902      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4903 
4904      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4905 
4906    Level: intermediate
4907 
4908    Concepts: matrices^transposing
4909 
4910 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4911 @*/
4912 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4913 {
4914   PetscErrorCode ierr;
4915 
4916   PetscFunctionBegin;
4917   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4918   PetscValidType(mat,1);
4919   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4920   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4921   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4922   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4923   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4924   MatCheckPreallocated(mat,1);
4925 
4926   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4927   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4928   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4929   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4930   PetscFunctionReturn(0);
4931 }
4932 
4933 /*@
4934    MatIsTranspose - Test whether a matrix is another one's transpose,
4935         or its own, in which case it tests symmetry.
4936 
4937    Collective on Mat
4938 
4939    Input Parameter:
4940 +  A - the matrix to test
4941 -  B - the matrix to test against, this can equal the first parameter
4942 
4943    Output Parameters:
4944 .  flg - the result
4945 
4946    Notes:
4947    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4948    has a running time of the order of the number of nonzeros; the parallel
4949    test involves parallel copies of the block-offdiagonal parts of the matrix.
4950 
4951    Level: intermediate
4952 
4953    Concepts: matrices^transposing, matrix^symmetry
4954 
4955 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4956 @*/
4957 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4958 {
4959   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4960 
4961   PetscFunctionBegin;
4962   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4963   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4964   PetscValidPointer(flg,3);
4965   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4966   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4967   *flg = PETSC_FALSE;
4968   if (f && g) {
4969     if (f == g) {
4970       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4971     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4972   } else {
4973     MatType mattype;
4974     if (!f) {
4975       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4976     } else {
4977       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4978     }
4979     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4980   }
4981   PetscFunctionReturn(0);
4982 }
4983 
4984 /*@
4985    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4986 
4987    Collective on Mat
4988 
4989    Input Parameter:
4990 +  mat - the matrix to transpose and complex conjugate
4991 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4992 
4993    Output Parameters:
4994 .  B - the Hermitian
4995 
4996    Level: intermediate
4997 
4998    Concepts: matrices^transposing, complex conjugatex
4999 
5000 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5001 @*/
5002 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5003 {
5004   PetscErrorCode ierr;
5005 
5006   PetscFunctionBegin;
5007   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5008 #if defined(PETSC_USE_COMPLEX)
5009   ierr = MatConjugate(*B);CHKERRQ(ierr);
5010 #endif
5011   PetscFunctionReturn(0);
5012 }
5013 
5014 /*@
5015    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5016 
5017    Collective on Mat
5018 
5019    Input Parameter:
5020 +  A - the matrix to test
5021 -  B - the matrix to test against, this can equal the first parameter
5022 
5023    Output Parameters:
5024 .  flg - the result
5025 
5026    Notes:
5027    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5028    has a running time of the order of the number of nonzeros; the parallel
5029    test involves parallel copies of the block-offdiagonal parts of the matrix.
5030 
5031    Level: intermediate
5032 
5033    Concepts: matrices^transposing, matrix^symmetry
5034 
5035 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5036 @*/
5037 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5038 {
5039   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5040 
5041   PetscFunctionBegin;
5042   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5043   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5044   PetscValidPointer(flg,3);
5045   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5046   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5047   if (f && g) {
5048     if (f==g) {
5049       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5050     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5051   }
5052   PetscFunctionReturn(0);
5053 }
5054 
5055 /*@
5056    MatPermute - Creates a new matrix with rows and columns permuted from the
5057    original.
5058 
5059    Collective on Mat
5060 
5061    Input Parameters:
5062 +  mat - the matrix to permute
5063 .  row - row permutation, each processor supplies only the permutation for its rows
5064 -  col - column permutation, each processor supplies only the permutation for its columns
5065 
5066    Output Parameters:
5067 .  B - the permuted matrix
5068 
5069    Level: advanced
5070 
5071    Note:
5072    The index sets map from row/col of permuted matrix to row/col of original matrix.
5073    The index sets should be on the same communicator as Mat and have the same local sizes.
5074 
5075    Concepts: matrices^permuting
5076 
5077 .seealso: MatGetOrdering(), ISAllGather()
5078 
5079 @*/
5080 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5081 {
5082   PetscErrorCode ierr;
5083 
5084   PetscFunctionBegin;
5085   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5086   PetscValidType(mat,1);
5087   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5088   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5089   PetscValidPointer(B,4);
5090   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5091   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5092   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5093   MatCheckPreallocated(mat,1);
5094 
5095   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5096   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5097   PetscFunctionReturn(0);
5098 }
5099 
5100 /*@
5101    MatEqual - Compares two matrices.
5102 
5103    Collective on Mat
5104 
5105    Input Parameters:
5106 +  A - the first matrix
5107 -  B - the second matrix
5108 
5109    Output Parameter:
5110 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5111 
5112    Level: intermediate
5113 
5114    Concepts: matrices^equality between
5115 @*/
5116 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5117 {
5118   PetscErrorCode ierr;
5119 
5120   PetscFunctionBegin;
5121   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5122   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5123   PetscValidType(A,1);
5124   PetscValidType(B,2);
5125   PetscValidIntPointer(flg,3);
5126   PetscCheckSameComm(A,1,B,2);
5127   MatCheckPreallocated(B,2);
5128   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5129   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5130   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);
5131   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5132   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5133   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);
5134   MatCheckPreallocated(A,1);
5135 
5136   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5137   PetscFunctionReturn(0);
5138 }
5139 
5140 /*@
5141    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5142    matrices that are stored as vectors.  Either of the two scaling
5143    matrices can be NULL.
5144 
5145    Collective on Mat
5146 
5147    Input Parameters:
5148 +  mat - the matrix to be scaled
5149 .  l - the left scaling vector (or NULL)
5150 -  r - the right scaling vector (or NULL)
5151 
5152    Notes:
5153    MatDiagonalScale() computes A = LAR, where
5154    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5155    The L scales the rows of the matrix, the R scales the columns of the matrix.
5156 
5157    Level: intermediate
5158 
5159    Concepts: matrices^diagonal scaling
5160    Concepts: diagonal scaling of matrices
5161 
5162 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5163 @*/
5164 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5165 {
5166   PetscErrorCode ierr;
5167 
5168   PetscFunctionBegin;
5169   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5170   PetscValidType(mat,1);
5171   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5172   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5173   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5174   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5175   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5176   MatCheckPreallocated(mat,1);
5177 
5178   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5179   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5180   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5181   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5182 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5183   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5184     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5185   }
5186 #endif
5187   PetscFunctionReturn(0);
5188 }
5189 
5190 /*@
5191     MatScale - Scales all elements of a matrix by a given number.
5192 
5193     Logically Collective on Mat
5194 
5195     Input Parameters:
5196 +   mat - the matrix to be scaled
5197 -   a  - the scaling value
5198 
5199     Output Parameter:
5200 .   mat - the scaled matrix
5201 
5202     Level: intermediate
5203 
5204     Concepts: matrices^scaling all entries
5205 
5206 .seealso: MatDiagonalScale()
5207 @*/
5208 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5209 {
5210   PetscErrorCode ierr;
5211 
5212   PetscFunctionBegin;
5213   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5214   PetscValidType(mat,1);
5215   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5216   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5217   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5218   PetscValidLogicalCollectiveScalar(mat,a,2);
5219   MatCheckPreallocated(mat,1);
5220 
5221   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5222   if (a != (PetscScalar)1.0) {
5223     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5224     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5225 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5226     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5227       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5228     }
5229 #endif
5230   }
5231   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5232   PetscFunctionReturn(0);
5233 }
5234 
5235 /*@
5236    MatNorm - Calculates various norms of a matrix.
5237 
5238    Collective on Mat
5239 
5240    Input Parameters:
5241 +  mat - the matrix
5242 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5243 
5244    Output Parameters:
5245 .  nrm - the resulting norm
5246 
5247    Level: intermediate
5248 
5249    Concepts: matrices^norm
5250    Concepts: norm^of matrix
5251 @*/
5252 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5253 {
5254   PetscErrorCode ierr;
5255 
5256   PetscFunctionBegin;
5257   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5258   PetscValidType(mat,1);
5259   PetscValidScalarPointer(nrm,3);
5260 
5261   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5262   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5263   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5264   MatCheckPreallocated(mat,1);
5265 
5266   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5267   PetscFunctionReturn(0);
5268 }
5269 
5270 /*
5271      This variable is used to prevent counting of MatAssemblyBegin() that
5272    are called from within a MatAssemblyEnd().
5273 */
5274 static PetscInt MatAssemblyEnd_InUse = 0;
5275 /*@
5276    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5277    be called after completing all calls to MatSetValues().
5278 
5279    Collective on Mat
5280 
5281    Input Parameters:
5282 +  mat - the matrix
5283 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5284 
5285    Notes:
5286    MatSetValues() generally caches the values.  The matrix is ready to
5287    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5288    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5289    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5290    using the matrix.
5291 
5292    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5293    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
5294    a global collective operation requring all processes that share the matrix.
5295 
5296    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5297    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5298    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5299 
5300    Level: beginner
5301 
5302    Concepts: matrices^assembling
5303 
5304 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5305 @*/
5306 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5307 {
5308   PetscErrorCode ierr;
5309 
5310   PetscFunctionBegin;
5311   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5312   PetscValidType(mat,1);
5313   MatCheckPreallocated(mat,1);
5314   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5315   if (mat->assembled) {
5316     mat->was_assembled = PETSC_TRUE;
5317     mat->assembled     = PETSC_FALSE;
5318   }
5319   if (!MatAssemblyEnd_InUse) {
5320     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5321     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5322     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5323   } else if (mat->ops->assemblybegin) {
5324     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5325   }
5326   PetscFunctionReturn(0);
5327 }
5328 
5329 /*@
5330    MatAssembled - Indicates if a matrix has been assembled and is ready for
5331      use; for example, in matrix-vector product.
5332 
5333    Not Collective
5334 
5335    Input Parameter:
5336 .  mat - the matrix
5337 
5338    Output Parameter:
5339 .  assembled - PETSC_TRUE or PETSC_FALSE
5340 
5341    Level: advanced
5342 
5343    Concepts: matrices^assembled?
5344 
5345 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5346 @*/
5347 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5348 {
5349   PetscFunctionBegin;
5350   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5351   PetscValidPointer(assembled,2);
5352   *assembled = mat->assembled;
5353   PetscFunctionReturn(0);
5354 }
5355 
5356 /*@
5357    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5358    be called after MatAssemblyBegin().
5359 
5360    Collective on Mat
5361 
5362    Input Parameters:
5363 +  mat - the matrix
5364 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5365 
5366    Options Database Keys:
5367 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5368 .  -mat_view ::ascii_info_detail - Prints more detailed info
5369 .  -mat_view - Prints matrix in ASCII format
5370 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5371 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5372 .  -display <name> - Sets display name (default is host)
5373 .  -draw_pause <sec> - Sets number of seconds to pause after display
5374 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5375 .  -viewer_socket_machine <machine> - Machine to use for socket
5376 .  -viewer_socket_port <port> - Port number to use for socket
5377 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5378 
5379    Notes:
5380    MatSetValues() generally caches the values.  The matrix is ready to
5381    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5382    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5383    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5384    using the matrix.
5385 
5386    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5387    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5388    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5389 
5390    Level: beginner
5391 
5392 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5393 @*/
5394 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5395 {
5396   PetscErrorCode  ierr;
5397   static PetscInt inassm = 0;
5398   PetscBool       flg    = PETSC_FALSE;
5399 
5400   PetscFunctionBegin;
5401   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5402   PetscValidType(mat,1);
5403 
5404   inassm++;
5405   MatAssemblyEnd_InUse++;
5406   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5407     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5408     if (mat->ops->assemblyend) {
5409       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5410     }
5411     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5412   } else if (mat->ops->assemblyend) {
5413     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5414   }
5415 
5416   /* Flush assembly is not a true assembly */
5417   if (type != MAT_FLUSH_ASSEMBLY) {
5418     mat->assembled = PETSC_TRUE; mat->num_ass++;
5419   }
5420   mat->insertmode = NOT_SET_VALUES;
5421   MatAssemblyEnd_InUse--;
5422   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5423   if (!mat->symmetric_eternal) {
5424     mat->symmetric_set              = PETSC_FALSE;
5425     mat->hermitian_set              = PETSC_FALSE;
5426     mat->structurally_symmetric_set = PETSC_FALSE;
5427   }
5428 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5429   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5430     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5431   }
5432 #endif
5433   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5434     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5435 
5436     if (mat->checksymmetryonassembly) {
5437       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5438       if (flg) {
5439         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5440       } else {
5441         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5442       }
5443     }
5444     if (mat->nullsp && mat->checknullspaceonassembly) {
5445       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5446     }
5447   }
5448   inassm--;
5449   PetscFunctionReturn(0);
5450 }
5451 
5452 /*@
5453    MatSetOption - Sets a parameter option for a matrix. Some options
5454    may be specific to certain storage formats.  Some options
5455    determine how values will be inserted (or added). Sorted,
5456    row-oriented input will generally assemble the fastest. The default
5457    is row-oriented.
5458 
5459    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5460 
5461    Input Parameters:
5462 +  mat - the matrix
5463 .  option - the option, one of those listed below (and possibly others),
5464 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5465 
5466   Options Describing Matrix Structure:
5467 +    MAT_SPD - symmetric positive definite
5468 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5469 .    MAT_HERMITIAN - transpose is the complex conjugation
5470 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5471 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5472                             you set to be kept with all future use of the matrix
5473                             including after MatAssemblyBegin/End() which could
5474                             potentially change the symmetry structure, i.e. you
5475                             KNOW the matrix will ALWAYS have the property you set.
5476 
5477 
5478    Options For Use with MatSetValues():
5479    Insert a logically dense subblock, which can be
5480 .    MAT_ROW_ORIENTED - row-oriented (default)
5481 
5482    Note these options reflect the data you pass in with MatSetValues(); it has
5483    nothing to do with how the data is stored internally in the matrix
5484    data structure.
5485 
5486    When (re)assembling a matrix, we can restrict the input for
5487    efficiency/debugging purposes.  These options include:
5488 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5489 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5490 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5491 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5492 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5493 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5494         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5495         performance for very large process counts.
5496 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5497         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5498         functions, instead sending only neighbor messages.
5499 
5500    Notes:
5501    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5502 
5503    Some options are relevant only for particular matrix types and
5504    are thus ignored by others.  Other options are not supported by
5505    certain matrix types and will generate an error message if set.
5506 
5507    If using a Fortran 77 module to compute a matrix, one may need to
5508    use the column-oriented option (or convert to the row-oriented
5509    format).
5510 
5511    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5512    that would generate a new entry in the nonzero structure is instead
5513    ignored.  Thus, if memory has not alredy been allocated for this particular
5514    data, then the insertion is ignored. For dense matrices, in which
5515    the entire array is allocated, no entries are ever ignored.
5516    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5517 
5518    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5519    that would generate a new entry in the nonzero structure instead produces
5520    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
5521 
5522    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5523    that would generate a new entry that has not been preallocated will
5524    instead produce an error. (Currently supported for AIJ and BAIJ formats
5525    only.) This is a useful flag when debugging matrix memory preallocation.
5526    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5527 
5528    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5529    other processors should be dropped, rather than stashed.
5530    This is useful if you know that the "owning" processor is also
5531    always generating the correct matrix entries, so that PETSc need
5532    not transfer duplicate entries generated on another processor.
5533 
5534    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5535    searches during matrix assembly. When this flag is set, the hash table
5536    is created during the first Matrix Assembly. This hash table is
5537    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5538    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5539    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5540    supported by MATMPIBAIJ format only.
5541 
5542    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5543    are kept in the nonzero structure
5544 
5545    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5546    a zero location in the matrix
5547 
5548    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5549 
5550    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5551         zero row routines and thus improves performance for very large process counts.
5552 
5553    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5554         part of the matrix (since they should match the upper triangular part).
5555 
5556    Notes:
5557     Can only be called after MatSetSizes() and MatSetType() have been set.
5558 
5559    Level: intermediate
5560 
5561    Concepts: matrices^setting options
5562 
5563 .seealso:  MatOption, Mat
5564 
5565 @*/
5566 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5567 {
5568   PetscErrorCode ierr;
5569 
5570   PetscFunctionBegin;
5571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5572   PetscValidType(mat,1);
5573   if (op > 0) {
5574     PetscValidLogicalCollectiveEnum(mat,op,2);
5575     PetscValidLogicalCollectiveBool(mat,flg,3);
5576   }
5577 
5578   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);
5579   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()");
5580 
5581   switch (op) {
5582   case MAT_NO_OFF_PROC_ENTRIES:
5583     mat->nooffprocentries = flg;
5584     PetscFunctionReturn(0);
5585     break;
5586   case MAT_SUBSET_OFF_PROC_ENTRIES:
5587     mat->subsetoffprocentries = flg;
5588     PetscFunctionReturn(0);
5589   case MAT_NO_OFF_PROC_ZERO_ROWS:
5590     mat->nooffproczerorows = flg;
5591     PetscFunctionReturn(0);
5592     break;
5593   case MAT_SPD:
5594     mat->spd_set = PETSC_TRUE;
5595     mat->spd     = flg;
5596     if (flg) {
5597       mat->symmetric                  = PETSC_TRUE;
5598       mat->structurally_symmetric     = PETSC_TRUE;
5599       mat->symmetric_set              = PETSC_TRUE;
5600       mat->structurally_symmetric_set = PETSC_TRUE;
5601     }
5602     break;
5603   case MAT_SYMMETRIC:
5604     mat->symmetric = flg;
5605     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5606     mat->symmetric_set              = PETSC_TRUE;
5607     mat->structurally_symmetric_set = flg;
5608 #if !defined(PETSC_USE_COMPLEX)
5609     mat->hermitian     = flg;
5610     mat->hermitian_set = PETSC_TRUE;
5611 #endif
5612     break;
5613   case MAT_HERMITIAN:
5614     mat->hermitian = flg;
5615     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5616     mat->hermitian_set              = PETSC_TRUE;
5617     mat->structurally_symmetric_set = flg;
5618 #if !defined(PETSC_USE_COMPLEX)
5619     mat->symmetric     = flg;
5620     mat->symmetric_set = PETSC_TRUE;
5621 #endif
5622     break;
5623   case MAT_STRUCTURALLY_SYMMETRIC:
5624     mat->structurally_symmetric     = flg;
5625     mat->structurally_symmetric_set = PETSC_TRUE;
5626     break;
5627   case MAT_SYMMETRY_ETERNAL:
5628     mat->symmetric_eternal = flg;
5629     break;
5630   case MAT_STRUCTURE_ONLY:
5631     mat->structure_only = flg;
5632     break;
5633   default:
5634     break;
5635   }
5636   if (mat->ops->setoption) {
5637     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5638   }
5639   PetscFunctionReturn(0);
5640 }
5641 
5642 /*@
5643    MatGetOption - Gets a parameter option that has been set for a matrix.
5644 
5645    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5646 
5647    Input Parameters:
5648 +  mat - the matrix
5649 -  option - the option, this only responds to certain options, check the code for which ones
5650 
5651    Output Parameter:
5652 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5653 
5654     Notes:
5655     Can only be called after MatSetSizes() and MatSetType() have been set.
5656 
5657    Level: intermediate
5658 
5659    Concepts: matrices^setting options
5660 
5661 .seealso:  MatOption, MatSetOption()
5662 
5663 @*/
5664 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5665 {
5666   PetscFunctionBegin;
5667   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5668   PetscValidType(mat,1);
5669 
5670   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);
5671   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()");
5672 
5673   switch (op) {
5674   case MAT_NO_OFF_PROC_ENTRIES:
5675     *flg = mat->nooffprocentries;
5676     break;
5677   case MAT_NO_OFF_PROC_ZERO_ROWS:
5678     *flg = mat->nooffproczerorows;
5679     break;
5680   case MAT_SYMMETRIC:
5681     *flg = mat->symmetric;
5682     break;
5683   case MAT_HERMITIAN:
5684     *flg = mat->hermitian;
5685     break;
5686   case MAT_STRUCTURALLY_SYMMETRIC:
5687     *flg = mat->structurally_symmetric;
5688     break;
5689   case MAT_SYMMETRY_ETERNAL:
5690     *flg = mat->symmetric_eternal;
5691     break;
5692   case MAT_SPD:
5693     *flg = mat->spd;
5694     break;
5695   default:
5696     break;
5697   }
5698   PetscFunctionReturn(0);
5699 }
5700 
5701 /*@
5702    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5703    this routine retains the old nonzero structure.
5704 
5705    Logically Collective on Mat
5706 
5707    Input Parameters:
5708 .  mat - the matrix
5709 
5710    Level: intermediate
5711 
5712    Notes:
5713     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.
5714    See the Performance chapter of the users manual for information on preallocating matrices.
5715 
5716    Concepts: matrices^zeroing
5717 
5718 .seealso: MatZeroRows()
5719 @*/
5720 PetscErrorCode MatZeroEntries(Mat mat)
5721 {
5722   PetscErrorCode ierr;
5723 
5724   PetscFunctionBegin;
5725   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5726   PetscValidType(mat,1);
5727   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5728   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");
5729   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5730   MatCheckPreallocated(mat,1);
5731 
5732   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5733   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5734   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5735   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5736 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5737   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5738     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5739   }
5740 #endif
5741   PetscFunctionReturn(0);
5742 }
5743 
5744 /*@
5745    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5746    of a set of rows and columns of a matrix.
5747 
5748    Collective on Mat
5749 
5750    Input Parameters:
5751 +  mat - the matrix
5752 .  numRows - the number of rows to remove
5753 .  rows - the global row indices
5754 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5755 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5756 -  b - optional vector of right hand side, that will be adjusted by provided solution
5757 
5758    Notes:
5759    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5760 
5761    The user can set a value in the diagonal entry (or for the AIJ and
5762    row formats can optionally remove the main diagonal entry from the
5763    nonzero structure as well, by passing 0.0 as the final argument).
5764 
5765    For the parallel case, all processes that share the matrix (i.e.,
5766    those in the communicator used for matrix creation) MUST call this
5767    routine, regardless of whether any rows being zeroed are owned by
5768    them.
5769 
5770    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5771    list only rows local to itself).
5772 
5773    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5774 
5775    Level: intermediate
5776 
5777    Concepts: matrices^zeroing rows
5778 
5779 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5780           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5781 @*/
5782 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5783 {
5784   PetscErrorCode ierr;
5785 
5786   PetscFunctionBegin;
5787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5788   PetscValidType(mat,1);
5789   if (numRows) PetscValidIntPointer(rows,3);
5790   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5791   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5792   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5793   MatCheckPreallocated(mat,1);
5794 
5795   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5796   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5797   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5798 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5799   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5800     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5801   }
5802 #endif
5803   PetscFunctionReturn(0);
5804 }
5805 
5806 /*@
5807    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5808    of a set of rows and columns of a matrix.
5809 
5810    Collective on Mat
5811 
5812    Input Parameters:
5813 +  mat - the matrix
5814 .  is - the rows to zero
5815 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5816 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5817 -  b - optional vector of right hand side, that will be adjusted by provided solution
5818 
5819    Notes:
5820    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5821 
5822    The user can set a value in the diagonal entry (or for the AIJ and
5823    row formats can optionally remove the main diagonal entry from the
5824    nonzero structure as well, by passing 0.0 as the final argument).
5825 
5826    For the parallel case, all processes that share the matrix (i.e.,
5827    those in the communicator used for matrix creation) MUST call this
5828    routine, regardless of whether any rows being zeroed are owned by
5829    them.
5830 
5831    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5832    list only rows local to itself).
5833 
5834    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5835 
5836    Level: intermediate
5837 
5838    Concepts: matrices^zeroing rows
5839 
5840 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5841           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5842 @*/
5843 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5844 {
5845   PetscErrorCode ierr;
5846   PetscInt       numRows;
5847   const PetscInt *rows;
5848 
5849   PetscFunctionBegin;
5850   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5851   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5852   PetscValidType(mat,1);
5853   PetscValidType(is,2);
5854   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5855   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5856   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5857   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5858   PetscFunctionReturn(0);
5859 }
5860 
5861 /*@
5862    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5863    of a set of rows of a matrix.
5864 
5865    Collective on Mat
5866 
5867    Input Parameters:
5868 +  mat - the matrix
5869 .  numRows - the number of rows to remove
5870 .  rows - the global row indices
5871 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5872 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5873 -  b - optional vector of right hand side, that will be adjusted by provided solution
5874 
5875    Notes:
5876    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5877    but does not release memory.  For the dense and block diagonal
5878    formats this does not alter the nonzero structure.
5879 
5880    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5881    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5882    merely zeroed.
5883 
5884    The user can set a value in the diagonal entry (or for the AIJ and
5885    row formats can optionally remove the main diagonal entry from the
5886    nonzero structure as well, by passing 0.0 as the final argument).
5887 
5888    For the parallel case, all processes that share the matrix (i.e.,
5889    those in the communicator used for matrix creation) MUST call this
5890    routine, regardless of whether any rows being zeroed are owned by
5891    them.
5892 
5893    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5894    list only rows local to itself).
5895 
5896    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5897    owns that are to be zeroed. This saves a global synchronization in the implementation.
5898 
5899    Level: intermediate
5900 
5901    Concepts: matrices^zeroing rows
5902 
5903 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5904           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5905 @*/
5906 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5907 {
5908   PetscErrorCode ierr;
5909 
5910   PetscFunctionBegin;
5911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5912   PetscValidType(mat,1);
5913   if (numRows) PetscValidIntPointer(rows,3);
5914   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5915   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5916   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5917   MatCheckPreallocated(mat,1);
5918 
5919   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5920   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5921   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5922 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5923   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5924     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5925   }
5926 #endif
5927   PetscFunctionReturn(0);
5928 }
5929 
5930 /*@
5931    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5932    of a set of rows of a matrix.
5933 
5934    Collective on Mat
5935 
5936    Input Parameters:
5937 +  mat - the matrix
5938 .  is - index set of rows to remove
5939 .  diag - value put in all diagonals of eliminated rows
5940 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5941 -  b - optional vector of right hand side, that will be adjusted by provided solution
5942 
5943    Notes:
5944    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5945    but does not release memory.  For the dense and block diagonal
5946    formats this does not alter the nonzero structure.
5947 
5948    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5949    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5950    merely zeroed.
5951 
5952    The user can set a value in the diagonal entry (or for the AIJ and
5953    row formats can optionally remove the main diagonal entry from the
5954    nonzero structure as well, by passing 0.0 as the final argument).
5955 
5956    For the parallel case, all processes that share the matrix (i.e.,
5957    those in the communicator used for matrix creation) MUST call this
5958    routine, regardless of whether any rows being zeroed are owned by
5959    them.
5960 
5961    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5962    list only rows local to itself).
5963 
5964    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5965    owns that are to be zeroed. This saves a global synchronization in the implementation.
5966 
5967    Level: intermediate
5968 
5969    Concepts: matrices^zeroing rows
5970 
5971 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5972           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5973 @*/
5974 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5975 {
5976   PetscInt       numRows;
5977   const PetscInt *rows;
5978   PetscErrorCode ierr;
5979 
5980   PetscFunctionBegin;
5981   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5982   PetscValidType(mat,1);
5983   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5984   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5985   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5986   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5987   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5988   PetscFunctionReturn(0);
5989 }
5990 
5991 /*@
5992    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5993    of a set of rows of a matrix. These rows must be local to the process.
5994 
5995    Collective on Mat
5996 
5997    Input Parameters:
5998 +  mat - the matrix
5999 .  numRows - the number of rows to remove
6000 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6001 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6002 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6003 -  b - optional vector of right hand side, that will be adjusted by provided solution
6004 
6005    Notes:
6006    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6007    but does not release memory.  For the dense and block diagonal
6008    formats this does not alter the nonzero structure.
6009 
6010    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6011    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6012    merely zeroed.
6013 
6014    The user can set a value in the diagonal entry (or for the AIJ and
6015    row formats can optionally remove the main diagonal entry from the
6016    nonzero structure as well, by passing 0.0 as the final argument).
6017 
6018    For the parallel case, all processes that share the matrix (i.e.,
6019    those in the communicator used for matrix creation) MUST call this
6020    routine, regardless of whether any rows being zeroed are owned by
6021    them.
6022 
6023    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6024    list only rows local to itself).
6025 
6026    The grid coordinates are across the entire grid, not just the local portion
6027 
6028    In Fortran idxm and idxn should be declared as
6029 $     MatStencil idxm(4,m)
6030    and the values inserted using
6031 $    idxm(MatStencil_i,1) = i
6032 $    idxm(MatStencil_j,1) = j
6033 $    idxm(MatStencil_k,1) = k
6034 $    idxm(MatStencil_c,1) = c
6035    etc
6036 
6037    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6038    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6039    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6040    DM_BOUNDARY_PERIODIC boundary type.
6041 
6042    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
6043    a single value per point) you can skip filling those indices.
6044 
6045    Level: intermediate
6046 
6047    Concepts: matrices^zeroing rows
6048 
6049 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6050           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6051 @*/
6052 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6053 {
6054   PetscInt       dim     = mat->stencil.dim;
6055   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6056   PetscInt       *dims   = mat->stencil.dims+1;
6057   PetscInt       *starts = mat->stencil.starts;
6058   PetscInt       *dxm    = (PetscInt*) rows;
6059   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6060   PetscErrorCode ierr;
6061 
6062   PetscFunctionBegin;
6063   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6064   PetscValidType(mat,1);
6065   if (numRows) PetscValidIntPointer(rows,3);
6066 
6067   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6068   for (i = 0; i < numRows; ++i) {
6069     /* Skip unused dimensions (they are ordered k, j, i, c) */
6070     for (j = 0; j < 3-sdim; ++j) dxm++;
6071     /* Local index in X dir */
6072     tmp = *dxm++ - starts[0];
6073     /* Loop over remaining dimensions */
6074     for (j = 0; j < dim-1; ++j) {
6075       /* If nonlocal, set index to be negative */
6076       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6077       /* Update local index */
6078       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6079     }
6080     /* Skip component slot if necessary */
6081     if (mat->stencil.noc) dxm++;
6082     /* Local row number */
6083     if (tmp >= 0) {
6084       jdxm[numNewRows++] = tmp;
6085     }
6086   }
6087   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6088   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6089   PetscFunctionReturn(0);
6090 }
6091 
6092 /*@
6093    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6094    of a set of rows and columns of a matrix.
6095 
6096    Collective on Mat
6097 
6098    Input Parameters:
6099 +  mat - the matrix
6100 .  numRows - the number of rows/columns to remove
6101 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6102 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6103 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6104 -  b - optional vector of right hand side, that will be adjusted by provided solution
6105 
6106    Notes:
6107    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6108    but does not release memory.  For the dense and block diagonal
6109    formats this does not alter the nonzero structure.
6110 
6111    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6112    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6113    merely zeroed.
6114 
6115    The user can set a value in the diagonal entry (or for the AIJ and
6116    row formats can optionally remove the main diagonal entry from the
6117    nonzero structure as well, by passing 0.0 as the final argument).
6118 
6119    For the parallel case, all processes that share the matrix (i.e.,
6120    those in the communicator used for matrix creation) MUST call this
6121    routine, regardless of whether any rows being zeroed are owned by
6122    them.
6123 
6124    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6125    list only rows local to itself, but the row/column numbers are given in local numbering).
6126 
6127    The grid coordinates are across the entire grid, not just the local portion
6128 
6129    In Fortran idxm and idxn should be declared as
6130 $     MatStencil idxm(4,m)
6131    and the values inserted using
6132 $    idxm(MatStencil_i,1) = i
6133 $    idxm(MatStencil_j,1) = j
6134 $    idxm(MatStencil_k,1) = k
6135 $    idxm(MatStencil_c,1) = c
6136    etc
6137 
6138    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6139    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6140    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6141    DM_BOUNDARY_PERIODIC boundary type.
6142 
6143    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
6144    a single value per point) you can skip filling those indices.
6145 
6146    Level: intermediate
6147 
6148    Concepts: matrices^zeroing rows
6149 
6150 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6151           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6152 @*/
6153 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6154 {
6155   PetscInt       dim     = mat->stencil.dim;
6156   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6157   PetscInt       *dims   = mat->stencil.dims+1;
6158   PetscInt       *starts = mat->stencil.starts;
6159   PetscInt       *dxm    = (PetscInt*) rows;
6160   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6161   PetscErrorCode ierr;
6162 
6163   PetscFunctionBegin;
6164   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6165   PetscValidType(mat,1);
6166   if (numRows) PetscValidIntPointer(rows,3);
6167 
6168   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6169   for (i = 0; i < numRows; ++i) {
6170     /* Skip unused dimensions (they are ordered k, j, i, c) */
6171     for (j = 0; j < 3-sdim; ++j) dxm++;
6172     /* Local index in X dir */
6173     tmp = *dxm++ - starts[0];
6174     /* Loop over remaining dimensions */
6175     for (j = 0; j < dim-1; ++j) {
6176       /* If nonlocal, set index to be negative */
6177       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6178       /* Update local index */
6179       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6180     }
6181     /* Skip component slot if necessary */
6182     if (mat->stencil.noc) dxm++;
6183     /* Local row number */
6184     if (tmp >= 0) {
6185       jdxm[numNewRows++] = tmp;
6186     }
6187   }
6188   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6189   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6190   PetscFunctionReturn(0);
6191 }
6192 
6193 /*@C
6194    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6195    of a set of rows of a matrix; using local numbering of rows.
6196 
6197    Collective on Mat
6198 
6199    Input Parameters:
6200 +  mat - the matrix
6201 .  numRows - the number of rows to remove
6202 .  rows - the global row indices
6203 .  diag - value put in all diagonals of eliminated rows
6204 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6205 -  b - optional vector of right hand side, that will be adjusted by provided solution
6206 
6207    Notes:
6208    Before calling MatZeroRowsLocal(), the user must first set the
6209    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6210 
6211    For the AIJ matrix formats this removes the old nonzero structure,
6212    but does not release memory.  For the dense and block diagonal
6213    formats this does not alter the nonzero structure.
6214 
6215    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6216    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6217    merely zeroed.
6218 
6219    The user can set a value in the diagonal entry (or for the AIJ and
6220    row formats can optionally remove the main diagonal entry from the
6221    nonzero structure as well, by passing 0.0 as the final argument).
6222 
6223    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6224    owns that are to be zeroed. This saves a global synchronization in the implementation.
6225 
6226    Level: intermediate
6227 
6228    Concepts: matrices^zeroing
6229 
6230 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6231           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6232 @*/
6233 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6234 {
6235   PetscErrorCode ierr;
6236 
6237   PetscFunctionBegin;
6238   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6239   PetscValidType(mat,1);
6240   if (numRows) PetscValidIntPointer(rows,3);
6241   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6242   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6243   MatCheckPreallocated(mat,1);
6244 
6245   if (mat->ops->zerorowslocal) {
6246     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6247   } else {
6248     IS             is, newis;
6249     const PetscInt *newRows;
6250 
6251     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6252     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6253     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6254     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6255     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6256     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6257     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6258     ierr = ISDestroy(&is);CHKERRQ(ierr);
6259   }
6260   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6261 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6262   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6263     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6264   }
6265 #endif
6266   PetscFunctionReturn(0);
6267 }
6268 
6269 /*@
6270    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6271    of a set of rows of a matrix; using local numbering of rows.
6272 
6273    Collective on Mat
6274 
6275    Input Parameters:
6276 +  mat - the matrix
6277 .  is - index set of rows to remove
6278 .  diag - value put in all diagonals of eliminated rows
6279 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6280 -  b - optional vector of right hand side, that will be adjusted by provided solution
6281 
6282    Notes:
6283    Before calling MatZeroRowsLocalIS(), the user must first set the
6284    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6285 
6286    For the AIJ matrix formats this removes the old nonzero structure,
6287    but does not release memory.  For the dense and block diagonal
6288    formats this does not alter the nonzero structure.
6289 
6290    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6291    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6292    merely zeroed.
6293 
6294    The user can set a value in the diagonal entry (or for the AIJ and
6295    row formats can optionally remove the main diagonal entry from the
6296    nonzero structure as well, by passing 0.0 as the final argument).
6297 
6298    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6299    owns that are to be zeroed. This saves a global synchronization in the implementation.
6300 
6301    Level: intermediate
6302 
6303    Concepts: matrices^zeroing
6304 
6305 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6306           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6307 @*/
6308 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6309 {
6310   PetscErrorCode ierr;
6311   PetscInt       numRows;
6312   const PetscInt *rows;
6313 
6314   PetscFunctionBegin;
6315   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6316   PetscValidType(mat,1);
6317   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6318   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6319   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6320   MatCheckPreallocated(mat,1);
6321 
6322   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6323   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6324   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6325   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6326   PetscFunctionReturn(0);
6327 }
6328 
6329 /*@
6330    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6331    of a set of rows and columns of a matrix; using local numbering of rows.
6332 
6333    Collective on Mat
6334 
6335    Input Parameters:
6336 +  mat - the matrix
6337 .  numRows - the number of rows to remove
6338 .  rows - the global row indices
6339 .  diag - value put in all diagonals of eliminated rows
6340 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6341 -  b - optional vector of right hand side, that will be adjusted by provided solution
6342 
6343    Notes:
6344    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6345    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6346 
6347    The user can set a value in the diagonal entry (or for the AIJ and
6348    row formats can optionally remove the main diagonal entry from the
6349    nonzero structure as well, by passing 0.0 as the final argument).
6350 
6351    Level: intermediate
6352 
6353    Concepts: matrices^zeroing
6354 
6355 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6356           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6357 @*/
6358 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6359 {
6360   PetscErrorCode ierr;
6361   IS             is, newis;
6362   const PetscInt *newRows;
6363 
6364   PetscFunctionBegin;
6365   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6366   PetscValidType(mat,1);
6367   if (numRows) PetscValidIntPointer(rows,3);
6368   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6369   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6370   MatCheckPreallocated(mat,1);
6371 
6372   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6373   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6374   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6375   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6376   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6377   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6378   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6379   ierr = ISDestroy(&is);CHKERRQ(ierr);
6380   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6381 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6382   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6383     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6384   }
6385 #endif
6386   PetscFunctionReturn(0);
6387 }
6388 
6389 /*@
6390    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6391    of a set of rows and columns of a matrix; using local numbering of rows.
6392 
6393    Collective on Mat
6394 
6395    Input Parameters:
6396 +  mat - the matrix
6397 .  is - index set of rows to remove
6398 .  diag - value put in all diagonals of eliminated rows
6399 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6400 -  b - optional vector of right hand side, that will be adjusted by provided solution
6401 
6402    Notes:
6403    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6404    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6405 
6406    The user can set a value in the diagonal entry (or for the AIJ and
6407    row formats can optionally remove the main diagonal entry from the
6408    nonzero structure as well, by passing 0.0 as the final argument).
6409 
6410    Level: intermediate
6411 
6412    Concepts: matrices^zeroing
6413 
6414 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6415           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6416 @*/
6417 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6418 {
6419   PetscErrorCode ierr;
6420   PetscInt       numRows;
6421   const PetscInt *rows;
6422 
6423   PetscFunctionBegin;
6424   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6425   PetscValidType(mat,1);
6426   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6427   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6428   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6429   MatCheckPreallocated(mat,1);
6430 
6431   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6432   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6433   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6434   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6435   PetscFunctionReturn(0);
6436 }
6437 
6438 /*@C
6439    MatGetSize - Returns the numbers of rows and columns in a matrix.
6440 
6441    Not Collective
6442 
6443    Input Parameter:
6444 .  mat - the matrix
6445 
6446    Output Parameters:
6447 +  m - the number of global rows
6448 -  n - the number of global columns
6449 
6450    Note: both output parameters can be NULL on input.
6451 
6452    Level: beginner
6453 
6454    Concepts: matrices^size
6455 
6456 .seealso: MatGetLocalSize()
6457 @*/
6458 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6459 {
6460   PetscFunctionBegin;
6461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6462   if (m) *m = mat->rmap->N;
6463   if (n) *n = mat->cmap->N;
6464   PetscFunctionReturn(0);
6465 }
6466 
6467 /*@C
6468    MatGetLocalSize - Returns the number of rows and columns in a matrix
6469    stored locally.  This information may be implementation dependent, so
6470    use with care.
6471 
6472    Not Collective
6473 
6474    Input Parameters:
6475 .  mat - the matrix
6476 
6477    Output Parameters:
6478 +  m - the number of local rows
6479 -  n - the number of local columns
6480 
6481    Note: both output parameters can be NULL on input.
6482 
6483    Level: beginner
6484 
6485    Concepts: matrices^local size
6486 
6487 .seealso: MatGetSize()
6488 @*/
6489 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6490 {
6491   PetscFunctionBegin;
6492   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6493   if (m) PetscValidIntPointer(m,2);
6494   if (n) PetscValidIntPointer(n,3);
6495   if (m) *m = mat->rmap->n;
6496   if (n) *n = mat->cmap->n;
6497   PetscFunctionReturn(0);
6498 }
6499 
6500 /*@C
6501    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6502    this processor. (The columns of the "diagonal block")
6503 
6504    Not Collective, unless matrix has not been allocated, then collective on Mat
6505 
6506    Input Parameters:
6507 .  mat - the matrix
6508 
6509    Output Parameters:
6510 +  m - the global index of the first local column
6511 -  n - one more than the global index of the last local column
6512 
6513    Notes:
6514     both output parameters can be NULL on input.
6515 
6516    Level: developer
6517 
6518    Concepts: matrices^column ownership
6519 
6520 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6521 
6522 @*/
6523 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6524 {
6525   PetscFunctionBegin;
6526   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6527   PetscValidType(mat,1);
6528   if (m) PetscValidIntPointer(m,2);
6529   if (n) PetscValidIntPointer(n,3);
6530   MatCheckPreallocated(mat,1);
6531   if (m) *m = mat->cmap->rstart;
6532   if (n) *n = mat->cmap->rend;
6533   PetscFunctionReturn(0);
6534 }
6535 
6536 /*@C
6537    MatGetOwnershipRange - Returns the range of matrix rows owned by
6538    this processor, assuming that the matrix is laid out with the first
6539    n1 rows on the first processor, the next n2 rows on the second, etc.
6540    For certain parallel layouts this range may not be well defined.
6541 
6542    Not Collective
6543 
6544    Input Parameters:
6545 .  mat - the matrix
6546 
6547    Output Parameters:
6548 +  m - the global index of the first local row
6549 -  n - one more than the global index of the last local row
6550 
6551    Note: Both output parameters can be NULL on input.
6552 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6553 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6554 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6555 
6556    Level: beginner
6557 
6558    Concepts: matrices^row ownership
6559 
6560 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6561 
6562 @*/
6563 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6564 {
6565   PetscFunctionBegin;
6566   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6567   PetscValidType(mat,1);
6568   if (m) PetscValidIntPointer(m,2);
6569   if (n) PetscValidIntPointer(n,3);
6570   MatCheckPreallocated(mat,1);
6571   if (m) *m = mat->rmap->rstart;
6572   if (n) *n = mat->rmap->rend;
6573   PetscFunctionReturn(0);
6574 }
6575 
6576 /*@C
6577    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6578    each process
6579 
6580    Not Collective, unless matrix has not been allocated, then collective on Mat
6581 
6582    Input Parameters:
6583 .  mat - the matrix
6584 
6585    Output Parameters:
6586 .  ranges - start of each processors portion plus one more than the total length at the end
6587 
6588    Level: beginner
6589 
6590    Concepts: matrices^row ownership
6591 
6592 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6593 
6594 @*/
6595 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6596 {
6597   PetscErrorCode ierr;
6598 
6599   PetscFunctionBegin;
6600   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6601   PetscValidType(mat,1);
6602   MatCheckPreallocated(mat,1);
6603   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6604   PetscFunctionReturn(0);
6605 }
6606 
6607 /*@C
6608    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6609    this processor. (The columns of the "diagonal blocks" for each process)
6610 
6611    Not Collective, unless matrix has not been allocated, then collective on Mat
6612 
6613    Input Parameters:
6614 .  mat - the matrix
6615 
6616    Output Parameters:
6617 .  ranges - start of each processors portion plus one more then the total length at the end
6618 
6619    Level: beginner
6620 
6621    Concepts: matrices^column ownership
6622 
6623 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6624 
6625 @*/
6626 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6627 {
6628   PetscErrorCode ierr;
6629 
6630   PetscFunctionBegin;
6631   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6632   PetscValidType(mat,1);
6633   MatCheckPreallocated(mat,1);
6634   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6635   PetscFunctionReturn(0);
6636 }
6637 
6638 /*@C
6639    MatGetOwnershipIS - Get row and column ownership as index sets
6640 
6641    Not Collective
6642 
6643    Input Arguments:
6644 .  A - matrix of type Elemental
6645 
6646    Output Arguments:
6647 +  rows - rows in which this process owns elements
6648 .  cols - columns in which this process owns elements
6649 
6650    Level: intermediate
6651 
6652 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6653 @*/
6654 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6655 {
6656   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6657 
6658   PetscFunctionBegin;
6659   MatCheckPreallocated(A,1);
6660   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6661   if (f) {
6662     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6663   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6664     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6665     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6666   }
6667   PetscFunctionReturn(0);
6668 }
6669 
6670 /*@C
6671    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6672    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6673    to complete the factorization.
6674 
6675    Collective on Mat
6676 
6677    Input Parameters:
6678 +  mat - the matrix
6679 .  row - row permutation
6680 .  column - column permutation
6681 -  info - structure containing
6682 $      levels - number of levels of fill.
6683 $      expected fill - as ratio of original fill.
6684 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6685                 missing diagonal entries)
6686 
6687    Output Parameters:
6688 .  fact - new matrix that has been symbolically factored
6689 
6690    Notes:
6691     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6692 
6693    Most users should employ the simplified KSP interface for linear solvers
6694    instead of working directly with matrix algebra routines such as this.
6695    See, e.g., KSPCreate().
6696 
6697    Level: developer
6698 
6699   Concepts: matrices^symbolic LU factorization
6700   Concepts: matrices^factorization
6701   Concepts: LU^symbolic factorization
6702 
6703 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6704           MatGetOrdering(), MatFactorInfo
6705 
6706     Note: this uses the definition of level of fill as in Y. Saad, 2003
6707 
6708     Developer Note: fortran interface is not autogenerated as the f90
6709     interface defintion cannot be generated correctly [due to MatFactorInfo]
6710 
6711    References:
6712      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6713 @*/
6714 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6715 {
6716   PetscErrorCode ierr;
6717 
6718   PetscFunctionBegin;
6719   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6720   PetscValidType(mat,1);
6721   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6722   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6723   PetscValidPointer(info,4);
6724   PetscValidPointer(fact,5);
6725   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6726   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6727   if (!(fact)->ops->ilufactorsymbolic) {
6728     MatSolverType spackage;
6729     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6730     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6731   }
6732   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6733   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6734   MatCheckPreallocated(mat,2);
6735 
6736   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6737   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6738   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6739   PetscFunctionReturn(0);
6740 }
6741 
6742 /*@C
6743    MatICCFactorSymbolic - Performs symbolic incomplete
6744    Cholesky factorization for a symmetric matrix.  Use
6745    MatCholeskyFactorNumeric() to complete the factorization.
6746 
6747    Collective on Mat
6748 
6749    Input Parameters:
6750 +  mat - the matrix
6751 .  perm - row and column permutation
6752 -  info - structure containing
6753 $      levels - number of levels of fill.
6754 $      expected fill - as ratio of original fill.
6755 
6756    Output Parameter:
6757 .  fact - the factored matrix
6758 
6759    Notes:
6760    Most users should employ the KSP interface for linear solvers
6761    instead of working directly with matrix algebra routines such as this.
6762    See, e.g., KSPCreate().
6763 
6764    Level: developer
6765 
6766   Concepts: matrices^symbolic incomplete Cholesky factorization
6767   Concepts: matrices^factorization
6768   Concepts: Cholsky^symbolic factorization
6769 
6770 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6771 
6772     Note: this uses the definition of level of fill as in Y. Saad, 2003
6773 
6774     Developer Note: fortran interface is not autogenerated as the f90
6775     interface defintion cannot be generated correctly [due to MatFactorInfo]
6776 
6777    References:
6778      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6779 @*/
6780 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6781 {
6782   PetscErrorCode ierr;
6783 
6784   PetscFunctionBegin;
6785   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6786   PetscValidType(mat,1);
6787   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6788   PetscValidPointer(info,3);
6789   PetscValidPointer(fact,4);
6790   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6791   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6792   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6793   if (!(fact)->ops->iccfactorsymbolic) {
6794     MatSolverType spackage;
6795     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6796     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6797   }
6798   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6799   MatCheckPreallocated(mat,2);
6800 
6801   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6802   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6803   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6804   PetscFunctionReturn(0);
6805 }
6806 
6807 /*@C
6808    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6809    points to an array of valid matrices, they may be reused to store the new
6810    submatrices.
6811 
6812    Collective on Mat
6813 
6814    Input Parameters:
6815 +  mat - the matrix
6816 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6817 .  irow, icol - index sets of rows and columns to extract
6818 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6819 
6820    Output Parameter:
6821 .  submat - the array of submatrices
6822 
6823    Notes:
6824    MatCreateSubMatrices() can extract ONLY sequential submatrices
6825    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6826    to extract a parallel submatrix.
6827 
6828    Some matrix types place restrictions on the row and column
6829    indices, such as that they be sorted or that they be equal to each other.
6830 
6831    The index sets may not have duplicate entries.
6832 
6833    When extracting submatrices from a parallel matrix, each processor can
6834    form a different submatrix by setting the rows and columns of its
6835    individual index sets according to the local submatrix desired.
6836 
6837    When finished using the submatrices, the user should destroy
6838    them with MatDestroySubMatrices().
6839 
6840    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6841    original matrix has not changed from that last call to MatCreateSubMatrices().
6842 
6843    This routine creates the matrices in submat; you should NOT create them before
6844    calling it. It also allocates the array of matrix pointers submat.
6845 
6846    For BAIJ matrices the index sets must respect the block structure, that is if they
6847    request one row/column in a block, they must request all rows/columns that are in
6848    that block. For example, if the block size is 2 you cannot request just row 0 and
6849    column 0.
6850 
6851    Fortran Note:
6852    The Fortran interface is slightly different from that given below; it
6853    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6854 
6855    Level: advanced
6856 
6857    Concepts: matrices^accessing submatrices
6858    Concepts: submatrices
6859 
6860 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6861 @*/
6862 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6863 {
6864   PetscErrorCode ierr;
6865   PetscInt       i;
6866   PetscBool      eq;
6867 
6868   PetscFunctionBegin;
6869   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6870   PetscValidType(mat,1);
6871   if (n) {
6872     PetscValidPointer(irow,3);
6873     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6874     PetscValidPointer(icol,4);
6875     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6876   }
6877   PetscValidPointer(submat,6);
6878   if (n && scall == MAT_REUSE_MATRIX) {
6879     PetscValidPointer(*submat,6);
6880     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6881   }
6882   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6883   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6884   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6885   MatCheckPreallocated(mat,1);
6886 
6887   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6888   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6889   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6890   for (i=0; i<n; i++) {
6891     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6892     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6893       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6894       if (eq) {
6895         if (mat->symmetric) {
6896           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6897         } else if (mat->hermitian) {
6898           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6899         } else if (mat->structurally_symmetric) {
6900           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6901         }
6902       }
6903     }
6904   }
6905   PetscFunctionReturn(0);
6906 }
6907 
6908 /*@C
6909    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6910 
6911    Collective on Mat
6912 
6913    Input Parameters:
6914 +  mat - the matrix
6915 .  n   - the number of submatrixes to be extracted
6916 .  irow, icol - index sets of rows and columns to extract
6917 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6918 
6919    Output Parameter:
6920 .  submat - the array of submatrices
6921 
6922    Level: advanced
6923 
6924    Concepts: matrices^accessing submatrices
6925    Concepts: submatrices
6926 
6927 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6928 @*/
6929 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6930 {
6931   PetscErrorCode ierr;
6932   PetscInt       i;
6933   PetscBool      eq;
6934 
6935   PetscFunctionBegin;
6936   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6937   PetscValidType(mat,1);
6938   if (n) {
6939     PetscValidPointer(irow,3);
6940     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6941     PetscValidPointer(icol,4);
6942     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6943   }
6944   PetscValidPointer(submat,6);
6945   if (n && scall == MAT_REUSE_MATRIX) {
6946     PetscValidPointer(*submat,6);
6947     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6948   }
6949   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6950   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6951   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6952   MatCheckPreallocated(mat,1);
6953 
6954   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6955   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6956   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6957   for (i=0; i<n; i++) {
6958     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6959       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6960       if (eq) {
6961         if (mat->symmetric) {
6962           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6963         } else if (mat->hermitian) {
6964           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6965         } else if (mat->structurally_symmetric) {
6966           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6967         }
6968       }
6969     }
6970   }
6971   PetscFunctionReturn(0);
6972 }
6973 
6974 /*@C
6975    MatDestroyMatrices - Destroys an array of matrices.
6976 
6977    Collective on Mat
6978 
6979    Input Parameters:
6980 +  n - the number of local matrices
6981 -  mat - the matrices (note that this is a pointer to the array of matrices)
6982 
6983    Level: advanced
6984 
6985     Notes:
6986     Frees not only the matrices, but also the array that contains the matrices
6987            In Fortran will not free the array.
6988 
6989 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6990 @*/
6991 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6992 {
6993   PetscErrorCode ierr;
6994   PetscInt       i;
6995 
6996   PetscFunctionBegin;
6997   if (!*mat) PetscFunctionReturn(0);
6998   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6999   PetscValidPointer(mat,2);
7000 
7001   for (i=0; i<n; i++) {
7002     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7003   }
7004 
7005   /* memory is allocated even if n = 0 */
7006   ierr = PetscFree(*mat);CHKERRQ(ierr);
7007   PetscFunctionReturn(0);
7008 }
7009 
7010 /*@C
7011    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7012 
7013    Collective on Mat
7014 
7015    Input Parameters:
7016 +  n - the number of local matrices
7017 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7018                        sequence of MatCreateSubMatrices())
7019 
7020    Level: advanced
7021 
7022     Notes:
7023     Frees not only the matrices, but also the array that contains the matrices
7024            In Fortran will not free the array.
7025 
7026 .seealso: MatCreateSubMatrices()
7027 @*/
7028 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7029 {
7030   PetscErrorCode ierr;
7031   Mat            mat0;
7032 
7033   PetscFunctionBegin;
7034   if (!*mat) PetscFunctionReturn(0);
7035   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7036   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7037   PetscValidPointer(mat,2);
7038 
7039   mat0 = (*mat)[0];
7040   if (mat0 && mat0->ops->destroysubmatrices) {
7041     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7042   } else {
7043     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7044   }
7045   PetscFunctionReturn(0);
7046 }
7047 
7048 /*@C
7049    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7050 
7051    Collective on Mat
7052 
7053    Input Parameters:
7054 .  mat - the matrix
7055 
7056    Output Parameter:
7057 .  matstruct - the sequential matrix with the nonzero structure of mat
7058 
7059   Level: intermediate
7060 
7061 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7062 @*/
7063 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7064 {
7065   PetscErrorCode ierr;
7066 
7067   PetscFunctionBegin;
7068   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7069   PetscValidPointer(matstruct,2);
7070 
7071   PetscValidType(mat,1);
7072   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7073   MatCheckPreallocated(mat,1);
7074 
7075   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7076   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7077   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7078   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7079   PetscFunctionReturn(0);
7080 }
7081 
7082 /*@C
7083    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7084 
7085    Collective on Mat
7086 
7087    Input Parameters:
7088 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7089                        sequence of MatGetSequentialNonzeroStructure())
7090 
7091    Level: advanced
7092 
7093     Notes:
7094     Frees not only the matrices, but also the array that contains the matrices
7095 
7096 .seealso: MatGetSeqNonzeroStructure()
7097 @*/
7098 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7099 {
7100   PetscErrorCode ierr;
7101 
7102   PetscFunctionBegin;
7103   PetscValidPointer(mat,1);
7104   ierr = MatDestroy(mat);CHKERRQ(ierr);
7105   PetscFunctionReturn(0);
7106 }
7107 
7108 /*@
7109    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7110    replaces the index sets by larger ones that represent submatrices with
7111    additional overlap.
7112 
7113    Collective on Mat
7114 
7115    Input Parameters:
7116 +  mat - the matrix
7117 .  n   - the number of index sets
7118 .  is  - the array of index sets (these index sets will changed during the call)
7119 -  ov  - the additional overlap requested
7120 
7121    Options Database:
7122 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7123 
7124    Level: developer
7125 
7126    Concepts: overlap
7127    Concepts: ASM^computing overlap
7128 
7129 .seealso: MatCreateSubMatrices()
7130 @*/
7131 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7132 {
7133   PetscErrorCode ierr;
7134 
7135   PetscFunctionBegin;
7136   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7137   PetscValidType(mat,1);
7138   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7139   if (n) {
7140     PetscValidPointer(is,3);
7141     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7142   }
7143   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7144   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7145   MatCheckPreallocated(mat,1);
7146 
7147   if (!ov) PetscFunctionReturn(0);
7148   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7149   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7150   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7151   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7152   PetscFunctionReturn(0);
7153 }
7154 
7155 
7156 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7157 
7158 /*@
7159    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7160    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7161    additional overlap.
7162 
7163    Collective on Mat
7164 
7165    Input Parameters:
7166 +  mat - the matrix
7167 .  n   - the number of index sets
7168 .  is  - the array of index sets (these index sets will changed during the call)
7169 -  ov  - the additional overlap requested
7170 
7171    Options Database:
7172 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7173 
7174    Level: developer
7175 
7176    Concepts: overlap
7177    Concepts: ASM^computing overlap
7178 
7179 .seealso: MatCreateSubMatrices()
7180 @*/
7181 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7182 {
7183   PetscInt       i;
7184   PetscErrorCode ierr;
7185 
7186   PetscFunctionBegin;
7187   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7188   PetscValidType(mat,1);
7189   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7190   if (n) {
7191     PetscValidPointer(is,3);
7192     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7193   }
7194   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7195   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7196   MatCheckPreallocated(mat,1);
7197   if (!ov) PetscFunctionReturn(0);
7198   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7199   for(i=0; i<n; i++){
7200 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7201   }
7202   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7203   PetscFunctionReturn(0);
7204 }
7205 
7206 
7207 
7208 
7209 /*@
7210    MatGetBlockSize - Returns the matrix block size.
7211 
7212    Not Collective
7213 
7214    Input Parameter:
7215 .  mat - the matrix
7216 
7217    Output Parameter:
7218 .  bs - block size
7219 
7220    Notes:
7221     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7222 
7223    If the block size has not been set yet this routine returns 1.
7224 
7225    Level: intermediate
7226 
7227    Concepts: matrices^block size
7228 
7229 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7230 @*/
7231 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7232 {
7233   PetscFunctionBegin;
7234   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7235   PetscValidIntPointer(bs,2);
7236   *bs = PetscAbs(mat->rmap->bs);
7237   PetscFunctionReturn(0);
7238 }
7239 
7240 /*@
7241    MatGetBlockSizes - Returns the matrix block row and column sizes.
7242 
7243    Not Collective
7244 
7245    Input Parameter:
7246 .  mat - the matrix
7247 
7248    Output Parameter:
7249 .  rbs - row block size
7250 .  cbs - column block size
7251 
7252    Notes:
7253     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7254     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7255 
7256    If a block size has not been set yet this routine returns 1.
7257 
7258    Level: intermediate
7259 
7260    Concepts: matrices^block size
7261 
7262 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7263 @*/
7264 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7265 {
7266   PetscFunctionBegin;
7267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7268   if (rbs) PetscValidIntPointer(rbs,2);
7269   if (cbs) PetscValidIntPointer(cbs,3);
7270   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7271   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7272   PetscFunctionReturn(0);
7273 }
7274 
7275 /*@
7276    MatSetBlockSize - Sets the matrix block size.
7277 
7278    Logically Collective on Mat
7279 
7280    Input Parameters:
7281 +  mat - the matrix
7282 -  bs - block size
7283 
7284    Notes:
7285     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7286     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7287 
7288     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7289     is compatible with the matrix local sizes.
7290 
7291    Level: intermediate
7292 
7293    Concepts: matrices^block size
7294 
7295 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7296 @*/
7297 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7298 {
7299   PetscErrorCode ierr;
7300 
7301   PetscFunctionBegin;
7302   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7303   PetscValidLogicalCollectiveInt(mat,bs,2);
7304   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7305   PetscFunctionReturn(0);
7306 }
7307 
7308 /*@
7309    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7310 
7311    Logically Collective on Mat
7312 
7313    Input Parameters:
7314 +  mat - the matrix
7315 .  nblocks - the number of blocks on this process
7316 -  bsizes - the block sizes
7317 
7318    Notes:
7319     Currently used by PCVPBJACOBI for SeqAIJ matrices
7320 
7321    Level: intermediate
7322 
7323    Concepts: matrices^block size
7324 
7325 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7326 @*/
7327 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7328 {
7329   PetscErrorCode ierr;
7330   PetscInt       i,ncnt = 0, nlocal;
7331 
7332   PetscFunctionBegin;
7333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7334   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7335   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7336   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7337   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);
7338   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7339   mat->nblocks = nblocks;
7340   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7341   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7342   PetscFunctionReturn(0);
7343 }
7344 
7345 /*@C
7346    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7347 
7348    Logically Collective on Mat
7349 
7350    Input Parameters:
7351 .  mat - the matrix
7352 
7353    Output Parameters:
7354 +  nblocks - the number of blocks on this process
7355 -  bsizes - the block sizes
7356 
7357    Notes: Currently not supported from Fortran
7358 
7359    Level: intermediate
7360 
7361    Concepts: matrices^block size
7362 
7363 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7364 @*/
7365 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7366 {
7367   PetscFunctionBegin;
7368   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7369   *nblocks = mat->nblocks;
7370   *bsizes  = mat->bsizes;
7371   PetscFunctionReturn(0);
7372 }
7373 
7374 /*@
7375    MatSetBlockSizes - Sets the matrix block row and column sizes.
7376 
7377    Logically Collective on Mat
7378 
7379    Input Parameters:
7380 +  mat - the matrix
7381 -  rbs - row block size
7382 -  cbs - column block size
7383 
7384    Notes:
7385     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7386     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7387     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7388 
7389     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7390     are compatible with the matrix local sizes.
7391 
7392     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7393 
7394    Level: intermediate
7395 
7396    Concepts: matrices^block size
7397 
7398 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7399 @*/
7400 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7401 {
7402   PetscErrorCode ierr;
7403 
7404   PetscFunctionBegin;
7405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7406   PetscValidLogicalCollectiveInt(mat,rbs,2);
7407   PetscValidLogicalCollectiveInt(mat,cbs,3);
7408   if (mat->ops->setblocksizes) {
7409     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7410   }
7411   if (mat->rmap->refcnt) {
7412     ISLocalToGlobalMapping l2g = NULL;
7413     PetscLayout            nmap = NULL;
7414 
7415     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7416     if (mat->rmap->mapping) {
7417       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7418     }
7419     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7420     mat->rmap = nmap;
7421     mat->rmap->mapping = l2g;
7422   }
7423   if (mat->cmap->refcnt) {
7424     ISLocalToGlobalMapping l2g = NULL;
7425     PetscLayout            nmap = NULL;
7426 
7427     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7428     if (mat->cmap->mapping) {
7429       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7430     }
7431     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7432     mat->cmap = nmap;
7433     mat->cmap->mapping = l2g;
7434   }
7435   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7436   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7437   PetscFunctionReturn(0);
7438 }
7439 
7440 /*@
7441    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7442 
7443    Logically Collective on Mat
7444 
7445    Input Parameters:
7446 +  mat - the matrix
7447 .  fromRow - matrix from which to copy row block size
7448 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7449 
7450    Level: developer
7451 
7452    Concepts: matrices^block size
7453 
7454 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7455 @*/
7456 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7457 {
7458   PetscErrorCode ierr;
7459 
7460   PetscFunctionBegin;
7461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7462   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7463   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7464   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7465   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7466   PetscFunctionReturn(0);
7467 }
7468 
7469 /*@
7470    MatResidual - Default routine to calculate the residual.
7471 
7472    Collective on Mat and Vec
7473 
7474    Input Parameters:
7475 +  mat - the matrix
7476 .  b   - the right-hand-side
7477 -  x   - the approximate solution
7478 
7479    Output Parameter:
7480 .  r - location to store the residual
7481 
7482    Level: developer
7483 
7484 .keywords: MG, default, multigrid, residual
7485 
7486 .seealso: PCMGSetResidual()
7487 @*/
7488 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7489 {
7490   PetscErrorCode ierr;
7491 
7492   PetscFunctionBegin;
7493   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7494   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7495   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7496   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7497   PetscValidType(mat,1);
7498   MatCheckPreallocated(mat,1);
7499   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7500   if (!mat->ops->residual) {
7501     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7502     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7503   } else {
7504     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7505   }
7506   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7507   PetscFunctionReturn(0);
7508 }
7509 
7510 /*@C
7511     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7512 
7513    Collective on Mat
7514 
7515     Input Parameters:
7516 +   mat - the matrix
7517 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7518 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7519 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7520                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7521                  always used.
7522 
7523     Output Parameters:
7524 +   n - number of rows in the (possibly compressed) matrix
7525 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7526 .   ja - the column indices
7527 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7528            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7529 
7530     Level: developer
7531 
7532     Notes:
7533     You CANNOT change any of the ia[] or ja[] values.
7534 
7535     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7536 
7537     Fortran Notes:
7538     In Fortran use
7539 $
7540 $      PetscInt ia(1), ja(1)
7541 $      PetscOffset iia, jja
7542 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7543 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7544 
7545      or
7546 $
7547 $    PetscInt, pointer :: ia(:),ja(:)
7548 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7549 $    ! Access the ith and jth entries via ia(i) and ja(j)
7550 
7551 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7552 @*/
7553 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7554 {
7555   PetscErrorCode ierr;
7556 
7557   PetscFunctionBegin;
7558   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7559   PetscValidType(mat,1);
7560   PetscValidIntPointer(n,5);
7561   if (ia) PetscValidIntPointer(ia,6);
7562   if (ja) PetscValidIntPointer(ja,7);
7563   PetscValidIntPointer(done,8);
7564   MatCheckPreallocated(mat,1);
7565   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7566   else {
7567     *done = PETSC_TRUE;
7568     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7569     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7570     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7571   }
7572   PetscFunctionReturn(0);
7573 }
7574 
7575 /*@C
7576     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7577 
7578     Collective on Mat
7579 
7580     Input Parameters:
7581 +   mat - the matrix
7582 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7583 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7584                 symmetrized
7585 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7586                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7587                  always used.
7588 .   n - number of columns in the (possibly compressed) matrix
7589 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7590 -   ja - the row indices
7591 
7592     Output Parameters:
7593 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7594 
7595     Level: developer
7596 
7597 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7598 @*/
7599 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7600 {
7601   PetscErrorCode ierr;
7602 
7603   PetscFunctionBegin;
7604   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7605   PetscValidType(mat,1);
7606   PetscValidIntPointer(n,4);
7607   if (ia) PetscValidIntPointer(ia,5);
7608   if (ja) PetscValidIntPointer(ja,6);
7609   PetscValidIntPointer(done,7);
7610   MatCheckPreallocated(mat,1);
7611   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7612   else {
7613     *done = PETSC_TRUE;
7614     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7615   }
7616   PetscFunctionReturn(0);
7617 }
7618 
7619 /*@C
7620     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7621     MatGetRowIJ().
7622 
7623     Collective on Mat
7624 
7625     Input Parameters:
7626 +   mat - the matrix
7627 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7628 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7629                 symmetrized
7630 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7631                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7632                  always used.
7633 .   n - size of (possibly compressed) matrix
7634 .   ia - the row pointers
7635 -   ja - the column indices
7636 
7637     Output Parameters:
7638 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7639 
7640     Note:
7641     This routine zeros out n, ia, and ja. This is to prevent accidental
7642     us of the array after it has been restored. If you pass NULL, it will
7643     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7644 
7645     Level: developer
7646 
7647 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7648 @*/
7649 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7650 {
7651   PetscErrorCode ierr;
7652 
7653   PetscFunctionBegin;
7654   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7655   PetscValidType(mat,1);
7656   if (ia) PetscValidIntPointer(ia,6);
7657   if (ja) PetscValidIntPointer(ja,7);
7658   PetscValidIntPointer(done,8);
7659   MatCheckPreallocated(mat,1);
7660 
7661   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7662   else {
7663     *done = PETSC_TRUE;
7664     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7665     if (n)  *n = 0;
7666     if (ia) *ia = NULL;
7667     if (ja) *ja = NULL;
7668   }
7669   PetscFunctionReturn(0);
7670 }
7671 
7672 /*@C
7673     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7674     MatGetColumnIJ().
7675 
7676     Collective on Mat
7677 
7678     Input Parameters:
7679 +   mat - the matrix
7680 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7681 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7682                 symmetrized
7683 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7684                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7685                  always used.
7686 
7687     Output Parameters:
7688 +   n - size of (possibly compressed) matrix
7689 .   ia - the column pointers
7690 .   ja - the row indices
7691 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7692 
7693     Level: developer
7694 
7695 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7696 @*/
7697 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7698 {
7699   PetscErrorCode ierr;
7700 
7701   PetscFunctionBegin;
7702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7703   PetscValidType(mat,1);
7704   if (ia) PetscValidIntPointer(ia,5);
7705   if (ja) PetscValidIntPointer(ja,6);
7706   PetscValidIntPointer(done,7);
7707   MatCheckPreallocated(mat,1);
7708 
7709   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7710   else {
7711     *done = PETSC_TRUE;
7712     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7713     if (n)  *n = 0;
7714     if (ia) *ia = NULL;
7715     if (ja) *ja = NULL;
7716   }
7717   PetscFunctionReturn(0);
7718 }
7719 
7720 /*@C
7721     MatColoringPatch -Used inside matrix coloring routines that
7722     use MatGetRowIJ() and/or MatGetColumnIJ().
7723 
7724     Collective on Mat
7725 
7726     Input Parameters:
7727 +   mat - the matrix
7728 .   ncolors - max color value
7729 .   n   - number of entries in colorarray
7730 -   colorarray - array indicating color for each column
7731 
7732     Output Parameters:
7733 .   iscoloring - coloring generated using colorarray information
7734 
7735     Level: developer
7736 
7737 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7738 
7739 @*/
7740 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7741 {
7742   PetscErrorCode ierr;
7743 
7744   PetscFunctionBegin;
7745   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7746   PetscValidType(mat,1);
7747   PetscValidIntPointer(colorarray,4);
7748   PetscValidPointer(iscoloring,5);
7749   MatCheckPreallocated(mat,1);
7750 
7751   if (!mat->ops->coloringpatch) {
7752     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7753   } else {
7754     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7755   }
7756   PetscFunctionReturn(0);
7757 }
7758 
7759 
7760 /*@
7761    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7762 
7763    Logically Collective on Mat
7764 
7765    Input Parameter:
7766 .  mat - the factored matrix to be reset
7767 
7768    Notes:
7769    This routine should be used only with factored matrices formed by in-place
7770    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7771    format).  This option can save memory, for example, when solving nonlinear
7772    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7773    ILU(0) preconditioner.
7774 
7775    Note that one can specify in-place ILU(0) factorization by calling
7776 .vb
7777      PCType(pc,PCILU);
7778      PCFactorSeUseInPlace(pc);
7779 .ve
7780    or by using the options -pc_type ilu -pc_factor_in_place
7781 
7782    In-place factorization ILU(0) can also be used as a local
7783    solver for the blocks within the block Jacobi or additive Schwarz
7784    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7785    for details on setting local solver options.
7786 
7787    Most users should employ the simplified KSP interface for linear solvers
7788    instead of working directly with matrix algebra routines such as this.
7789    See, e.g., KSPCreate().
7790 
7791    Level: developer
7792 
7793 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7794 
7795    Concepts: matrices^unfactored
7796 
7797 @*/
7798 PetscErrorCode MatSetUnfactored(Mat mat)
7799 {
7800   PetscErrorCode ierr;
7801 
7802   PetscFunctionBegin;
7803   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7804   PetscValidType(mat,1);
7805   MatCheckPreallocated(mat,1);
7806   mat->factortype = MAT_FACTOR_NONE;
7807   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7808   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7809   PetscFunctionReturn(0);
7810 }
7811 
7812 /*MC
7813     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7814 
7815     Synopsis:
7816     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7817 
7818     Not collective
7819 
7820     Input Parameter:
7821 .   x - matrix
7822 
7823     Output Parameters:
7824 +   xx_v - the Fortran90 pointer to the array
7825 -   ierr - error code
7826 
7827     Example of Usage:
7828 .vb
7829       PetscScalar, pointer xx_v(:,:)
7830       ....
7831       call MatDenseGetArrayF90(x,xx_v,ierr)
7832       a = xx_v(3)
7833       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7834 .ve
7835 
7836     Level: advanced
7837 
7838 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7839 
7840     Concepts: matrices^accessing array
7841 
7842 M*/
7843 
7844 /*MC
7845     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7846     accessed with MatDenseGetArrayF90().
7847 
7848     Synopsis:
7849     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7850 
7851     Not collective
7852 
7853     Input Parameters:
7854 +   x - matrix
7855 -   xx_v - the Fortran90 pointer to the array
7856 
7857     Output Parameter:
7858 .   ierr - error code
7859 
7860     Example of Usage:
7861 .vb
7862        PetscScalar, pointer xx_v(:,:)
7863        ....
7864        call MatDenseGetArrayF90(x,xx_v,ierr)
7865        a = xx_v(3)
7866        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7867 .ve
7868 
7869     Level: advanced
7870 
7871 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7872 
7873 M*/
7874 
7875 
7876 /*MC
7877     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7878 
7879     Synopsis:
7880     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7881 
7882     Not collective
7883 
7884     Input Parameter:
7885 .   x - matrix
7886 
7887     Output Parameters:
7888 +   xx_v - the Fortran90 pointer to the array
7889 -   ierr - error code
7890 
7891     Example of Usage:
7892 .vb
7893       PetscScalar, pointer xx_v(:)
7894       ....
7895       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7896       a = xx_v(3)
7897       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7898 .ve
7899 
7900     Level: advanced
7901 
7902 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7903 
7904     Concepts: matrices^accessing array
7905 
7906 M*/
7907 
7908 /*MC
7909     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7910     accessed with MatSeqAIJGetArrayF90().
7911 
7912     Synopsis:
7913     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7914 
7915     Not collective
7916 
7917     Input Parameters:
7918 +   x - matrix
7919 -   xx_v - the Fortran90 pointer to the array
7920 
7921     Output Parameter:
7922 .   ierr - error code
7923 
7924     Example of Usage:
7925 .vb
7926        PetscScalar, pointer xx_v(:)
7927        ....
7928        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7929        a = xx_v(3)
7930        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7931 .ve
7932 
7933     Level: advanced
7934 
7935 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7936 
7937 M*/
7938 
7939 
7940 /*@
7941     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7942                       as the original matrix.
7943 
7944     Collective on Mat
7945 
7946     Input Parameters:
7947 +   mat - the original matrix
7948 .   isrow - parallel IS containing the rows this processor should obtain
7949 .   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.
7950 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7951 
7952     Output Parameter:
7953 .   newmat - the new submatrix, of the same type as the old
7954 
7955     Level: advanced
7956 
7957     Notes:
7958     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7959 
7960     Some matrix types place restrictions on the row and column indices, such
7961     as that they be sorted or that they be equal to each other.
7962 
7963     The index sets may not have duplicate entries.
7964 
7965       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7966    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7967    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7968    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7969    you are finished using it.
7970 
7971     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7972     the input matrix.
7973 
7974     If iscol is NULL then all columns are obtained (not supported in Fortran).
7975 
7976    Example usage:
7977    Consider the following 8x8 matrix with 34 non-zero values, that is
7978    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7979    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7980    as follows:
7981 
7982 .vb
7983             1  2  0  |  0  3  0  |  0  4
7984     Proc0   0  5  6  |  7  0  0  |  8  0
7985             9  0 10  | 11  0  0  | 12  0
7986     -------------------------------------
7987            13  0 14  | 15 16 17  |  0  0
7988     Proc1   0 18  0  | 19 20 21  |  0  0
7989             0  0  0  | 22 23  0  | 24  0
7990     -------------------------------------
7991     Proc2  25 26 27  |  0  0 28  | 29  0
7992            30  0  0  | 31 32 33  |  0 34
7993 .ve
7994 
7995     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7996 
7997 .vb
7998             2  0  |  0  3  0  |  0
7999     Proc0   5  6  |  7  0  0  |  8
8000     -------------------------------
8001     Proc1  18  0  | 19 20 21  |  0
8002     -------------------------------
8003     Proc2  26 27  |  0  0 28  | 29
8004             0  0  | 31 32 33  |  0
8005 .ve
8006 
8007 
8008     Concepts: matrices^submatrices
8009 
8010 .seealso: MatCreateSubMatrices()
8011 @*/
8012 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8013 {
8014   PetscErrorCode ierr;
8015   PetscMPIInt    size;
8016   Mat            *local;
8017   IS             iscoltmp;
8018 
8019   PetscFunctionBegin;
8020   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8021   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8022   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8023   PetscValidPointer(newmat,5);
8024   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8025   PetscValidType(mat,1);
8026   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8027   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8028 
8029   MatCheckPreallocated(mat,1);
8030   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8031 
8032   if (!iscol || isrow == iscol) {
8033     PetscBool   stride;
8034     PetscMPIInt grabentirematrix = 0,grab;
8035     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8036     if (stride) {
8037       PetscInt first,step,n,rstart,rend;
8038       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8039       if (step == 1) {
8040         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8041         if (rstart == first) {
8042           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8043           if (n == rend-rstart) {
8044             grabentirematrix = 1;
8045           }
8046         }
8047       }
8048     }
8049     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8050     if (grab) {
8051       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8052       if (cll == MAT_INITIAL_MATRIX) {
8053         *newmat = mat;
8054         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8055       }
8056       PetscFunctionReturn(0);
8057     }
8058   }
8059 
8060   if (!iscol) {
8061     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8062   } else {
8063     iscoltmp = iscol;
8064   }
8065 
8066   /* if original matrix is on just one processor then use submatrix generated */
8067   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8068     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8069     goto setproperties;
8070   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8071     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8072     *newmat = *local;
8073     ierr    = PetscFree(local);CHKERRQ(ierr);
8074     goto setproperties;
8075   } else if (!mat->ops->createsubmatrix) {
8076     /* Create a new matrix type that implements the operation using the full matrix */
8077     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8078     switch (cll) {
8079     case MAT_INITIAL_MATRIX:
8080       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8081       break;
8082     case MAT_REUSE_MATRIX:
8083       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8084       break;
8085     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8086     }
8087     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8088     goto setproperties;
8089   }
8090 
8091   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8092   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8093   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8094   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8095 
8096   /* Propagate symmetry information for diagonal blocks */
8097 setproperties:
8098   if (isrow == iscoltmp) {
8099     if (mat->symmetric_set && mat->symmetric) {
8100       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8101     }
8102     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8103       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8104     }
8105     if (mat->hermitian_set && mat->hermitian) {
8106       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8107     }
8108     if (mat->spd_set && mat->spd) {
8109       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8110     }
8111   }
8112 
8113   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8114   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8115   PetscFunctionReturn(0);
8116 }
8117 
8118 /*@
8119    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8120    used during the assembly process to store values that belong to
8121    other processors.
8122 
8123    Not Collective
8124 
8125    Input Parameters:
8126 +  mat   - the matrix
8127 .  size  - the initial size of the stash.
8128 -  bsize - the initial size of the block-stash(if used).
8129 
8130    Options Database Keys:
8131 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8132 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8133 
8134    Level: intermediate
8135 
8136    Notes:
8137      The block-stash is used for values set with MatSetValuesBlocked() while
8138      the stash is used for values set with MatSetValues()
8139 
8140      Run with the option -info and look for output of the form
8141      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8142      to determine the appropriate value, MM, to use for size and
8143      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8144      to determine the value, BMM to use for bsize
8145 
8146    Concepts: stash^setting matrix size
8147    Concepts: matrices^stash
8148 
8149 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8150 
8151 @*/
8152 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8153 {
8154   PetscErrorCode ierr;
8155 
8156   PetscFunctionBegin;
8157   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8158   PetscValidType(mat,1);
8159   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8160   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8161   PetscFunctionReturn(0);
8162 }
8163 
8164 /*@
8165    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8166      the matrix
8167 
8168    Neighbor-wise Collective on Mat
8169 
8170    Input Parameters:
8171 +  mat   - the matrix
8172 .  x,y - the vectors
8173 -  w - where the result is stored
8174 
8175    Level: intermediate
8176 
8177    Notes:
8178     w may be the same vector as y.
8179 
8180     This allows one to use either the restriction or interpolation (its transpose)
8181     matrix to do the interpolation
8182 
8183     Concepts: interpolation
8184 
8185 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8186 
8187 @*/
8188 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8189 {
8190   PetscErrorCode ierr;
8191   PetscInt       M,N,Ny;
8192 
8193   PetscFunctionBegin;
8194   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8195   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8196   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8197   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8198   PetscValidType(A,1);
8199   MatCheckPreallocated(A,1);
8200   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8201   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8202   if (M == Ny) {
8203     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8204   } else {
8205     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8206   }
8207   PetscFunctionReturn(0);
8208 }
8209 
8210 /*@
8211    MatInterpolate - y = A*x or A'*x depending on the shape of
8212      the matrix
8213 
8214    Neighbor-wise Collective on Mat
8215 
8216    Input Parameters:
8217 +  mat   - the matrix
8218 -  x,y - the vectors
8219 
8220    Level: intermediate
8221 
8222    Notes:
8223     This allows one to use either the restriction or interpolation (its transpose)
8224     matrix to do the interpolation
8225 
8226    Concepts: matrices^interpolation
8227 
8228 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8229 
8230 @*/
8231 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8232 {
8233   PetscErrorCode ierr;
8234   PetscInt       M,N,Ny;
8235 
8236   PetscFunctionBegin;
8237   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8238   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8239   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8240   PetscValidType(A,1);
8241   MatCheckPreallocated(A,1);
8242   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8243   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8244   if (M == Ny) {
8245     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8246   } else {
8247     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8248   }
8249   PetscFunctionReturn(0);
8250 }
8251 
8252 /*@
8253    MatRestrict - y = A*x or A'*x
8254 
8255    Neighbor-wise Collective on Mat
8256 
8257    Input Parameters:
8258 +  mat   - the matrix
8259 -  x,y - the vectors
8260 
8261    Level: intermediate
8262 
8263    Notes:
8264     This allows one to use either the restriction or interpolation (its transpose)
8265     matrix to do the restriction
8266 
8267    Concepts: matrices^restriction
8268 
8269 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8270 
8271 @*/
8272 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8273 {
8274   PetscErrorCode ierr;
8275   PetscInt       M,N,Ny;
8276 
8277   PetscFunctionBegin;
8278   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8279   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8280   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8281   PetscValidType(A,1);
8282   MatCheckPreallocated(A,1);
8283 
8284   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8285   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8286   if (M == Ny) {
8287     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8288   } else {
8289     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8290   }
8291   PetscFunctionReturn(0);
8292 }
8293 
8294 /*@
8295    MatGetNullSpace - retrieves the null space of a matrix.
8296 
8297    Logically Collective on Mat and MatNullSpace
8298 
8299    Input Parameters:
8300 +  mat - the matrix
8301 -  nullsp - the null space object
8302 
8303    Level: developer
8304 
8305    Concepts: null space^attaching to matrix
8306 
8307 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8308 @*/
8309 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8310 {
8311   PetscFunctionBegin;
8312   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8313   PetscValidPointer(nullsp,2);
8314   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8315   PetscFunctionReturn(0);
8316 }
8317 
8318 /*@
8319    MatSetNullSpace - attaches a null space to a matrix.
8320 
8321    Logically Collective on Mat and MatNullSpace
8322 
8323    Input Parameters:
8324 +  mat - the matrix
8325 -  nullsp - the null space object
8326 
8327    Level: advanced
8328 
8329    Notes:
8330       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8331 
8332       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8333       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8334 
8335       You can remove the null space by calling this routine with an nullsp of NULL
8336 
8337 
8338       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8339    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).
8340    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
8341    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
8342    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).
8343 
8344       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8345 
8346     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
8347     routine also automatically calls MatSetTransposeNullSpace().
8348 
8349    Concepts: null space^attaching to matrix
8350 
8351 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8352 @*/
8353 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8354 {
8355   PetscErrorCode ierr;
8356 
8357   PetscFunctionBegin;
8358   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8359   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8360   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8361   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8362   mat->nullsp = nullsp;
8363   if (mat->symmetric_set && mat->symmetric) {
8364     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8365   }
8366   PetscFunctionReturn(0);
8367 }
8368 
8369 /*@
8370    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8371 
8372    Logically Collective on Mat and MatNullSpace
8373 
8374    Input Parameters:
8375 +  mat - the matrix
8376 -  nullsp - the null space object
8377 
8378    Level: developer
8379 
8380    Concepts: null space^attaching to matrix
8381 
8382 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8383 @*/
8384 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8385 {
8386   PetscFunctionBegin;
8387   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8388   PetscValidType(mat,1);
8389   PetscValidPointer(nullsp,2);
8390   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8391   PetscFunctionReturn(0);
8392 }
8393 
8394 /*@
8395    MatSetTransposeNullSpace - attaches a null space to a matrix.
8396 
8397    Logically Collective on Mat and MatNullSpace
8398 
8399    Input Parameters:
8400 +  mat - the matrix
8401 -  nullsp - the null space object
8402 
8403    Level: advanced
8404 
8405    Notes:
8406       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.
8407       You must also call MatSetNullSpace()
8408 
8409 
8410       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8411    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).
8412    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
8413    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
8414    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).
8415 
8416       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8417 
8418    Concepts: null space^attaching to matrix
8419 
8420 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8421 @*/
8422 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8423 {
8424   PetscErrorCode ierr;
8425 
8426   PetscFunctionBegin;
8427   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8428   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8429   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8430   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8431   mat->transnullsp = nullsp;
8432   PetscFunctionReturn(0);
8433 }
8434 
8435 /*@
8436    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8437         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8438 
8439    Logically Collective on Mat and MatNullSpace
8440 
8441    Input Parameters:
8442 +  mat - the matrix
8443 -  nullsp - the null space object
8444 
8445    Level: advanced
8446 
8447    Notes:
8448       Overwrites any previous near null space that may have been attached
8449 
8450       You can remove the null space by calling this routine with an nullsp of NULL
8451 
8452    Concepts: null space^attaching to matrix
8453 
8454 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8455 @*/
8456 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8457 {
8458   PetscErrorCode ierr;
8459 
8460   PetscFunctionBegin;
8461   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8462   PetscValidType(mat,1);
8463   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8464   MatCheckPreallocated(mat,1);
8465   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8466   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8467   mat->nearnullsp = nullsp;
8468   PetscFunctionReturn(0);
8469 }
8470 
8471 /*@
8472    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8473 
8474    Not Collective
8475 
8476    Input Parameters:
8477 .  mat - the matrix
8478 
8479    Output Parameters:
8480 .  nullsp - the null space object, NULL if not set
8481 
8482    Level: developer
8483 
8484    Concepts: null space^attaching to matrix
8485 
8486 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8487 @*/
8488 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8489 {
8490   PetscFunctionBegin;
8491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8492   PetscValidType(mat,1);
8493   PetscValidPointer(nullsp,2);
8494   MatCheckPreallocated(mat,1);
8495   *nullsp = mat->nearnullsp;
8496   PetscFunctionReturn(0);
8497 }
8498 
8499 /*@C
8500    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8501 
8502    Collective on Mat
8503 
8504    Input Parameters:
8505 +  mat - the matrix
8506 .  row - row/column permutation
8507 .  fill - expected fill factor >= 1.0
8508 -  level - level of fill, for ICC(k)
8509 
8510    Notes:
8511    Probably really in-place only when level of fill is zero, otherwise allocates
8512    new space to store factored matrix and deletes previous memory.
8513 
8514    Most users should employ the simplified KSP interface for linear solvers
8515    instead of working directly with matrix algebra routines such as this.
8516    See, e.g., KSPCreate().
8517 
8518    Level: developer
8519 
8520    Concepts: matrices^incomplete Cholesky factorization
8521    Concepts: Cholesky factorization
8522 
8523 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8524 
8525     Developer Note: fortran interface is not autogenerated as the f90
8526     interface defintion cannot be generated correctly [due to MatFactorInfo]
8527 
8528 @*/
8529 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8530 {
8531   PetscErrorCode ierr;
8532 
8533   PetscFunctionBegin;
8534   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8535   PetscValidType(mat,1);
8536   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8537   PetscValidPointer(info,3);
8538   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8539   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8540   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8541   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8542   MatCheckPreallocated(mat,1);
8543   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8544   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8545   PetscFunctionReturn(0);
8546 }
8547 
8548 /*@
8549    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8550          ghosted ones.
8551 
8552    Not Collective
8553 
8554    Input Parameters:
8555 +  mat - the matrix
8556 -  diag = the diagonal values, including ghost ones
8557 
8558    Level: developer
8559 
8560    Notes:
8561     Works only for MPIAIJ and MPIBAIJ matrices
8562 
8563 .seealso: MatDiagonalScale()
8564 @*/
8565 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8566 {
8567   PetscErrorCode ierr;
8568   PetscMPIInt    size;
8569 
8570   PetscFunctionBegin;
8571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8572   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8573   PetscValidType(mat,1);
8574 
8575   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8576   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8577   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8578   if (size == 1) {
8579     PetscInt n,m;
8580     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8581     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8582     if (m == n) {
8583       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8584     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8585   } else {
8586     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8587   }
8588   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8589   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8590   PetscFunctionReturn(0);
8591 }
8592 
8593 /*@
8594    MatGetInertia - Gets the inertia from a factored matrix
8595 
8596    Collective on Mat
8597 
8598    Input Parameter:
8599 .  mat - the matrix
8600 
8601    Output Parameters:
8602 +   nneg - number of negative eigenvalues
8603 .   nzero - number of zero eigenvalues
8604 -   npos - number of positive eigenvalues
8605 
8606    Level: advanced
8607 
8608    Notes:
8609     Matrix must have been factored by MatCholeskyFactor()
8610 
8611 
8612 @*/
8613 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8614 {
8615   PetscErrorCode ierr;
8616 
8617   PetscFunctionBegin;
8618   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8619   PetscValidType(mat,1);
8620   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8621   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8622   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8623   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8624   PetscFunctionReturn(0);
8625 }
8626 
8627 /* ----------------------------------------------------------------*/
8628 /*@C
8629    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8630 
8631    Neighbor-wise Collective on Mat and Vecs
8632 
8633    Input Parameters:
8634 +  mat - the factored matrix
8635 -  b - the right-hand-side vectors
8636 
8637    Output Parameter:
8638 .  x - the result vectors
8639 
8640    Notes:
8641    The vectors b and x cannot be the same.  I.e., one cannot
8642    call MatSolves(A,x,x).
8643 
8644    Notes:
8645    Most users should employ the simplified KSP interface for linear solvers
8646    instead of working directly with matrix algebra routines such as this.
8647    See, e.g., KSPCreate().
8648 
8649    Level: developer
8650 
8651    Concepts: matrices^triangular solves
8652 
8653 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8654 @*/
8655 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8656 {
8657   PetscErrorCode ierr;
8658 
8659   PetscFunctionBegin;
8660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8661   PetscValidType(mat,1);
8662   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8663   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8664   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8665 
8666   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8667   MatCheckPreallocated(mat,1);
8668   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8669   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8670   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8671   PetscFunctionReturn(0);
8672 }
8673 
8674 /*@
8675    MatIsSymmetric - Test whether a matrix is symmetric
8676 
8677    Collective on Mat
8678 
8679    Input Parameter:
8680 +  A - the matrix to test
8681 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8682 
8683    Output Parameters:
8684 .  flg - the result
8685 
8686    Notes:
8687     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8688 
8689    Level: intermediate
8690 
8691    Concepts: matrix^symmetry
8692 
8693 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8694 @*/
8695 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8696 {
8697   PetscErrorCode ierr;
8698 
8699   PetscFunctionBegin;
8700   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8701   PetscValidPointer(flg,2);
8702 
8703   if (!A->symmetric_set) {
8704     if (!A->ops->issymmetric) {
8705       MatType mattype;
8706       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8707       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8708     }
8709     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8710     if (!tol) {
8711       A->symmetric_set = PETSC_TRUE;
8712       A->symmetric     = *flg;
8713       if (A->symmetric) {
8714         A->structurally_symmetric_set = PETSC_TRUE;
8715         A->structurally_symmetric     = PETSC_TRUE;
8716       }
8717     }
8718   } else if (A->symmetric) {
8719     *flg = PETSC_TRUE;
8720   } else if (!tol) {
8721     *flg = PETSC_FALSE;
8722   } else {
8723     if (!A->ops->issymmetric) {
8724       MatType mattype;
8725       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8726       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8727     }
8728     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8729   }
8730   PetscFunctionReturn(0);
8731 }
8732 
8733 /*@
8734    MatIsHermitian - Test whether a matrix is Hermitian
8735 
8736    Collective on Mat
8737 
8738    Input Parameter:
8739 +  A - the matrix to test
8740 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8741 
8742    Output Parameters:
8743 .  flg - the result
8744 
8745    Level: intermediate
8746 
8747    Concepts: matrix^symmetry
8748 
8749 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8750           MatIsSymmetricKnown(), MatIsSymmetric()
8751 @*/
8752 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8753 {
8754   PetscErrorCode ierr;
8755 
8756   PetscFunctionBegin;
8757   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8758   PetscValidPointer(flg,2);
8759 
8760   if (!A->hermitian_set) {
8761     if (!A->ops->ishermitian) {
8762       MatType mattype;
8763       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8764       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8765     }
8766     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8767     if (!tol) {
8768       A->hermitian_set = PETSC_TRUE;
8769       A->hermitian     = *flg;
8770       if (A->hermitian) {
8771         A->structurally_symmetric_set = PETSC_TRUE;
8772         A->structurally_symmetric     = PETSC_TRUE;
8773       }
8774     }
8775   } else if (A->hermitian) {
8776     *flg = PETSC_TRUE;
8777   } else if (!tol) {
8778     *flg = PETSC_FALSE;
8779   } else {
8780     if (!A->ops->ishermitian) {
8781       MatType mattype;
8782       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8783       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8784     }
8785     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8786   }
8787   PetscFunctionReturn(0);
8788 }
8789 
8790 /*@
8791    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8792 
8793    Not Collective
8794 
8795    Input Parameter:
8796 .  A - the matrix to check
8797 
8798    Output Parameters:
8799 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8800 -  flg - the result
8801 
8802    Level: advanced
8803 
8804    Concepts: matrix^symmetry
8805 
8806    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8807          if you want it explicitly checked
8808 
8809 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8810 @*/
8811 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8812 {
8813   PetscFunctionBegin;
8814   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8815   PetscValidPointer(set,2);
8816   PetscValidPointer(flg,3);
8817   if (A->symmetric_set) {
8818     *set = PETSC_TRUE;
8819     *flg = A->symmetric;
8820   } else {
8821     *set = PETSC_FALSE;
8822   }
8823   PetscFunctionReturn(0);
8824 }
8825 
8826 /*@
8827    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8828 
8829    Not Collective
8830 
8831    Input Parameter:
8832 .  A - the matrix to check
8833 
8834    Output Parameters:
8835 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8836 -  flg - the result
8837 
8838    Level: advanced
8839 
8840    Concepts: matrix^symmetry
8841 
8842    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8843          if you want it explicitly checked
8844 
8845 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8846 @*/
8847 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8848 {
8849   PetscFunctionBegin;
8850   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8851   PetscValidPointer(set,2);
8852   PetscValidPointer(flg,3);
8853   if (A->hermitian_set) {
8854     *set = PETSC_TRUE;
8855     *flg = A->hermitian;
8856   } else {
8857     *set = PETSC_FALSE;
8858   }
8859   PetscFunctionReturn(0);
8860 }
8861 
8862 /*@
8863    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8864 
8865    Collective on Mat
8866 
8867    Input Parameter:
8868 .  A - the matrix to test
8869 
8870    Output Parameters:
8871 .  flg - the result
8872 
8873    Level: intermediate
8874 
8875    Concepts: matrix^symmetry
8876 
8877 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8878 @*/
8879 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8880 {
8881   PetscErrorCode ierr;
8882 
8883   PetscFunctionBegin;
8884   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8885   PetscValidPointer(flg,2);
8886   if (!A->structurally_symmetric_set) {
8887     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8888     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8889 
8890     A->structurally_symmetric_set = PETSC_TRUE;
8891   }
8892   *flg = A->structurally_symmetric;
8893   PetscFunctionReturn(0);
8894 }
8895 
8896 /*@
8897    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8898        to be communicated to other processors during the MatAssemblyBegin/End() process
8899 
8900     Not collective
8901 
8902    Input Parameter:
8903 .   vec - the vector
8904 
8905    Output Parameters:
8906 +   nstash   - the size of the stash
8907 .   reallocs - the number of additional mallocs incurred.
8908 .   bnstash   - the size of the block stash
8909 -   breallocs - the number of additional mallocs incurred.in the block stash
8910 
8911    Level: advanced
8912 
8913 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8914 
8915 @*/
8916 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8917 {
8918   PetscErrorCode ierr;
8919 
8920   PetscFunctionBegin;
8921   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8922   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8923   PetscFunctionReturn(0);
8924 }
8925 
8926 /*@C
8927    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8928      parallel layout
8929 
8930    Collective on Mat
8931 
8932    Input Parameter:
8933 .  mat - the matrix
8934 
8935    Output Parameter:
8936 +   right - (optional) vector that the matrix can be multiplied against
8937 -   left - (optional) vector that the matrix vector product can be stored in
8938 
8939    Notes:
8940     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().
8941 
8942   Notes:
8943     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8944 
8945   Level: advanced
8946 
8947 .seealso: MatCreate(), VecDestroy()
8948 @*/
8949 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8950 {
8951   PetscErrorCode ierr;
8952 
8953   PetscFunctionBegin;
8954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8955   PetscValidType(mat,1);
8956   if (mat->ops->getvecs) {
8957     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8958   } else {
8959     PetscInt rbs,cbs;
8960     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8961     if (right) {
8962       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8963       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8964       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8965       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8966       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8967       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8968     }
8969     if (left) {
8970       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8971       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8972       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8973       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8974       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8975       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8976     }
8977   }
8978   PetscFunctionReturn(0);
8979 }
8980 
8981 /*@C
8982    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8983      with default values.
8984 
8985    Not Collective
8986 
8987    Input Parameters:
8988 .    info - the MatFactorInfo data structure
8989 
8990 
8991    Notes:
8992     The solvers are generally used through the KSP and PC objects, for example
8993           PCLU, PCILU, PCCHOLESKY, PCICC
8994 
8995    Level: developer
8996 
8997 .seealso: MatFactorInfo
8998 
8999     Developer Note: fortran interface is not autogenerated as the f90
9000     interface defintion cannot be generated correctly [due to MatFactorInfo]
9001 
9002 @*/
9003 
9004 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9005 {
9006   PetscErrorCode ierr;
9007 
9008   PetscFunctionBegin;
9009   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9010   PetscFunctionReturn(0);
9011 }
9012 
9013 /*@
9014    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9015 
9016    Collective on Mat
9017 
9018    Input Parameters:
9019 +  mat - the factored matrix
9020 -  is - the index set defining the Schur indices (0-based)
9021 
9022    Notes:
9023     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9024 
9025    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9026 
9027    Level: developer
9028 
9029    Concepts:
9030 
9031 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9032           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9033 
9034 @*/
9035 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9036 {
9037   PetscErrorCode ierr,(*f)(Mat,IS);
9038 
9039   PetscFunctionBegin;
9040   PetscValidType(mat,1);
9041   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9042   PetscValidType(is,2);
9043   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9044   PetscCheckSameComm(mat,1,is,2);
9045   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9046   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9047   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");
9048   if (mat->schur) {
9049     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9050   }
9051   ierr = (*f)(mat,is);CHKERRQ(ierr);
9052   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9053   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9054   PetscFunctionReturn(0);
9055 }
9056 
9057 /*@
9058   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9059 
9060    Logically Collective on Mat
9061 
9062    Input Parameters:
9063 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9064 .  S - location where to return the Schur complement, can be NULL
9065 -  status - the status of the Schur complement matrix, can be NULL
9066 
9067    Notes:
9068    You must call MatFactorSetSchurIS() before calling this routine.
9069 
9070    The routine provides a copy of the Schur matrix stored within the solver data structures.
9071    The caller must destroy the object when it is no longer needed.
9072    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9073 
9074    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)
9075 
9076    Developer Notes:
9077     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9078    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9079 
9080    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9081 
9082    Level: advanced
9083 
9084    References:
9085 
9086 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9087 @*/
9088 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9089 {
9090   PetscErrorCode ierr;
9091 
9092   PetscFunctionBegin;
9093   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9094   if (S) PetscValidPointer(S,2);
9095   if (status) PetscValidPointer(status,3);
9096   if (S) {
9097     PetscErrorCode (*f)(Mat,Mat*);
9098 
9099     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9100     if (f) {
9101       ierr = (*f)(F,S);CHKERRQ(ierr);
9102     } else {
9103       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9104     }
9105   }
9106   if (status) *status = F->schur_status;
9107   PetscFunctionReturn(0);
9108 }
9109 
9110 /*@
9111   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9112 
9113    Logically Collective on Mat
9114 
9115    Input Parameters:
9116 +  F - the factored matrix obtained by calling MatGetFactor()
9117 .  *S - location where to return the Schur complement, can be NULL
9118 -  status - the status of the Schur complement matrix, can be NULL
9119 
9120    Notes:
9121    You must call MatFactorSetSchurIS() before calling this routine.
9122 
9123    Schur complement mode is currently implemented for sequential matrices.
9124    The routine returns a the Schur Complement stored within the data strutures of the solver.
9125    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9126    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9127 
9128    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9129 
9130    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9131 
9132    Level: advanced
9133 
9134    References:
9135 
9136 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9137 @*/
9138 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9139 {
9140   PetscFunctionBegin;
9141   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9142   if (S) PetscValidPointer(S,2);
9143   if (status) PetscValidPointer(status,3);
9144   if (S) *S = F->schur;
9145   if (status) *status = F->schur_status;
9146   PetscFunctionReturn(0);
9147 }
9148 
9149 /*@
9150   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9151 
9152    Logically Collective on Mat
9153 
9154    Input Parameters:
9155 +  F - the factored matrix obtained by calling MatGetFactor()
9156 .  *S - location where the Schur complement is stored
9157 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9158 
9159    Notes:
9160 
9161    Level: advanced
9162 
9163    References:
9164 
9165 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9166 @*/
9167 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9168 {
9169   PetscErrorCode ierr;
9170 
9171   PetscFunctionBegin;
9172   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9173   if (S) {
9174     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9175     *S = NULL;
9176   }
9177   F->schur_status = status;
9178   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9179   PetscFunctionReturn(0);
9180 }
9181 
9182 /*@
9183   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9184 
9185    Logically Collective on Mat
9186 
9187    Input Parameters:
9188 +  F - the factored matrix obtained by calling MatGetFactor()
9189 .  rhs - location where the right hand side of the Schur complement system is stored
9190 -  sol - location where the solution of the Schur complement system has to be returned
9191 
9192    Notes:
9193    The sizes of the vectors should match the size of the Schur complement
9194 
9195    Must be called after MatFactorSetSchurIS()
9196 
9197    Level: advanced
9198 
9199    References:
9200 
9201 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9202 @*/
9203 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9204 {
9205   PetscErrorCode ierr;
9206 
9207   PetscFunctionBegin;
9208   PetscValidType(F,1);
9209   PetscValidType(rhs,2);
9210   PetscValidType(sol,3);
9211   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9212   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9213   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9214   PetscCheckSameComm(F,1,rhs,2);
9215   PetscCheckSameComm(F,1,sol,3);
9216   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9217   switch (F->schur_status) {
9218   case MAT_FACTOR_SCHUR_FACTORED:
9219     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9220     break;
9221   case MAT_FACTOR_SCHUR_INVERTED:
9222     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9223     break;
9224   default:
9225     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9226     break;
9227   }
9228   PetscFunctionReturn(0);
9229 }
9230 
9231 /*@
9232   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9233 
9234    Logically Collective on Mat
9235 
9236    Input Parameters:
9237 +  F - the factored matrix obtained by calling MatGetFactor()
9238 .  rhs - location where the right hand side of the Schur complement system is stored
9239 -  sol - location where the solution of the Schur complement system has to be returned
9240 
9241    Notes:
9242    The sizes of the vectors should match the size of the Schur complement
9243 
9244    Must be called after MatFactorSetSchurIS()
9245 
9246    Level: advanced
9247 
9248    References:
9249 
9250 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9251 @*/
9252 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9253 {
9254   PetscErrorCode ierr;
9255 
9256   PetscFunctionBegin;
9257   PetscValidType(F,1);
9258   PetscValidType(rhs,2);
9259   PetscValidType(sol,3);
9260   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9261   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9262   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9263   PetscCheckSameComm(F,1,rhs,2);
9264   PetscCheckSameComm(F,1,sol,3);
9265   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9266   switch (F->schur_status) {
9267   case MAT_FACTOR_SCHUR_FACTORED:
9268     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9269     break;
9270   case MAT_FACTOR_SCHUR_INVERTED:
9271     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9272     break;
9273   default:
9274     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9275     break;
9276   }
9277   PetscFunctionReturn(0);
9278 }
9279 
9280 /*@
9281   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9282 
9283    Logically Collective on Mat
9284 
9285    Input Parameters:
9286 +  F - the factored matrix obtained by calling MatGetFactor()
9287 
9288    Notes:
9289     Must be called after MatFactorSetSchurIS().
9290 
9291    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9292 
9293    Level: advanced
9294 
9295    References:
9296 
9297 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9298 @*/
9299 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9300 {
9301   PetscErrorCode ierr;
9302 
9303   PetscFunctionBegin;
9304   PetscValidType(F,1);
9305   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9306   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9307   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9308   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9309   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9310   PetscFunctionReturn(0);
9311 }
9312 
9313 /*@
9314   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9315 
9316    Logically Collective on Mat
9317 
9318    Input Parameters:
9319 +  F - the factored matrix obtained by calling MatGetFactor()
9320 
9321    Notes:
9322     Must be called after MatFactorSetSchurIS().
9323 
9324    Level: advanced
9325 
9326    References:
9327 
9328 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9329 @*/
9330 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9331 {
9332   PetscErrorCode ierr;
9333 
9334   PetscFunctionBegin;
9335   PetscValidType(F,1);
9336   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9337   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9338   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9339   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9340   PetscFunctionReturn(0);
9341 }
9342 
9343 /*@
9344    MatPtAP - Creates the matrix product C = P^T * A * P
9345 
9346    Neighbor-wise Collective on Mat
9347 
9348    Input Parameters:
9349 +  A - the matrix
9350 .  P - the projection matrix
9351 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9352 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9353           if the result is a dense matrix this is irrelevent
9354 
9355    Output Parameters:
9356 .  C - the product matrix
9357 
9358    Notes:
9359    C will be created and must be destroyed by the user with MatDestroy().
9360 
9361    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9362    which inherit from AIJ.
9363 
9364    Level: intermediate
9365 
9366 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9367 @*/
9368 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9369 {
9370   PetscErrorCode ierr;
9371   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9372   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9373   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9374   PetscBool      sametype;
9375 
9376   PetscFunctionBegin;
9377   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9378   PetscValidType(A,1);
9379   MatCheckPreallocated(A,1);
9380   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9381   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9382   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9383   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9384   PetscValidType(P,2);
9385   MatCheckPreallocated(P,2);
9386   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9387   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9388 
9389   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);
9390   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);
9391   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9392   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9393 
9394   if (scall == MAT_REUSE_MATRIX) {
9395     PetscValidPointer(*C,5);
9396     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9397 
9398     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9399     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9400     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9401     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9402     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9403     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9404     PetscFunctionReturn(0);
9405   }
9406 
9407   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9408   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9409 
9410   fA = A->ops->ptap;
9411   fP = P->ops->ptap;
9412   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9413   if (fP == fA && sametype) {
9414     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9415     ptap = fA;
9416   } else {
9417     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9418     char ptapname[256];
9419     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9420     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9421     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9422     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9423     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9424     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9425     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);
9426   }
9427 
9428   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9429   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9430   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9431   if (A->symmetric_set && A->symmetric) {
9432     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9433   }
9434   PetscFunctionReturn(0);
9435 }
9436 
9437 /*@
9438    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9439 
9440    Neighbor-wise Collective on Mat
9441 
9442    Input Parameters:
9443 +  A - the matrix
9444 -  P - the projection matrix
9445 
9446    Output Parameters:
9447 .  C - the product matrix
9448 
9449    Notes:
9450    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9451    the user using MatDeatroy().
9452 
9453    This routine is currently only implemented for pairs of AIJ matrices and classes
9454    which inherit from AIJ.  C will be of type MATAIJ.
9455 
9456    Level: intermediate
9457 
9458 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9459 @*/
9460 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9461 {
9462   PetscErrorCode ierr;
9463 
9464   PetscFunctionBegin;
9465   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9466   PetscValidType(A,1);
9467   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9468   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9469   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9470   PetscValidType(P,2);
9471   MatCheckPreallocated(P,2);
9472   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9473   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9474   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9475   PetscValidType(C,3);
9476   MatCheckPreallocated(C,3);
9477   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9478   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);
9479   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);
9480   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);
9481   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);
9482   MatCheckPreallocated(A,1);
9483 
9484   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9485   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9486   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9487   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9488   PetscFunctionReturn(0);
9489 }
9490 
9491 /*@
9492    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9493 
9494    Neighbor-wise Collective on Mat
9495 
9496    Input Parameters:
9497 +  A - the matrix
9498 -  P - the projection matrix
9499 
9500    Output Parameters:
9501 .  C - the (i,j) structure of the product matrix
9502 
9503    Notes:
9504    C will be created and must be destroyed by the user with MatDestroy().
9505 
9506    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9507    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9508    this (i,j) structure by calling MatPtAPNumeric().
9509 
9510    Level: intermediate
9511 
9512 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9513 @*/
9514 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9515 {
9516   PetscErrorCode ierr;
9517 
9518   PetscFunctionBegin;
9519   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9520   PetscValidType(A,1);
9521   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9522   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9523   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9524   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9525   PetscValidType(P,2);
9526   MatCheckPreallocated(P,2);
9527   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9528   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9529   PetscValidPointer(C,3);
9530 
9531   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);
9532   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);
9533   MatCheckPreallocated(A,1);
9534 
9535   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9536   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9537   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9538   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9539 
9540   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9541   PetscFunctionReturn(0);
9542 }
9543 
9544 /*@
9545    MatRARt - Creates the matrix product C = R * A * R^T
9546 
9547    Neighbor-wise Collective on Mat
9548 
9549    Input Parameters:
9550 +  A - the matrix
9551 .  R - the projection matrix
9552 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9553 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9554           if the result is a dense matrix this is irrelevent
9555 
9556    Output Parameters:
9557 .  C - the product matrix
9558 
9559    Notes:
9560    C will be created and must be destroyed by the user with MatDestroy().
9561 
9562    This routine is currently only implemented for pairs of AIJ matrices and classes
9563    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9564    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9565    We recommend using MatPtAP().
9566 
9567    Level: intermediate
9568 
9569 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9570 @*/
9571 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9572 {
9573   PetscErrorCode ierr;
9574 
9575   PetscFunctionBegin;
9576   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9577   PetscValidType(A,1);
9578   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9579   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9580   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9581   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9582   PetscValidType(R,2);
9583   MatCheckPreallocated(R,2);
9584   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9585   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9586   PetscValidPointer(C,3);
9587   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);
9588 
9589   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9590   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9591   MatCheckPreallocated(A,1);
9592 
9593   if (!A->ops->rart) {
9594     Mat Rt;
9595     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9596     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9597     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9598     PetscFunctionReturn(0);
9599   }
9600   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9601   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9602   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9603   PetscFunctionReturn(0);
9604 }
9605 
9606 /*@
9607    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9608 
9609    Neighbor-wise Collective on Mat
9610 
9611    Input Parameters:
9612 +  A - the matrix
9613 -  R - the projection matrix
9614 
9615    Output Parameters:
9616 .  C - the product matrix
9617 
9618    Notes:
9619    C must have been created by calling MatRARtSymbolic and must be destroyed by
9620    the user using MatDestroy().
9621 
9622    This routine is currently only implemented for pairs of AIJ matrices and classes
9623    which inherit from AIJ.  C will be of type MATAIJ.
9624 
9625    Level: intermediate
9626 
9627 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9628 @*/
9629 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9630 {
9631   PetscErrorCode ierr;
9632 
9633   PetscFunctionBegin;
9634   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9635   PetscValidType(A,1);
9636   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9637   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9638   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9639   PetscValidType(R,2);
9640   MatCheckPreallocated(R,2);
9641   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9642   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9643   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9644   PetscValidType(C,3);
9645   MatCheckPreallocated(C,3);
9646   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9647   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);
9648   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);
9649   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);
9650   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);
9651   MatCheckPreallocated(A,1);
9652 
9653   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9654   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9655   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9656   PetscFunctionReturn(0);
9657 }
9658 
9659 /*@
9660    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9661 
9662    Neighbor-wise Collective on Mat
9663 
9664    Input Parameters:
9665 +  A - the matrix
9666 -  R - the projection matrix
9667 
9668    Output Parameters:
9669 .  C - the (i,j) structure of the product matrix
9670 
9671    Notes:
9672    C will be created and must be destroyed by the user with MatDestroy().
9673 
9674    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9675    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9676    this (i,j) structure by calling MatRARtNumeric().
9677 
9678    Level: intermediate
9679 
9680 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9681 @*/
9682 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9683 {
9684   PetscErrorCode ierr;
9685 
9686   PetscFunctionBegin;
9687   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9688   PetscValidType(A,1);
9689   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9690   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9691   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9692   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9693   PetscValidType(R,2);
9694   MatCheckPreallocated(R,2);
9695   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9696   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9697   PetscValidPointer(C,3);
9698 
9699   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);
9700   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);
9701   MatCheckPreallocated(A,1);
9702   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9703   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9704   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9705 
9706   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9707   PetscFunctionReturn(0);
9708 }
9709 
9710 /*@
9711    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9712 
9713    Neighbor-wise Collective on Mat
9714 
9715    Input Parameters:
9716 +  A - the left matrix
9717 .  B - the right matrix
9718 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9719 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9720           if the result is a dense matrix this is irrelevent
9721 
9722    Output Parameters:
9723 .  C - the product matrix
9724 
9725    Notes:
9726    Unless scall is MAT_REUSE_MATRIX C will be created.
9727 
9728    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
9729    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9730 
9731    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9732    actually needed.
9733 
9734    If you have many matrices with the same non-zero structure to multiply, you
9735    should either
9736 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9737 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9738    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
9739    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9740 
9741    Level: intermediate
9742 
9743 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9744 @*/
9745 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9746 {
9747   PetscErrorCode ierr;
9748   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9749   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9750   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9751 
9752   PetscFunctionBegin;
9753   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9754   PetscValidType(A,1);
9755   MatCheckPreallocated(A,1);
9756   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9757   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9758   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9759   PetscValidType(B,2);
9760   MatCheckPreallocated(B,2);
9761   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9762   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9763   PetscValidPointer(C,3);
9764   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9765   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);
9766   if (scall == MAT_REUSE_MATRIX) {
9767     PetscValidPointer(*C,5);
9768     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9769     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9770     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9771     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9772     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9773     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9774     PetscFunctionReturn(0);
9775   }
9776   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9777   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9778 
9779   fA = A->ops->matmult;
9780   fB = B->ops->matmult;
9781   if (fB == fA) {
9782     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9783     mult = fB;
9784   } else {
9785     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9786     char multname[256];
9787     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9788     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9789     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9790     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9791     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9792     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9793     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);
9794   }
9795   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9796   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9797   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9798   PetscFunctionReturn(0);
9799 }
9800 
9801 /*@
9802    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9803    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9804 
9805    Neighbor-wise Collective on Mat
9806 
9807    Input Parameters:
9808 +  A - the left matrix
9809 .  B - the right matrix
9810 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9811       if C is a dense matrix this is irrelevent
9812 
9813    Output Parameters:
9814 .  C - the product matrix
9815 
9816    Notes:
9817    Unless scall is MAT_REUSE_MATRIX C will be created.
9818 
9819    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9820    actually needed.
9821 
9822    This routine is currently implemented for
9823     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9824     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9825     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9826 
9827    Level: intermediate
9828 
9829    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9830      We should incorporate them into PETSc.
9831 
9832 .seealso: MatMatMult(), MatMatMultNumeric()
9833 @*/
9834 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9835 {
9836   PetscErrorCode ierr;
9837   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9838   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9839   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9840 
9841   PetscFunctionBegin;
9842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9843   PetscValidType(A,1);
9844   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9845   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9846 
9847   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9848   PetscValidType(B,2);
9849   MatCheckPreallocated(B,2);
9850   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9851   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9852   PetscValidPointer(C,3);
9853 
9854   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);
9855   if (fill == PETSC_DEFAULT) fill = 2.0;
9856   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9857   MatCheckPreallocated(A,1);
9858 
9859   Asymbolic = A->ops->matmultsymbolic;
9860   Bsymbolic = B->ops->matmultsymbolic;
9861   if (Asymbolic == Bsymbolic) {
9862     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9863     symbolic = Bsymbolic;
9864   } else { /* dispatch based on the type of A and B */
9865     char symbolicname[256];
9866     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9867     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9868     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9869     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9870     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9871     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9872     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);
9873   }
9874   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9875   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9876   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9877   PetscFunctionReturn(0);
9878 }
9879 
9880 /*@
9881    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9882    Call this routine after first calling MatMatMultSymbolic().
9883 
9884    Neighbor-wise Collective on Mat
9885 
9886    Input Parameters:
9887 +  A - the left matrix
9888 -  B - the right matrix
9889 
9890    Output Parameters:
9891 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9892 
9893    Notes:
9894    C must have been created with MatMatMultSymbolic().
9895 
9896    This routine is currently implemented for
9897     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9898     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9899     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9900 
9901    Level: intermediate
9902 
9903 .seealso: MatMatMult(), MatMatMultSymbolic()
9904 @*/
9905 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9906 {
9907   PetscErrorCode ierr;
9908 
9909   PetscFunctionBegin;
9910   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9911   PetscFunctionReturn(0);
9912 }
9913 
9914 /*@
9915    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9916 
9917    Neighbor-wise Collective on Mat
9918 
9919    Input Parameters:
9920 +  A - the left matrix
9921 .  B - the right matrix
9922 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9923 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9924 
9925    Output Parameters:
9926 .  C - the product matrix
9927 
9928    Notes:
9929    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9930 
9931    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9932 
9933   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9934    actually needed.
9935 
9936    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9937    and for pairs of MPIDense matrices.
9938 
9939    Options Database Keys:
9940 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9941                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9942                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9943 
9944    Level: intermediate
9945 
9946 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9947 @*/
9948 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9949 {
9950   PetscErrorCode ierr;
9951   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9952   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9953 
9954   PetscFunctionBegin;
9955   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9956   PetscValidType(A,1);
9957   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9958   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9959   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9960   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9961   PetscValidType(B,2);
9962   MatCheckPreallocated(B,2);
9963   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9964   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9965   PetscValidPointer(C,3);
9966   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);
9967   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9968   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9969   MatCheckPreallocated(A,1);
9970 
9971   fA = A->ops->mattransposemult;
9972   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9973   fB = B->ops->mattransposemult;
9974   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9975   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);
9976 
9977   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9978   if (scall == MAT_INITIAL_MATRIX) {
9979     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9980     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9981     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9982   }
9983   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9984   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9985   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9986   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9987   PetscFunctionReturn(0);
9988 }
9989 
9990 /*@
9991    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9992 
9993    Neighbor-wise Collective on Mat
9994 
9995    Input Parameters:
9996 +  A - the left matrix
9997 .  B - the right matrix
9998 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9999 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10000 
10001    Output Parameters:
10002 .  C - the product matrix
10003 
10004    Notes:
10005    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10006 
10007    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10008 
10009   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10010    actually needed.
10011 
10012    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10013    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10014 
10015    Level: intermediate
10016 
10017 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10018 @*/
10019 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10020 {
10021   PetscErrorCode ierr;
10022   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10023   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10024   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10025 
10026   PetscFunctionBegin;
10027   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10028   PetscValidType(A,1);
10029   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10030   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10031   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10032   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10033   PetscValidType(B,2);
10034   MatCheckPreallocated(B,2);
10035   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10036   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10037   PetscValidPointer(C,3);
10038   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);
10039   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10040   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10041   MatCheckPreallocated(A,1);
10042 
10043   fA = A->ops->transposematmult;
10044   fB = B->ops->transposematmult;
10045   if (fB==fA) {
10046     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10047     transposematmult = fA;
10048   } else {
10049     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10050     char multname[256];
10051     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10052     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10053     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10054     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10055     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10056     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10057     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);
10058   }
10059   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10060   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10061   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10062   PetscFunctionReturn(0);
10063 }
10064 
10065 /*@
10066    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10067 
10068    Neighbor-wise Collective on Mat
10069 
10070    Input Parameters:
10071 +  A - the left matrix
10072 .  B - the middle matrix
10073 .  C - the right matrix
10074 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10075 -  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
10076           if the result is a dense matrix this is irrelevent
10077 
10078    Output Parameters:
10079 .  D - the product matrix
10080 
10081    Notes:
10082    Unless scall is MAT_REUSE_MATRIX D will be created.
10083 
10084    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10085 
10086    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10087    actually needed.
10088 
10089    If you have many matrices with the same non-zero structure to multiply, you
10090    should use MAT_REUSE_MATRIX in all calls but the first or
10091 
10092    Level: intermediate
10093 
10094 .seealso: MatMatMult, MatPtAP()
10095 @*/
10096 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10097 {
10098   PetscErrorCode ierr;
10099   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10100   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10101   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10102   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10103 
10104   PetscFunctionBegin;
10105   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10106   PetscValidType(A,1);
10107   MatCheckPreallocated(A,1);
10108   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10109   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10110   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10111   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10112   PetscValidType(B,2);
10113   MatCheckPreallocated(B,2);
10114   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10115   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10116   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10117   PetscValidPointer(C,3);
10118   MatCheckPreallocated(C,3);
10119   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10120   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10121   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);
10122   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);
10123   if (scall == MAT_REUSE_MATRIX) {
10124     PetscValidPointer(*D,6);
10125     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10126     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10127     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10128     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10129     PetscFunctionReturn(0);
10130   }
10131   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10132   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10133 
10134   fA = A->ops->matmatmult;
10135   fB = B->ops->matmatmult;
10136   fC = C->ops->matmatmult;
10137   if (fA == fB && fA == fC) {
10138     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10139     mult = fA;
10140   } else {
10141     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10142     char multname[256];
10143     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10144     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10145     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10146     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10147     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10148     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10149     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10150     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10151     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);
10152   }
10153   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10154   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10155   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10156   PetscFunctionReturn(0);
10157 }
10158 
10159 /*@
10160    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10161 
10162    Collective on Mat
10163 
10164    Input Parameters:
10165 +  mat - the matrix
10166 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10167 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10168 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10169 
10170    Output Parameter:
10171 .  matredundant - redundant matrix
10172 
10173    Notes:
10174    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10175    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10176 
10177    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10178    calling it.
10179 
10180    Level: advanced
10181 
10182    Concepts: subcommunicator
10183    Concepts: duplicate matrix
10184 
10185 .seealso: MatDestroy()
10186 @*/
10187 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10188 {
10189   PetscErrorCode ierr;
10190   MPI_Comm       comm;
10191   PetscMPIInt    size;
10192   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10193   Mat_Redundant  *redund=NULL;
10194   PetscSubcomm   psubcomm=NULL;
10195   MPI_Comm       subcomm_in=subcomm;
10196   Mat            *matseq;
10197   IS             isrow,iscol;
10198   PetscBool      newsubcomm=PETSC_FALSE;
10199 
10200   PetscFunctionBegin;
10201   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10202   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10203     PetscValidPointer(*matredundant,5);
10204     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10205   }
10206 
10207   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10208   if (size == 1 || nsubcomm == 1) {
10209     if (reuse == MAT_INITIAL_MATRIX) {
10210       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10211     } else {
10212       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");
10213       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10214     }
10215     PetscFunctionReturn(0);
10216   }
10217 
10218   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10219   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10220   MatCheckPreallocated(mat,1);
10221 
10222   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10223   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10224     /* create psubcomm, then get subcomm */
10225     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10226     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10227     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10228 
10229     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10230     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10231     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10232     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10233     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10234     newsubcomm = PETSC_TRUE;
10235     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10236   }
10237 
10238   /* get isrow, iscol and a local sequential matrix matseq[0] */
10239   if (reuse == MAT_INITIAL_MATRIX) {
10240     mloc_sub = PETSC_DECIDE;
10241     nloc_sub = PETSC_DECIDE;
10242     if (bs < 1) {
10243       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10244       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10245     } else {
10246       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10247       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10248     }
10249     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10250     rstart = rend - mloc_sub;
10251     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10252     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10253   } else { /* reuse == MAT_REUSE_MATRIX */
10254     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");
10255     /* retrieve subcomm */
10256     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10257     redund = (*matredundant)->redundant;
10258     isrow  = redund->isrow;
10259     iscol  = redund->iscol;
10260     matseq = redund->matseq;
10261   }
10262   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10263 
10264   /* get matredundant over subcomm */
10265   if (reuse == MAT_INITIAL_MATRIX) {
10266     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10267 
10268     /* create a supporting struct and attach it to C for reuse */
10269     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10270     (*matredundant)->redundant = redund;
10271     redund->isrow              = isrow;
10272     redund->iscol              = iscol;
10273     redund->matseq             = matseq;
10274     if (newsubcomm) {
10275       redund->subcomm          = subcomm;
10276     } else {
10277       redund->subcomm          = MPI_COMM_NULL;
10278     }
10279   } else {
10280     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10281   }
10282   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10283   PetscFunctionReturn(0);
10284 }
10285 
10286 /*@C
10287    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10288    a given 'mat' object. Each submatrix can span multiple procs.
10289 
10290    Collective on Mat
10291 
10292    Input Parameters:
10293 +  mat - the matrix
10294 .  subcomm - the subcommunicator obtained by com_split(comm)
10295 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10296 
10297    Output Parameter:
10298 .  subMat - 'parallel submatrices each spans a given subcomm
10299 
10300   Notes:
10301   The submatrix partition across processors is dictated by 'subComm' a
10302   communicator obtained by com_split(comm). The comm_split
10303   is not restriced to be grouped with consecutive original ranks.
10304 
10305   Due the comm_split() usage, the parallel layout of the submatrices
10306   map directly to the layout of the original matrix [wrt the local
10307   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10308   into the 'DiagonalMat' of the subMat, hence it is used directly from
10309   the subMat. However the offDiagMat looses some columns - and this is
10310   reconstructed with MatSetValues()
10311 
10312   Level: advanced
10313 
10314   Concepts: subcommunicator
10315   Concepts: submatrices
10316 
10317 .seealso: MatCreateSubMatrices()
10318 @*/
10319 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10320 {
10321   PetscErrorCode ierr;
10322   PetscMPIInt    commsize,subCommSize;
10323 
10324   PetscFunctionBegin;
10325   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10326   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10327   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10328 
10329   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");
10330   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10331   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10332   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10333   PetscFunctionReturn(0);
10334 }
10335 
10336 /*@
10337    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10338 
10339    Not Collective
10340 
10341    Input Arguments:
10342    mat - matrix to extract local submatrix from
10343    isrow - local row indices for submatrix
10344    iscol - local column indices for submatrix
10345 
10346    Output Arguments:
10347    submat - the submatrix
10348 
10349    Level: intermediate
10350 
10351    Notes:
10352    The submat should be returned with MatRestoreLocalSubMatrix().
10353 
10354    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10355    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10356 
10357    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10358    MatSetValuesBlockedLocal() will also be implemented.
10359 
10360    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10361    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10362 
10363 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10364 @*/
10365 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10366 {
10367   PetscErrorCode ierr;
10368 
10369   PetscFunctionBegin;
10370   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10371   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10372   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10373   PetscCheckSameComm(isrow,2,iscol,3);
10374   PetscValidPointer(submat,4);
10375   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10376 
10377   if (mat->ops->getlocalsubmatrix) {
10378     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10379   } else {
10380     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10381   }
10382   PetscFunctionReturn(0);
10383 }
10384 
10385 /*@
10386    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10387 
10388    Not Collective
10389 
10390    Input Arguments:
10391    mat - matrix to extract local submatrix from
10392    isrow - local row indices for submatrix
10393    iscol - local column indices for submatrix
10394    submat - the submatrix
10395 
10396    Level: intermediate
10397 
10398 .seealso: MatGetLocalSubMatrix()
10399 @*/
10400 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10401 {
10402   PetscErrorCode ierr;
10403 
10404   PetscFunctionBegin;
10405   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10406   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10407   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10408   PetscCheckSameComm(isrow,2,iscol,3);
10409   PetscValidPointer(submat,4);
10410   if (*submat) {
10411     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10412   }
10413 
10414   if (mat->ops->restorelocalsubmatrix) {
10415     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10416   } else {
10417     ierr = MatDestroy(submat);CHKERRQ(ierr);
10418   }
10419   *submat = NULL;
10420   PetscFunctionReturn(0);
10421 }
10422 
10423 /* --------------------------------------------------------*/
10424 /*@
10425    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10426 
10427    Collective on Mat
10428 
10429    Input Parameter:
10430 .  mat - the matrix
10431 
10432    Output Parameter:
10433 .  is - if any rows have zero diagonals this contains the list of them
10434 
10435    Level: developer
10436 
10437    Concepts: matrix-vector product
10438 
10439 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10440 @*/
10441 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10442 {
10443   PetscErrorCode ierr;
10444 
10445   PetscFunctionBegin;
10446   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10447   PetscValidType(mat,1);
10448   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10449   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10450 
10451   if (!mat->ops->findzerodiagonals) {
10452     Vec                diag;
10453     const PetscScalar *a;
10454     PetscInt          *rows;
10455     PetscInt           rStart, rEnd, r, nrow = 0;
10456 
10457     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10458     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10459     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10460     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10461     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10462     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10463     nrow = 0;
10464     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10465     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10466     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10467     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10468   } else {
10469     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10470   }
10471   PetscFunctionReturn(0);
10472 }
10473 
10474 /*@
10475    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10476 
10477    Collective on Mat
10478 
10479    Input Parameter:
10480 .  mat - the matrix
10481 
10482    Output Parameter:
10483 .  is - contains the list of rows with off block diagonal entries
10484 
10485    Level: developer
10486 
10487    Concepts: matrix-vector product
10488 
10489 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10490 @*/
10491 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10492 {
10493   PetscErrorCode ierr;
10494 
10495   PetscFunctionBegin;
10496   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10497   PetscValidType(mat,1);
10498   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10499   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10500 
10501   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10502   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10503   PetscFunctionReturn(0);
10504 }
10505 
10506 /*@C
10507   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10508 
10509   Collective on Mat
10510 
10511   Input Parameters:
10512 . mat - the matrix
10513 
10514   Output Parameters:
10515 . values - the block inverses in column major order (FORTRAN-like)
10516 
10517    Note:
10518    This routine is not available from Fortran.
10519 
10520   Level: advanced
10521 
10522 .seealso: MatInvertBockDiagonalMat
10523 @*/
10524 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10525 {
10526   PetscErrorCode ierr;
10527 
10528   PetscFunctionBegin;
10529   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10530   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10531   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10532   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10533   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10534   PetscFunctionReturn(0);
10535 }
10536 
10537 /*@C
10538   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10539 
10540   Collective on Mat
10541 
10542   Input Parameters:
10543 + mat - the matrix
10544 . nblocks - the number of blocks
10545 - bsizes - the size of each block
10546 
10547   Output Parameters:
10548 . values - the block inverses in column major order (FORTRAN-like)
10549 
10550    Note:
10551    This routine is not available from Fortran.
10552 
10553   Level: advanced
10554 
10555 .seealso: MatInvertBockDiagonal()
10556 @*/
10557 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10558 {
10559   PetscErrorCode ierr;
10560 
10561   PetscFunctionBegin;
10562   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10563   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10564   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10565   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10566   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10567   PetscFunctionReturn(0);
10568 }
10569 
10570 /*@
10571   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10572 
10573   Collective on Mat
10574 
10575   Input Parameters:
10576 . A - the matrix
10577 
10578   Output Parameters:
10579 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10580 
10581   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10582 
10583   Level: advanced
10584 
10585 .seealso: MatInvertBockDiagonal()
10586 @*/
10587 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10588 {
10589   PetscErrorCode     ierr;
10590   const PetscScalar *vals;
10591   PetscInt          *dnnz;
10592   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10593 
10594   PetscFunctionBegin;
10595   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10596   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10597   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10598   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10599   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10600   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10601   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10602   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10603   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10604   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10605   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10606   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10607   for (i = rstart/bs; i < rend/bs; i++) {
10608     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10609   }
10610   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10611   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10612   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10613   PetscFunctionReturn(0);
10614 }
10615 
10616 /*@C
10617     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10618     via MatTransposeColoringCreate().
10619 
10620     Collective on MatTransposeColoring
10621 
10622     Input Parameter:
10623 .   c - coloring context
10624 
10625     Level: intermediate
10626 
10627 .seealso: MatTransposeColoringCreate()
10628 @*/
10629 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10630 {
10631   PetscErrorCode       ierr;
10632   MatTransposeColoring matcolor=*c;
10633 
10634   PetscFunctionBegin;
10635   if (!matcolor) PetscFunctionReturn(0);
10636   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10637 
10638   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10639   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10640   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10641   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10642   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10643   if (matcolor->brows>0) {
10644     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10645   }
10646   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10647   PetscFunctionReturn(0);
10648 }
10649 
10650 /*@C
10651     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10652     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10653     MatTransposeColoring to sparse B.
10654 
10655     Collective on MatTransposeColoring
10656 
10657     Input Parameters:
10658 +   B - sparse matrix B
10659 .   Btdense - symbolic dense matrix B^T
10660 -   coloring - coloring context created with MatTransposeColoringCreate()
10661 
10662     Output Parameter:
10663 .   Btdense - dense matrix B^T
10664 
10665     Level: advanced
10666 
10667      Notes:
10668     These are used internally for some implementations of MatRARt()
10669 
10670 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10671 
10672 .keywords: coloring
10673 @*/
10674 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10675 {
10676   PetscErrorCode ierr;
10677 
10678   PetscFunctionBegin;
10679   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10680   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10681   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10682 
10683   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10684   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10685   PetscFunctionReturn(0);
10686 }
10687 
10688 /*@C
10689     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10690     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10691     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10692     Csp from Cden.
10693 
10694     Collective on MatTransposeColoring
10695 
10696     Input Parameters:
10697 +   coloring - coloring context created with MatTransposeColoringCreate()
10698 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10699 
10700     Output Parameter:
10701 .   Csp - sparse matrix
10702 
10703     Level: advanced
10704 
10705      Notes:
10706     These are used internally for some implementations of MatRARt()
10707 
10708 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10709 
10710 .keywords: coloring
10711 @*/
10712 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10713 {
10714   PetscErrorCode ierr;
10715 
10716   PetscFunctionBegin;
10717   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10718   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10719   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10720 
10721   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10722   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10723   PetscFunctionReturn(0);
10724 }
10725 
10726 /*@C
10727    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10728 
10729    Collective on Mat
10730 
10731    Input Parameters:
10732 +  mat - the matrix product C
10733 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10734 
10735     Output Parameter:
10736 .   color - the new coloring context
10737 
10738     Level: intermediate
10739 
10740 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10741            MatTransColoringApplyDenToSp()
10742 @*/
10743 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10744 {
10745   MatTransposeColoring c;
10746   MPI_Comm             comm;
10747   PetscErrorCode       ierr;
10748 
10749   PetscFunctionBegin;
10750   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10751   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10752   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10753 
10754   c->ctype = iscoloring->ctype;
10755   if (mat->ops->transposecoloringcreate) {
10756     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10757   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10758 
10759   *color = c;
10760   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10761   PetscFunctionReturn(0);
10762 }
10763 
10764 /*@
10765       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10766         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10767         same, otherwise it will be larger
10768 
10769      Not Collective
10770 
10771   Input Parameter:
10772 .    A  - the matrix
10773 
10774   Output Parameter:
10775 .    state - the current state
10776 
10777   Notes:
10778     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10779          different matrices
10780 
10781   Level: intermediate
10782 
10783 @*/
10784 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10785 {
10786   PetscFunctionBegin;
10787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10788   *state = mat->nonzerostate;
10789   PetscFunctionReturn(0);
10790 }
10791 
10792 /*@
10793       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10794                  matrices from each processor
10795 
10796     Collective on MPI_Comm
10797 
10798    Input Parameters:
10799 +    comm - the communicators the parallel matrix will live on
10800 .    seqmat - the input sequential matrices
10801 .    n - number of local columns (or PETSC_DECIDE)
10802 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10803 
10804    Output Parameter:
10805 .    mpimat - the parallel matrix generated
10806 
10807     Level: advanced
10808 
10809    Notes:
10810     The number of columns of the matrix in EACH processor MUST be the same.
10811 
10812 @*/
10813 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10814 {
10815   PetscErrorCode ierr;
10816 
10817   PetscFunctionBegin;
10818   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10819   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");
10820 
10821   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10822   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10823   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10824   PetscFunctionReturn(0);
10825 }
10826 
10827 /*@
10828      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10829                  ranks' ownership ranges.
10830 
10831     Collective on A
10832 
10833    Input Parameters:
10834 +    A   - the matrix to create subdomains from
10835 -    N   - requested number of subdomains
10836 
10837 
10838    Output Parameters:
10839 +    n   - number of subdomains resulting on this rank
10840 -    iss - IS list with indices of subdomains on this rank
10841 
10842     Level: advanced
10843 
10844     Notes:
10845     number of subdomains must be smaller than the communicator size
10846 @*/
10847 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10848 {
10849   MPI_Comm        comm,subcomm;
10850   PetscMPIInt     size,rank,color;
10851   PetscInt        rstart,rend,k;
10852   PetscErrorCode  ierr;
10853 
10854   PetscFunctionBegin;
10855   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10856   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10857   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10858   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);
10859   *n = 1;
10860   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10861   color = rank/k;
10862   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10863   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10864   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10865   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10866   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10867   PetscFunctionReturn(0);
10868 }
10869 
10870 /*@
10871    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10872 
10873    If the interpolation and restriction operators are the same, uses MatPtAP.
10874    If they are not the same, use MatMatMatMult.
10875 
10876    Once the coarse grid problem is constructed, correct for interpolation operators
10877    that are not of full rank, which can legitimately happen in the case of non-nested
10878    geometric multigrid.
10879 
10880    Input Parameters:
10881 +  restrct - restriction operator
10882 .  dA - fine grid matrix
10883 .  interpolate - interpolation operator
10884 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10885 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10886 
10887    Output Parameters:
10888 .  A - the Galerkin coarse matrix
10889 
10890    Options Database Key:
10891 .  -pc_mg_galerkin <both,pmat,mat,none>
10892 
10893    Level: developer
10894 
10895 .keywords: MG, multigrid, Galerkin
10896 
10897 .seealso: MatPtAP(), MatMatMatMult()
10898 @*/
10899 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10900 {
10901   PetscErrorCode ierr;
10902   IS             zerorows;
10903   Vec            diag;
10904 
10905   PetscFunctionBegin;
10906   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10907   /* Construct the coarse grid matrix */
10908   if (interpolate == restrct) {
10909     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10910   } else {
10911     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10912   }
10913 
10914   /* If the interpolation matrix is not of full rank, A will have zero rows.
10915      This can legitimately happen in the case of non-nested geometric multigrid.
10916      In that event, we set the rows of the matrix to the rows of the identity,
10917      ignoring the equations (as the RHS will also be zero). */
10918 
10919   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10920 
10921   if (zerorows != NULL) { /* if there are any zero rows */
10922     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10923     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10924     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10925     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10926     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10927     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10928   }
10929   PetscFunctionReturn(0);
10930 }
10931 
10932 /*@C
10933     MatSetOperation - Allows user to set a matrix operation for any matrix type
10934 
10935    Logically Collective on Mat
10936 
10937     Input Parameters:
10938 +   mat - the matrix
10939 .   op - the name of the operation
10940 -   f - the function that provides the operation
10941 
10942    Level: developer
10943 
10944     Usage:
10945 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10946 $      ierr = MatCreateXXX(comm,...&A);
10947 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10948 
10949     Notes:
10950     See the file include/petscmat.h for a complete list of matrix
10951     operations, which all have the form MATOP_<OPERATION>, where
10952     <OPERATION> is the name (in all capital letters) of the
10953     user interface routine (e.g., MatMult() -> MATOP_MULT).
10954 
10955     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10956     sequence as the usual matrix interface routines, since they
10957     are intended to be accessed via the usual matrix interface
10958     routines, e.g.,
10959 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10960 
10961     In particular each function MUST return an error code of 0 on success and
10962     nonzero on failure.
10963 
10964     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10965 
10966 .keywords: matrix, set, operation
10967 
10968 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10969 @*/
10970 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10971 {
10972   PetscFunctionBegin;
10973   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10974   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10975     mat->ops->viewnative = mat->ops->view;
10976   }
10977   (((void(**)(void))mat->ops)[op]) = f;
10978   PetscFunctionReturn(0);
10979 }
10980 
10981 /*@C
10982     MatGetOperation - Gets a matrix operation for any matrix type.
10983 
10984     Not Collective
10985 
10986     Input Parameters:
10987 +   mat - the matrix
10988 -   op - the name of the operation
10989 
10990     Output Parameter:
10991 .   f - the function that provides the operation
10992 
10993     Level: developer
10994 
10995     Usage:
10996 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
10997 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
10998 
10999     Notes:
11000     See the file include/petscmat.h for a complete list of matrix
11001     operations, which all have the form MATOP_<OPERATION>, where
11002     <OPERATION> is the name (in all capital letters) of the
11003     user interface routine (e.g., MatMult() -> MATOP_MULT).
11004 
11005     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11006 
11007 .keywords: matrix, get, operation
11008 
11009 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11010 @*/
11011 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11012 {
11013   PetscFunctionBegin;
11014   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11015   *f = (((void (**)(void))mat->ops)[op]);
11016   PetscFunctionReturn(0);
11017 }
11018 
11019 /*@
11020     MatHasOperation - Determines whether the given matrix supports the particular
11021     operation.
11022 
11023    Not Collective
11024 
11025    Input Parameters:
11026 +  mat - the matrix
11027 -  op - the operation, for example, MATOP_GET_DIAGONAL
11028 
11029    Output Parameter:
11030 .  has - either PETSC_TRUE or PETSC_FALSE
11031 
11032    Level: advanced
11033 
11034    Notes:
11035    See the file include/petscmat.h for a complete list of matrix
11036    operations, which all have the form MATOP_<OPERATION>, where
11037    <OPERATION> is the name (in all capital letters) of the
11038    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11039 
11040 .keywords: matrix, has, operation
11041 
11042 .seealso: MatCreateShell()
11043 @*/
11044 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11045 {
11046   PetscErrorCode ierr;
11047 
11048   PetscFunctionBegin;
11049   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11050   PetscValidType(mat,1);
11051   PetscValidPointer(has,3);
11052   if (mat->ops->hasoperation) {
11053     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11054   } else {
11055     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11056     else {
11057       *has = PETSC_FALSE;
11058       if (op == MATOP_CREATE_SUBMATRIX) {
11059         PetscMPIInt size;
11060 
11061         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11062         if (size == 1) {
11063           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11064         }
11065       }
11066     }
11067   }
11068   PetscFunctionReturn(0);
11069 }
11070 
11071 /*@
11072     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11073     of the matrix are congruent
11074 
11075    Collective on mat
11076 
11077    Input Parameters:
11078 .  mat - the matrix
11079 
11080    Output Parameter:
11081 .  cong - either PETSC_TRUE or PETSC_FALSE
11082 
11083    Level: beginner
11084 
11085    Notes:
11086 
11087 .keywords: matrix, has
11088 
11089 .seealso: MatCreate(), MatSetSizes()
11090 @*/
11091 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11092 {
11093   PetscErrorCode ierr;
11094 
11095   PetscFunctionBegin;
11096   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11097   PetscValidType(mat,1);
11098   PetscValidPointer(cong,2);
11099   if (!mat->rmap || !mat->cmap) {
11100     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11101     PetscFunctionReturn(0);
11102   }
11103   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11104     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11105     if (*cong) mat->congruentlayouts = 1;
11106     else       mat->congruentlayouts = 0;
11107   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11108   PetscFunctionReturn(0);
11109 }
11110 
11111 /*@
11112     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11113     e.g., matrx product of MatPtAP.
11114 
11115    Collective on mat
11116 
11117    Input Parameters:
11118 .  mat - the matrix
11119 
11120    Output Parameter:
11121 .  mat - the matrix with intermediate data structures released
11122 
11123    Level: advanced
11124 
11125    Notes:
11126 
11127 .keywords: matrix
11128 
11129 .seealso: MatPtAP(), MatMatMult()
11130 @*/
11131 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11132 {
11133   PetscErrorCode ierr;
11134 
11135   PetscFunctionBegin;
11136   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11137   PetscValidType(mat,1);
11138   if (mat->ops->freeintermediatedatastructures) {
11139     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11140   }
11141   PetscFunctionReturn(0);
11142 }
11143