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