xref: /petsc/src/mat/interface/matrix.c (revision 88e8bff4b4852f1e685e4e3f60070568b8aa5783)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   MatCheckPreallocated(mat,1);
694   if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   PetscValidType(mat,1);
722   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
723   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
724   MatCheckPreallocated(mat,1);
725   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
726   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
727   PetscFunctionReturn(0);
728 }
729 
730 /*@C
731    MatSetOptionsPrefix - Sets the prefix used for searching for all
732    Mat options in the database.
733 
734    Logically Collective on Mat
735 
736    Input Parameter:
737 +  A - the Mat context
738 -  prefix - the prefix to prepend to all option names
739 
740    Notes:
741    A hyphen (-) must NOT be given at the beginning of the prefix name.
742    The first character of all runtime options is AUTOMATICALLY the hyphen.
743 
744    Level: advanced
745 
746 .keywords: Mat, set, options, prefix, database
747 
748 .seealso: MatSetFromOptions()
749 @*/
750 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
751 {
752   PetscErrorCode ierr;
753 
754   PetscFunctionBegin;
755   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
756   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
757   PetscFunctionReturn(0);
758 }
759 
760 /*@C
761    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
762    Mat options in the database.
763 
764    Logically Collective on Mat
765 
766    Input Parameters:
767 +  A - the Mat context
768 -  prefix - the prefix to prepend to all option names
769 
770    Notes:
771    A hyphen (-) must NOT be given at the beginning of the prefix name.
772    The first character of all runtime options is AUTOMATICALLY the hyphen.
773 
774    Level: advanced
775 
776 .keywords: Mat, append, options, prefix, database
777 
778 .seealso: MatGetOptionsPrefix()
779 @*/
780 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
781 {
782   PetscErrorCode ierr;
783 
784   PetscFunctionBegin;
785   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
786   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
787   PetscFunctionReturn(0);
788 }
789 
790 /*@C
791    MatGetOptionsPrefix - Sets the prefix used for searching for all
792    Mat options in the database.
793 
794    Not Collective
795 
796    Input Parameter:
797 .  A - the Mat context
798 
799    Output Parameter:
800 .  prefix - pointer to the prefix string used
801 
802    Notes:
803     On the fortran side, the user should pass in a string 'prefix' of
804    sufficient length to hold the prefix.
805 
806    Level: advanced
807 
808 .keywords: Mat, get, options, prefix, database
809 
810 .seealso: MatAppendOptionsPrefix()
811 @*/
812 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
813 {
814   PetscErrorCode ierr;
815 
816   PetscFunctionBegin;
817   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
818   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
819   PetscFunctionReturn(0);
820 }
821 
822 /*@
823    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
824 
825    Collective on Mat
826 
827    Input Parameters:
828 .  A - the Mat context
829 
830    Notes:
831    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
832    Currently support MPIAIJ and SEQAIJ.
833 
834    Level: beginner
835 
836 .keywords: Mat, ResetPreallocation
837 
838 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
839 @*/
840 PetscErrorCode MatResetPreallocation(Mat A)
841 {
842   PetscErrorCode ierr;
843 
844   PetscFunctionBegin;
845   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
846   PetscValidType(A,1);
847   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
848   PetscFunctionReturn(0);
849 }
850 
851 
852 /*@
853    MatSetUp - Sets up the internal matrix data structures for the later use.
854 
855    Collective on Mat
856 
857    Input Parameters:
858 .  A - the Mat context
859 
860    Notes:
861    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
862 
863    If a suitable preallocation routine is used, this function does not need to be called.
864 
865    See the Performance chapter of the PETSc users manual for how to preallocate matrices
866 
867    Level: beginner
868 
869 .keywords: Mat, setup
870 
871 .seealso: MatCreate(), MatDestroy()
872 @*/
873 PetscErrorCode MatSetUp(Mat A)
874 {
875   PetscMPIInt    size;
876   PetscErrorCode ierr;
877 
878   PetscFunctionBegin;
879   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
880   if (!((PetscObject)A)->type_name) {
881     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
882     if (size == 1) {
883       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
884     } else {
885       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
886     }
887   }
888   if (!A->preallocated && A->ops->setup) {
889     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
890     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
891   }
892   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
893   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
894   A->preallocated = PETSC_TRUE;
895   PetscFunctionReturn(0);
896 }
897 
898 #if defined(PETSC_HAVE_SAWS)
899 #include <petscviewersaws.h>
900 #endif
901 /*@C
902    MatView - Visualizes a matrix object.
903 
904    Collective on Mat
905 
906    Input Parameters:
907 +  mat - the matrix
908 -  viewer - visualization context
909 
910   Notes:
911   The available visualization contexts include
912 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
913 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
914 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
915 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
916 
917    The user can open alternative visualization contexts with
918 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
919 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
920          specified file; corresponding input uses MatLoad()
921 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
922          an X window display
923 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
924          Currently only the sequential dense and AIJ
925          matrix types support the Socket viewer.
926 
927    The user can call PetscViewerPushFormat() to specify the output
928    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
929    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
930 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
931 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
932 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
933 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
934          format common among all matrix types
935 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
936          format (which is in many cases the same as the default)
937 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
938          size and structure (not the matrix entries)
939 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
940          the matrix structure
941 
942    Options Database Keys:
943 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
944 .  -mat_view ::ascii_info_detail - Prints more detailed info
945 .  -mat_view - Prints matrix in ASCII format
946 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
947 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
948 .  -display <name> - Sets display name (default is host)
949 .  -draw_pause <sec> - Sets number of seconds to pause after display
950 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
951 .  -viewer_socket_machine <machine> -
952 .  -viewer_socket_port <port> -
953 .  -mat_view binary - save matrix to file in binary format
954 -  -viewer_binary_filename <name> -
955    Level: beginner
956 
957    Notes:
958     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
959     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
960 
961     See the manual page for MatLoad() for the exact format of the binary file when the binary
962       viewer is used.
963 
964       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
965       viewer is used.
966 
967       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
968       and then use the following mouse functions.
969 + left mouse: zoom in
970 . middle mouse: zoom out
971 - right mouse: continue with the simulation
972 
973    Concepts: matrices^viewing
974    Concepts: matrices^plotting
975    Concepts: matrices^printing
976 
977 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
978           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
979 @*/
980 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
981 {
982   PetscErrorCode    ierr;
983   PetscInt          rows,cols,rbs,cbs;
984   PetscBool         iascii,ibinary,isstring;
985   PetscViewerFormat format;
986   PetscMPIInt       size;
987 #if defined(PETSC_HAVE_SAWS)
988   PetscBool         issaws;
989 #endif
990 
991   PetscFunctionBegin;
992   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
993   PetscValidType(mat,1);
994   if (!viewer) {
995     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
996   }
997   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
998   PetscCheckSameComm(mat,1,viewer,2);
999   MatCheckPreallocated(mat,1);
1000   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1001   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
1002   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
1003   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1004   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
1005   if (ibinary) {
1006     PetscBool mpiio;
1007     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1008     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1009   }
1010 
1011   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1012   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1013   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1014     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1015   }
1016 
1017 #if defined(PETSC_HAVE_SAWS)
1018   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1019 #endif
1020   if (iascii) {
1021     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1022     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1023     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1024       MatNullSpace nullsp,transnullsp;
1025 
1026       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1027       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1028       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1029       if (rbs != 1 || cbs != 1) {
1030         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1031         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1032       } else {
1033         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1034       }
1035       if (mat->factortype) {
1036         MatSolverType solver;
1037         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1038         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1039       }
1040       if (mat->ops->getinfo) {
1041         MatInfo info;
1042         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1043         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1044         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1045       }
1046       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1047       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1048       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1049       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1050       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1051       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1052     }
1053 #if defined(PETSC_HAVE_SAWS)
1054   } else if (issaws) {
1055     PetscMPIInt rank;
1056 
1057     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1058     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1059     if (!((PetscObject)mat)->amsmem && !rank) {
1060       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1061     }
1062 #endif
1063   } else if (isstring) {
1064     const char *type;
1065     ierr = MatGetType(mat,&type);CHKERRQ(ierr);
1066     ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr);
1067     if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);}
1068   }
1069   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1070     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1071     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1072     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1073   } else if (mat->ops->view) {
1074     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1075     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1076     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1077   }
1078   if (iascii) {
1079     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1080     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1081       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1082     }
1083   }
1084   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1085   PetscFunctionReturn(0);
1086 }
1087 
1088 #if defined(PETSC_USE_DEBUG)
1089 #include <../src/sys/totalview/tv_data_display.h>
1090 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1091 {
1092   TV_add_row("Local rows", "int", &mat->rmap->n);
1093   TV_add_row("Local columns", "int", &mat->cmap->n);
1094   TV_add_row("Global rows", "int", &mat->rmap->N);
1095   TV_add_row("Global columns", "int", &mat->cmap->N);
1096   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1097   return TV_format_OK;
1098 }
1099 #endif
1100 
1101 /*@C
1102    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1103    with MatView().  The matrix format is determined from the options database.
1104    Generates a parallel MPI matrix if the communicator has more than one
1105    processor.  The default matrix type is AIJ.
1106 
1107    Collective on PetscViewer
1108 
1109    Input Parameters:
1110 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1111             or some related function before a call to MatLoad()
1112 -  viewer - binary/HDF5 file viewer
1113 
1114    Options Database Keys:
1115    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1116    block size
1117 .    -matload_block_size <bs>
1118 
1119    Level: beginner
1120 
1121    Notes:
1122    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1123    Mat before calling this routine if you wish to set it from the options database.
1124 
1125    MatLoad() automatically loads into the options database any options
1126    given in the file filename.info where filename is the name of the file
1127    that was passed to the PetscViewerBinaryOpen(). The options in the info
1128    file will be ignored if you use the -viewer_binary_skip_info option.
1129 
1130    If the type or size of newmat is not set before a call to MatLoad, PETSc
1131    sets the default matrix type AIJ and sets the local and global sizes.
1132    If type and/or size is already set, then the same are used.
1133 
1134    In parallel, each processor can load a subset of rows (or the
1135    entire matrix).  This routine is especially useful when a large
1136    matrix is stored on disk and only part of it is desired on each
1137    processor.  For example, a parallel solver may access only some of
1138    the rows from each processor.  The algorithm used here reads
1139    relatively small blocks of data rather than reading the entire
1140    matrix and then subsetting it.
1141 
1142    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1143    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1144    or the sequence like
1145 $    PetscViewer v;
1146 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1147 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1148 $    PetscViewerSetFromOptions(v);
1149 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1150 $    PetscViewerFileSetName(v,"datafile");
1151    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1152 $ -viewer_type {binary,hdf5}
1153 
1154    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1155    and src/mat/examples/tutorials/ex10.c with the second approach.
1156 
1157    Notes about the PETSc binary format:
1158    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1159    is read onto rank 0 and then shipped to its destination rank, one after another.
1160    Multiple objects, both matrices and vectors, can be stored within the same file.
1161    Their PetscObject name is ignored; they are loaded in the order of their storage.
1162 
1163    Most users should not need to know the details of the binary storage
1164    format, since MatLoad() and MatView() completely hide these details.
1165    But for anyone who's interested, the standard binary matrix storage
1166    format is
1167 
1168 $    int    MAT_FILE_CLASSID
1169 $    int    number of rows
1170 $    int    number of columns
1171 $    int    total number of nonzeros
1172 $    int    *number nonzeros in each row
1173 $    int    *column indices of all nonzeros (starting index is zero)
1174 $    PetscScalar *values of all nonzeros
1175 
1176    PETSc automatically does the byte swapping for
1177 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1178 linux, Windows and the paragon; thus if you write your own binary
1179 read/write routines you have to swap the bytes; see PetscBinaryRead()
1180 and PetscBinaryWrite() to see how this may be done.
1181 
1182    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1183    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1184    Each processor's chunk is loaded independently by its owning rank.
1185    Multiple objects, both matrices and vectors, can be stored within the same file.
1186    They are looked up by their PetscObject name.
1187 
1188    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1189    by default the same structure and naming of the AIJ arrays and column count
1190    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1191 $    save example.mat A b -v7.3
1192    can be directly read by this routine (see Reference 1 for details).
1193    Note that depending on your MATLAB version, this format might be a default,
1194    otherwise you can set it as default in Preferences.
1195 
1196    Unless -nocompression flag is used to save the file in MATLAB,
1197    PETSc must be configured with ZLIB package.
1198 
1199    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1200 
1201    Current HDF5 (MAT-File) limitations:
1202    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1203 
1204    Corresponding MatView() is not yet implemented.
1205 
1206    The loaded matrix is actually a transpose of the original one in MATLAB,
1207    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1208    With this format, matrix is automatically transposed by PETSc,
1209    unless the matrix is marked as SPD or symmetric
1210    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1211 
1212    References:
1213 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1214 
1215 .keywords: matrix, load, binary, input, HDF5
1216 
1217 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad()
1218 
1219  @*/
1220 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1221 {
1222   PetscErrorCode ierr;
1223   PetscBool      flg;
1224 
1225   PetscFunctionBegin;
1226   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1227   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1228 
1229   if (!((PetscObject)newmat)->type_name) {
1230     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1231   }
1232 
1233   flg  = PETSC_FALSE;
1234   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1235   if (flg) {
1236     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1237     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1238   }
1239   flg  = PETSC_FALSE;
1240   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1241   if (flg) {
1242     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1243   }
1244 
1245   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1246   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1247   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1248   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1249   PetscFunctionReturn(0);
1250 }
1251 
1252 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1253 {
1254   PetscErrorCode ierr;
1255   Mat_Redundant  *redund = *redundant;
1256   PetscInt       i;
1257 
1258   PetscFunctionBegin;
1259   if (redund){
1260     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1261       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1262       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1263       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1264     } else {
1265       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1266       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1267       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1268       for (i=0; i<redund->nrecvs; i++) {
1269         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1270         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1271       }
1272       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1273     }
1274 
1275     if (redund->subcomm) {
1276       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1277     }
1278     ierr = PetscFree(redund);CHKERRQ(ierr);
1279   }
1280   PetscFunctionReturn(0);
1281 }
1282 
1283 /*@
1284    MatDestroy - Frees space taken by a matrix.
1285 
1286    Collective on Mat
1287 
1288    Input Parameter:
1289 .  A - the matrix
1290 
1291    Level: beginner
1292 
1293 @*/
1294 PetscErrorCode MatDestroy(Mat *A)
1295 {
1296   PetscErrorCode ierr;
1297 
1298   PetscFunctionBegin;
1299   if (!*A) PetscFunctionReturn(0);
1300   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1301   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1302 
1303   /* if memory was published with SAWs then destroy it */
1304   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1305   if ((*A)->ops->destroy) {
1306     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1307   }
1308 
1309   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1310   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1311   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1312   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1313   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1314   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1315   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1316   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1317   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1318   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1319   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1320   PetscFunctionReturn(0);
1321 }
1322 
1323 /*@C
1324    MatSetValues - Inserts or adds a block of values into a matrix.
1325    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1326    MUST be called after all calls to MatSetValues() have been completed.
1327 
1328    Not Collective
1329 
1330    Input Parameters:
1331 +  mat - the matrix
1332 .  v - a logically two-dimensional array of values
1333 .  m, idxm - the number of rows and their global indices
1334 .  n, idxn - the number of columns and their global indices
1335 -  addv - either ADD_VALUES or INSERT_VALUES, where
1336    ADD_VALUES adds values to any existing entries, and
1337    INSERT_VALUES replaces existing entries with new values
1338 
1339    Notes:
1340    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1341       MatSetUp() before using this routine
1342 
1343    By default the values, v, are row-oriented. See MatSetOption() for other options.
1344 
1345    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1346    options cannot be mixed without intervening calls to the assembly
1347    routines.
1348 
1349    MatSetValues() uses 0-based row and column numbers in Fortran
1350    as well as in C.
1351 
1352    Negative indices may be passed in idxm and idxn, these rows and columns are
1353    simply ignored. This allows easily inserting element stiffness matrices
1354    with homogeneous Dirchlet boundary conditions that you don't want represented
1355    in the matrix.
1356 
1357    Efficiency Alert:
1358    The routine MatSetValuesBlocked() may offer much better efficiency
1359    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1360 
1361    Level: beginner
1362 
1363    Developer Notes:
1364     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1365                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1366 
1367    Concepts: matrices^putting entries in
1368 
1369 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1370           InsertMode, INSERT_VALUES, ADD_VALUES
1371 @*/
1372 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1373 {
1374   PetscErrorCode ierr;
1375 #if defined(PETSC_USE_DEBUG)
1376   PetscInt       i,j;
1377 #endif
1378 
1379   PetscFunctionBeginHot;
1380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1381   PetscValidType(mat,1);
1382   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1383   PetscValidIntPointer(idxm,3);
1384   PetscValidIntPointer(idxn,5);
1385   PetscValidScalarPointer(v,6);
1386   MatCheckPreallocated(mat,1);
1387   if (mat->insertmode == NOT_SET_VALUES) {
1388     mat->insertmode = addv;
1389   }
1390 #if defined(PETSC_USE_DEBUG)
1391   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1392   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1393   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1394 
1395   for (i=0; i<m; i++) {
1396     for (j=0; j<n; j++) {
1397       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1398 #if defined(PETSC_USE_COMPLEX)
1399         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]);
1400 #else
1401         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1402 #endif
1403     }
1404   }
1405 #endif
1406 
1407   if (mat->assembled) {
1408     mat->was_assembled = PETSC_TRUE;
1409     mat->assembled     = PETSC_FALSE;
1410   }
1411   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1412   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1413   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1414 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1415   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1416     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1417   }
1418 #endif
1419   PetscFunctionReturn(0);
1420 }
1421 
1422 
1423 /*@
1424    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1425         values into a matrix
1426 
1427    Not Collective
1428 
1429    Input Parameters:
1430 +  mat - the matrix
1431 .  row - the (block) row to set
1432 -  v - a logically two-dimensional array of values
1433 
1434    Notes:
1435    By the values, v, are column-oriented (for the block version) and sorted
1436 
1437    All the nonzeros in the row must be provided
1438 
1439    The matrix must have previously had its column indices set
1440 
1441    The row must belong to this process
1442 
1443    Level: intermediate
1444 
1445    Concepts: matrices^putting entries in
1446 
1447 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1448           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1449 @*/
1450 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1451 {
1452   PetscErrorCode ierr;
1453   PetscInt       globalrow;
1454 
1455   PetscFunctionBegin;
1456   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1457   PetscValidType(mat,1);
1458   PetscValidScalarPointer(v,2);
1459   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1460   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1464   }
1465 #endif
1466   PetscFunctionReturn(0);
1467 }
1468 
1469 /*@
1470    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1471         values into a matrix
1472 
1473    Not Collective
1474 
1475    Input Parameters:
1476 +  mat - the matrix
1477 .  row - the (block) row to set
1478 -  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
1479 
1480    Notes:
1481    The values, v, are column-oriented for the block version.
1482 
1483    All the nonzeros in the row must be provided
1484 
1485    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1486 
1487    The row must belong to this process
1488 
1489    Level: advanced
1490 
1491    Concepts: matrices^putting entries in
1492 
1493 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1494           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1495 @*/
1496 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1497 {
1498   PetscErrorCode ierr;
1499 
1500   PetscFunctionBeginHot;
1501   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1502   PetscValidType(mat,1);
1503   MatCheckPreallocated(mat,1);
1504   PetscValidScalarPointer(v,2);
1505 #if defined(PETSC_USE_DEBUG)
1506   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1507   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1508 #endif
1509   mat->insertmode = INSERT_VALUES;
1510 
1511   if (mat->assembled) {
1512     mat->was_assembled = PETSC_TRUE;
1513     mat->assembled     = PETSC_FALSE;
1514   }
1515   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1516   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1517   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1518   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1519 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1520   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1521     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1522   }
1523 #endif
1524   PetscFunctionReturn(0);
1525 }
1526 
1527 /*@
1528    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1529      Using structured grid indexing
1530 
1531    Not Collective
1532 
1533    Input Parameters:
1534 +  mat - the matrix
1535 .  m - number of rows being entered
1536 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1537 .  n - number of columns being entered
1538 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1539 .  v - a logically two-dimensional array of values
1540 -  addv - either ADD_VALUES or INSERT_VALUES, where
1541    ADD_VALUES adds values to any existing entries, and
1542    INSERT_VALUES replaces existing entries with new values
1543 
1544    Notes:
1545    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1546 
1547    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1548    options cannot be mixed without intervening calls to the assembly
1549    routines.
1550 
1551    The grid coordinates are across the entire grid, not just the local portion
1552 
1553    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1554    as well as in C.
1555 
1556    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1557 
1558    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1559    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1560 
1561    The columns and rows in the stencil passed in MUST be contained within the
1562    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1563    if you create a DMDA with an overlap of one grid level and on a particular process its first
1564    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1565    first i index you can use in your column and row indices in MatSetStencil() is 5.
1566 
1567    In Fortran idxm and idxn should be declared as
1568 $     MatStencil idxm(4,m),idxn(4,n)
1569    and the values inserted using
1570 $    idxm(MatStencil_i,1) = i
1571 $    idxm(MatStencil_j,1) = j
1572 $    idxm(MatStencil_k,1) = k
1573 $    idxm(MatStencil_c,1) = c
1574    etc
1575 
1576    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1577    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1578    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1579    DM_BOUNDARY_PERIODIC boundary type.
1580 
1581    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
1582    a single value per point) you can skip filling those indices.
1583 
1584    Inspired by the structured grid interface to the HYPRE package
1585    (http://www.llnl.gov/CASC/hypre)
1586 
1587    Efficiency Alert:
1588    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1589    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1590 
1591    Level: beginner
1592 
1593    Concepts: matrices^putting entries in
1594 
1595 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1596           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1597 @*/
1598 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1599 {
1600   PetscErrorCode ierr;
1601   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1602   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1603   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1604 
1605   PetscFunctionBegin;
1606   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1607   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1608   PetscValidType(mat,1);
1609   PetscValidIntPointer(idxm,3);
1610   PetscValidIntPointer(idxn,5);
1611   PetscValidScalarPointer(v,6);
1612 
1613   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1614     jdxm = buf; jdxn = buf+m;
1615   } else {
1616     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1617     jdxm = bufm; jdxn = bufn;
1618   }
1619   for (i=0; i<m; i++) {
1620     for (j=0; j<3-sdim; j++) dxm++;
1621     tmp = *dxm++ - starts[0];
1622     for (j=0; j<dim-1; j++) {
1623       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1624       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1625     }
1626     if (mat->stencil.noc) dxm++;
1627     jdxm[i] = tmp;
1628   }
1629   for (i=0; i<n; i++) {
1630     for (j=0; j<3-sdim; j++) dxn++;
1631     tmp = *dxn++ - starts[0];
1632     for (j=0; j<dim-1; j++) {
1633       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1634       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1635     }
1636     if (mat->stencil.noc) dxn++;
1637     jdxn[i] = tmp;
1638   }
1639   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1640   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1641   PetscFunctionReturn(0);
1642 }
1643 
1644 /*@
1645    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1646      Using structured grid indexing
1647 
1648    Not Collective
1649 
1650    Input Parameters:
1651 +  mat - the matrix
1652 .  m - number of rows being entered
1653 .  idxm - grid coordinates for matrix rows being entered
1654 .  n - number of columns being entered
1655 .  idxn - grid coordinates for matrix columns being entered
1656 .  v - a logically two-dimensional array of values
1657 -  addv - either ADD_VALUES or INSERT_VALUES, where
1658    ADD_VALUES adds values to any existing entries, and
1659    INSERT_VALUES replaces existing entries with new values
1660 
1661    Notes:
1662    By default the values, v, are row-oriented and unsorted.
1663    See MatSetOption() for other options.
1664 
1665    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1666    options cannot be mixed without intervening calls to the assembly
1667    routines.
1668 
1669    The grid coordinates are across the entire grid, not just the local portion
1670 
1671    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1672    as well as in C.
1673 
1674    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1675 
1676    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1677    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1678 
1679    The columns and rows in the stencil passed in MUST be contained within the
1680    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1681    if you create a DMDA with an overlap of one grid level and on a particular process its first
1682    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1683    first i index you can use in your column and row indices in MatSetStencil() is 5.
1684 
1685    In Fortran idxm and idxn should be declared as
1686 $     MatStencil idxm(4,m),idxn(4,n)
1687    and the values inserted using
1688 $    idxm(MatStencil_i,1) = i
1689 $    idxm(MatStencil_j,1) = j
1690 $    idxm(MatStencil_k,1) = k
1691    etc
1692 
1693    Negative indices may be passed in idxm and idxn, these rows and columns are
1694    simply ignored. This allows easily inserting element stiffness matrices
1695    with homogeneous Dirchlet boundary conditions that you don't want represented
1696    in the matrix.
1697 
1698    Inspired by the structured grid interface to the HYPRE package
1699    (http://www.llnl.gov/CASC/hypre)
1700 
1701    Level: beginner
1702 
1703    Concepts: matrices^putting entries in
1704 
1705 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1706           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1707           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1708 @*/
1709 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1710 {
1711   PetscErrorCode ierr;
1712   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1713   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1714   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1715 
1716   PetscFunctionBegin;
1717   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1718   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1719   PetscValidType(mat,1);
1720   PetscValidIntPointer(idxm,3);
1721   PetscValidIntPointer(idxn,5);
1722   PetscValidScalarPointer(v,6);
1723 
1724   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1725     jdxm = buf; jdxn = buf+m;
1726   } else {
1727     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1728     jdxm = bufm; jdxn = bufn;
1729   }
1730   for (i=0; i<m; i++) {
1731     for (j=0; j<3-sdim; j++) dxm++;
1732     tmp = *dxm++ - starts[0];
1733     for (j=0; j<sdim-1; j++) {
1734       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1735       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1736     }
1737     dxm++;
1738     jdxm[i] = tmp;
1739   }
1740   for (i=0; i<n; i++) {
1741     for (j=0; j<3-sdim; j++) dxn++;
1742     tmp = *dxn++ - starts[0];
1743     for (j=0; j<sdim-1; j++) {
1744       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1745       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1746     }
1747     dxn++;
1748     jdxn[i] = tmp;
1749   }
1750   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1751   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1752 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1753   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1754     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1755   }
1756 #endif
1757   PetscFunctionReturn(0);
1758 }
1759 
1760 /*@
1761    MatSetStencil - Sets the grid information for setting values into a matrix via
1762         MatSetValuesStencil()
1763 
1764    Not Collective
1765 
1766    Input Parameters:
1767 +  mat - the matrix
1768 .  dim - dimension of the grid 1, 2, or 3
1769 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1770 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1771 -  dof - number of degrees of freedom per node
1772 
1773 
1774    Inspired by the structured grid interface to the HYPRE package
1775    (www.llnl.gov/CASC/hyper)
1776 
1777    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1778    user.
1779 
1780    Level: beginner
1781 
1782    Concepts: matrices^putting entries in
1783 
1784 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1785           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1786 @*/
1787 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1788 {
1789   PetscInt i;
1790 
1791   PetscFunctionBegin;
1792   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1793   PetscValidIntPointer(dims,3);
1794   PetscValidIntPointer(starts,4);
1795 
1796   mat->stencil.dim = dim + (dof > 1);
1797   for (i=0; i<dim; i++) {
1798     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1799     mat->stencil.starts[i] = starts[dim-i-1];
1800   }
1801   mat->stencil.dims[dim]   = dof;
1802   mat->stencil.starts[dim] = 0;
1803   mat->stencil.noc         = (PetscBool)(dof == 1);
1804   PetscFunctionReturn(0);
1805 }
1806 
1807 /*@C
1808    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1809 
1810    Not Collective
1811 
1812    Input Parameters:
1813 +  mat - the matrix
1814 .  v - a logically two-dimensional array of values
1815 .  m, idxm - the number of block rows and their global block indices
1816 .  n, idxn - the number of block columns and their global block indices
1817 -  addv - either ADD_VALUES or INSERT_VALUES, where
1818    ADD_VALUES adds values to any existing entries, and
1819    INSERT_VALUES replaces existing entries with new values
1820 
1821    Notes:
1822    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1823    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1824 
1825    The m and n count the NUMBER of blocks in the row direction and column direction,
1826    NOT the total number of rows/columns; for example, if the block size is 2 and
1827    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1828    The values in idxm would be 1 2; that is the first index for each block divided by
1829    the block size.
1830 
1831    Note that you must call MatSetBlockSize() when constructing this matrix (before
1832    preallocating it).
1833 
1834    By default the values, v, are row-oriented, so the layout of
1835    v is the same as for MatSetValues(). See MatSetOption() for other options.
1836 
1837    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1838    options cannot be mixed without intervening calls to the assembly
1839    routines.
1840 
1841    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1842    as well as in C.
1843 
1844    Negative indices may be passed in idxm and idxn, these rows and columns are
1845    simply ignored. This allows easily inserting element stiffness matrices
1846    with homogeneous Dirchlet boundary conditions that you don't want represented
1847    in the matrix.
1848 
1849    Each time an entry is set within a sparse matrix via MatSetValues(),
1850    internal searching must be done to determine where to place the
1851    data in the matrix storage space.  By instead inserting blocks of
1852    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1853    reduced.
1854 
1855    Example:
1856 $   Suppose m=n=2 and block size(bs) = 2 The array is
1857 $
1858 $   1  2  | 3  4
1859 $   5  6  | 7  8
1860 $   - - - | - - -
1861 $   9  10 | 11 12
1862 $   13 14 | 15 16
1863 $
1864 $   v[] should be passed in like
1865 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1866 $
1867 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1868 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1869 
1870    Level: intermediate
1871 
1872    Concepts: matrices^putting entries in blocked
1873 
1874 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1875 @*/
1876 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1877 {
1878   PetscErrorCode ierr;
1879 
1880   PetscFunctionBeginHot;
1881   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1882   PetscValidType(mat,1);
1883   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1884   PetscValidIntPointer(idxm,3);
1885   PetscValidIntPointer(idxn,5);
1886   PetscValidScalarPointer(v,6);
1887   MatCheckPreallocated(mat,1);
1888   if (mat->insertmode == NOT_SET_VALUES) {
1889     mat->insertmode = addv;
1890   }
1891 #if defined(PETSC_USE_DEBUG)
1892   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1893   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1894   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1895 #endif
1896 
1897   if (mat->assembled) {
1898     mat->was_assembled = PETSC_TRUE;
1899     mat->assembled     = PETSC_FALSE;
1900   }
1901   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1902   if (mat->ops->setvaluesblocked) {
1903     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1904   } else {
1905     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1906     PetscInt i,j,bs,cbs;
1907     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1908     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1909       iidxm = buf; iidxn = buf + m*bs;
1910     } else {
1911       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1912       iidxm = bufr; iidxn = bufc;
1913     }
1914     for (i=0; i<m; i++) {
1915       for (j=0; j<bs; j++) {
1916         iidxm[i*bs+j] = bs*idxm[i] + j;
1917       }
1918     }
1919     for (i=0; i<n; i++) {
1920       for (j=0; j<cbs; j++) {
1921         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1922       }
1923     }
1924     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1925     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1926   }
1927   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1928 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1929   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1930     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1931   }
1932 #endif
1933   PetscFunctionReturn(0);
1934 }
1935 
1936 /*@
1937    MatGetValues - Gets a block of values from a matrix.
1938 
1939    Not Collective; currently only returns a local block
1940 
1941    Input Parameters:
1942 +  mat - the matrix
1943 .  v - a logically two-dimensional array for storing the values
1944 .  m, idxm - the number of rows and their global indices
1945 -  n, idxn - the number of columns and their global indices
1946 
1947    Notes:
1948    The user must allocate space (m*n PetscScalars) for the values, v.
1949    The values, v, are then returned in a row-oriented format,
1950    analogous to that used by default in MatSetValues().
1951 
1952    MatGetValues() uses 0-based row and column numbers in
1953    Fortran as well as in C.
1954 
1955    MatGetValues() requires that the matrix has been assembled
1956    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1957    MatSetValues() and MatGetValues() CANNOT be made in succession
1958    without intermediate matrix assembly.
1959 
1960    Negative row or column indices will be ignored and those locations in v[] will be
1961    left unchanged.
1962 
1963    Level: advanced
1964 
1965    Concepts: matrices^accessing values
1966 
1967 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1968 @*/
1969 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1970 {
1971   PetscErrorCode ierr;
1972 
1973   PetscFunctionBegin;
1974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1975   PetscValidType(mat,1);
1976   if (!m || !n) PetscFunctionReturn(0);
1977   PetscValidIntPointer(idxm,3);
1978   PetscValidIntPointer(idxn,5);
1979   PetscValidScalarPointer(v,6);
1980   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1981   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1982   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1983   MatCheckPreallocated(mat,1);
1984 
1985   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1986   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1987   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1988   PetscFunctionReturn(0);
1989 }
1990 
1991 /*@
1992   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1993   the same size. Currently, this can only be called once and creates the given matrix.
1994 
1995   Not Collective
1996 
1997   Input Parameters:
1998 + mat - the matrix
1999 . nb - the number of blocks
2000 . bs - the number of rows (and columns) in each block
2001 . rows - a concatenation of the rows for each block
2002 - v - a concatenation of logically two-dimensional arrays of values
2003 
2004   Notes:
2005   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
2006 
2007   Level: advanced
2008 
2009   Concepts: matrices^putting entries in
2010 
2011 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2012           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2013 @*/
2014 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2015 {
2016   PetscErrorCode ierr;
2017 
2018   PetscFunctionBegin;
2019   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2020   PetscValidType(mat,1);
2021   PetscValidScalarPointer(rows,4);
2022   PetscValidScalarPointer(v,5);
2023 #if defined(PETSC_USE_DEBUG)
2024   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2025 #endif
2026 
2027   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2028   if (mat->ops->setvaluesbatch) {
2029     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2030   } else {
2031     PetscInt b;
2032     for (b = 0; b < nb; ++b) {
2033       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2034     }
2035   }
2036   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2037   PetscFunctionReturn(0);
2038 }
2039 
2040 /*@
2041    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2042    the routine MatSetValuesLocal() to allow users to insert matrix entries
2043    using a local (per-processor) numbering.
2044 
2045    Not Collective
2046 
2047    Input Parameters:
2048 +  x - the matrix
2049 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2050 - cmapping - column mapping
2051 
2052    Level: intermediate
2053 
2054    Concepts: matrices^local to global mapping
2055    Concepts: local to global mapping^for matrices
2056 
2057 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2058 @*/
2059 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2060 {
2061   PetscErrorCode ierr;
2062 
2063   PetscFunctionBegin;
2064   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2065   PetscValidType(x,1);
2066   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2067   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2068 
2069   if (x->ops->setlocaltoglobalmapping) {
2070     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2071   } else {
2072     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2073     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2074   }
2075   PetscFunctionReturn(0);
2076 }
2077 
2078 
2079 /*@
2080    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2081 
2082    Not Collective
2083 
2084    Input Parameters:
2085 .  A - the matrix
2086 
2087    Output Parameters:
2088 + rmapping - row mapping
2089 - cmapping - column mapping
2090 
2091    Level: advanced
2092 
2093    Concepts: matrices^local to global mapping
2094    Concepts: local to global mapping^for matrices
2095 
2096 .seealso:  MatSetValuesLocal()
2097 @*/
2098 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2099 {
2100   PetscFunctionBegin;
2101   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2102   PetscValidType(A,1);
2103   if (rmapping) PetscValidPointer(rmapping,2);
2104   if (cmapping) PetscValidPointer(cmapping,3);
2105   if (rmapping) *rmapping = A->rmap->mapping;
2106   if (cmapping) *cmapping = A->cmap->mapping;
2107   PetscFunctionReturn(0);
2108 }
2109 
2110 /*@
2111    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2112 
2113    Not Collective
2114 
2115    Input Parameters:
2116 .  A - the matrix
2117 
2118    Output Parameters:
2119 + rmap - row layout
2120 - cmap - column layout
2121 
2122    Level: advanced
2123 
2124 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2125 @*/
2126 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2127 {
2128   PetscFunctionBegin;
2129   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2130   PetscValidType(A,1);
2131   if (rmap) PetscValidPointer(rmap,2);
2132   if (cmap) PetscValidPointer(cmap,3);
2133   if (rmap) *rmap = A->rmap;
2134   if (cmap) *cmap = A->cmap;
2135   PetscFunctionReturn(0);
2136 }
2137 
2138 /*@C
2139    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2140    using a local ordering of the nodes.
2141 
2142    Not Collective
2143 
2144    Input Parameters:
2145 +  mat - the matrix
2146 .  nrow, irow - number of rows and their local indices
2147 .  ncol, icol - number of columns and their local indices
2148 .  y -  a logically two-dimensional array of values
2149 -  addv - either INSERT_VALUES or ADD_VALUES, where
2150    ADD_VALUES adds values to any existing entries, and
2151    INSERT_VALUES replaces existing entries with new values
2152 
2153    Notes:
2154    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2155       MatSetUp() before using this routine
2156 
2157    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2158 
2159    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2160    options cannot be mixed without intervening calls to the assembly
2161    routines.
2162 
2163    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2164    MUST be called after all calls to MatSetValuesLocal() have been completed.
2165 
2166    Level: intermediate
2167 
2168    Concepts: matrices^putting entries in with local numbering
2169 
2170    Developer Notes:
2171     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2172                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2173 
2174 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2175            MatSetValueLocal()
2176 @*/
2177 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2178 {
2179   PetscErrorCode ierr;
2180 
2181   PetscFunctionBeginHot;
2182   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2183   PetscValidType(mat,1);
2184   MatCheckPreallocated(mat,1);
2185   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2186   PetscValidIntPointer(irow,3);
2187   PetscValidIntPointer(icol,5);
2188   PetscValidScalarPointer(y,6);
2189   if (mat->insertmode == NOT_SET_VALUES) {
2190     mat->insertmode = addv;
2191   }
2192 #if defined(PETSC_USE_DEBUG)
2193   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2194   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2195   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2196 #endif
2197 
2198   if (mat->assembled) {
2199     mat->was_assembled = PETSC_TRUE;
2200     mat->assembled     = PETSC_FALSE;
2201   }
2202   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2203   if (mat->ops->setvalueslocal) {
2204     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2205   } else {
2206     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2207     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2208       irowm = buf; icolm = buf+nrow;
2209     } else {
2210       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2211       irowm = bufr; icolm = bufc;
2212     }
2213     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2214     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2215     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2216     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2217   }
2218   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2219 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2220   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2221     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2222   }
2223 #endif
2224   PetscFunctionReturn(0);
2225 }
2226 
2227 /*@C
2228    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2229    using a local ordering of the nodes a block at a time.
2230 
2231    Not Collective
2232 
2233    Input Parameters:
2234 +  x - the matrix
2235 .  nrow, irow - number of rows and their local indices
2236 .  ncol, icol - number of columns and their local indices
2237 .  y -  a logically two-dimensional array of values
2238 -  addv - either INSERT_VALUES or ADD_VALUES, where
2239    ADD_VALUES adds values to any existing entries, and
2240    INSERT_VALUES replaces existing entries with new values
2241 
2242    Notes:
2243    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2244       MatSetUp() before using this routine
2245 
2246    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2247       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2248 
2249    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2250    options cannot be mixed without intervening calls to the assembly
2251    routines.
2252 
2253    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2254    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2255 
2256    Level: intermediate
2257 
2258    Developer Notes:
2259     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2260                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2261 
2262    Concepts: matrices^putting blocked values in with local numbering
2263 
2264 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2265            MatSetValuesLocal(),  MatSetValuesBlocked()
2266 @*/
2267 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2268 {
2269   PetscErrorCode ierr;
2270 
2271   PetscFunctionBeginHot;
2272   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2273   PetscValidType(mat,1);
2274   MatCheckPreallocated(mat,1);
2275   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2276   PetscValidIntPointer(irow,3);
2277   PetscValidIntPointer(icol,5);
2278   PetscValidScalarPointer(y,6);
2279   if (mat->insertmode == NOT_SET_VALUES) {
2280     mat->insertmode = addv;
2281   }
2282 #if defined(PETSC_USE_DEBUG)
2283   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2284   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2285   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);
2286 #endif
2287 
2288   if (mat->assembled) {
2289     mat->was_assembled = PETSC_TRUE;
2290     mat->assembled     = PETSC_FALSE;
2291   }
2292 #if defined(PETSC_USE_DEBUG)
2293   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2294   if (mat->rmap->mapping) {
2295     PetscInt irbs, rbs;
2296     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2297     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2298     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2299   }
2300   if (mat->cmap->mapping) {
2301     PetscInt icbs, cbs;
2302     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2303     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2304     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2305   }
2306 #endif
2307   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2308   if (mat->ops->setvaluesblockedlocal) {
2309     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2310   } else {
2311     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2312     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2313       irowm = buf; icolm = buf + nrow;
2314     } else {
2315       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2316       irowm = bufr; icolm = bufc;
2317     }
2318     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2319     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2320     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2321     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2322   }
2323   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2324 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2325   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2326     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2327   }
2328 #endif
2329   PetscFunctionReturn(0);
2330 }
2331 
2332 /*@
2333    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2334 
2335    Collective on Mat and Vec
2336 
2337    Input Parameters:
2338 +  mat - the matrix
2339 -  x   - the vector to be multiplied
2340 
2341    Output Parameters:
2342 .  y - the result
2343 
2344    Notes:
2345    The vectors x and y cannot be the same.  I.e., one cannot
2346    call MatMult(A,y,y).
2347 
2348    Level: developer
2349 
2350    Concepts: matrix-vector product
2351 
2352 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2353 @*/
2354 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2355 {
2356   PetscErrorCode ierr;
2357 
2358   PetscFunctionBegin;
2359   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2360   PetscValidType(mat,1);
2361   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2362   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2363 
2364   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2365   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2366   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2367   MatCheckPreallocated(mat,1);
2368 
2369   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2370   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2371   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2372   PetscFunctionReturn(0);
2373 }
2374 
2375 /* --------------------------------------------------------*/
2376 /*@
2377    MatMult - Computes the matrix-vector product, y = Ax.
2378 
2379    Neighbor-wise Collective on Mat and Vec
2380 
2381    Input Parameters:
2382 +  mat - the matrix
2383 -  x   - the vector to be multiplied
2384 
2385    Output Parameters:
2386 .  y - the result
2387 
2388    Notes:
2389    The vectors x and y cannot be the same.  I.e., one cannot
2390    call MatMult(A,y,y).
2391 
2392    Level: beginner
2393 
2394    Concepts: matrix-vector product
2395 
2396 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2397 @*/
2398 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2399 {
2400   PetscErrorCode ierr;
2401 
2402   PetscFunctionBegin;
2403   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2404   PetscValidType(mat,1);
2405   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2406   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2407   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2408   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2409   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2410 #if !defined(PETSC_HAVE_CONSTRAINTS)
2411   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);
2412   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);
2413   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);
2414 #endif
2415   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2416   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2417   MatCheckPreallocated(mat,1);
2418 
2419   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2420   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2421   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2422   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2423   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2424   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2425   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2426   PetscFunctionReturn(0);
2427 }
2428 
2429 /*@
2430    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2431 
2432    Neighbor-wise Collective on Mat and Vec
2433 
2434    Input Parameters:
2435 +  mat - the matrix
2436 -  x   - the vector to be multiplied
2437 
2438    Output Parameters:
2439 .  y - the result
2440 
2441    Notes:
2442    The vectors x and y cannot be the same.  I.e., one cannot
2443    call MatMultTranspose(A,y,y).
2444 
2445    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2446    use MatMultHermitianTranspose()
2447 
2448    Level: beginner
2449 
2450    Concepts: matrix vector product^transpose
2451 
2452 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2453 @*/
2454 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2455 {
2456   PetscErrorCode ierr;
2457 
2458   PetscFunctionBegin;
2459   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2460   PetscValidType(mat,1);
2461   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2462   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2463 
2464   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2465   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2466   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2467 #if !defined(PETSC_HAVE_CONSTRAINTS)
2468   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);
2469   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);
2470 #endif
2471   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2472   MatCheckPreallocated(mat,1);
2473 
2474   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2475   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2476   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2477   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2478   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2479   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2480   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2481   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2482   PetscFunctionReturn(0);
2483 }
2484 
2485 /*@
2486    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2487 
2488    Neighbor-wise Collective on Mat and Vec
2489 
2490    Input Parameters:
2491 +  mat - the matrix
2492 -  x   - the vector to be multilplied
2493 
2494    Output Parameters:
2495 .  y - the result
2496 
2497    Notes:
2498    The vectors x and y cannot be the same.  I.e., one cannot
2499    call MatMultHermitianTranspose(A,y,y).
2500 
2501    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2502 
2503    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2504 
2505    Level: beginner
2506 
2507    Concepts: matrix vector product^transpose
2508 
2509 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2510 @*/
2511 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2512 {
2513   PetscErrorCode ierr;
2514   Vec            w;
2515 
2516   PetscFunctionBegin;
2517   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2518   PetscValidType(mat,1);
2519   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2520   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2521 
2522   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2523   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2524   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2525 #if !defined(PETSC_HAVE_CONSTRAINTS)
2526   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);
2527   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);
2528 #endif
2529   MatCheckPreallocated(mat,1);
2530 
2531   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2532   if (mat->ops->multhermitiantranspose) {
2533     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2534     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2535     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2536   } else {
2537     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2538     ierr = VecCopy(x,w);CHKERRQ(ierr);
2539     ierr = VecConjugate(w);CHKERRQ(ierr);
2540     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2541     ierr = VecDestroy(&w);CHKERRQ(ierr);
2542     ierr = VecConjugate(y);CHKERRQ(ierr);
2543   }
2544   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2545   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2546   PetscFunctionReturn(0);
2547 }
2548 
2549 /*@
2550     MatMultAdd -  Computes v3 = v2 + A * v1.
2551 
2552     Neighbor-wise Collective on Mat and Vec
2553 
2554     Input Parameters:
2555 +   mat - the matrix
2556 -   v1, v2 - the vectors
2557 
2558     Output Parameters:
2559 .   v3 - the result
2560 
2561     Notes:
2562     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2563     call MatMultAdd(A,v1,v2,v1).
2564 
2565     Level: beginner
2566 
2567     Concepts: matrix vector product^addition
2568 
2569 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2570 @*/
2571 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2572 {
2573   PetscErrorCode ierr;
2574 
2575   PetscFunctionBegin;
2576   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2577   PetscValidType(mat,1);
2578   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2579   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2580   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2581 
2582   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2583   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2584   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);
2585   /* 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);
2586      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); */
2587   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);
2588   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);
2589   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2590   MatCheckPreallocated(mat,1);
2591 
2592   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2593   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2594   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2595   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2596   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2597   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2598   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2599   PetscFunctionReturn(0);
2600 }
2601 
2602 /*@
2603    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2604 
2605    Neighbor-wise Collective on Mat and Vec
2606 
2607    Input Parameters:
2608 +  mat - the matrix
2609 -  v1, v2 - the vectors
2610 
2611    Output Parameters:
2612 .  v3 - the result
2613 
2614    Notes:
2615    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2616    call MatMultTransposeAdd(A,v1,v2,v1).
2617 
2618    Level: beginner
2619 
2620    Concepts: matrix vector product^transpose and addition
2621 
2622 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2623 @*/
2624 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2625 {
2626   PetscErrorCode ierr;
2627 
2628   PetscFunctionBegin;
2629   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2630   PetscValidType(mat,1);
2631   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2632   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2633   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2634 
2635   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2636   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2637   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2638   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2639   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);
2640   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);
2641   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);
2642   MatCheckPreallocated(mat,1);
2643 
2644   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2645   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2646   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2647   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2648   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2649   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2650   PetscFunctionReturn(0);
2651 }
2652 
2653 /*@
2654    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2655 
2656    Neighbor-wise Collective on Mat and Vec
2657 
2658    Input Parameters:
2659 +  mat - the matrix
2660 -  v1, v2 - the vectors
2661 
2662    Output Parameters:
2663 .  v3 - the result
2664 
2665    Notes:
2666    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2667    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2668 
2669    Level: beginner
2670 
2671    Concepts: matrix vector product^transpose and addition
2672 
2673 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2674 @*/
2675 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2676 {
2677   PetscErrorCode ierr;
2678 
2679   PetscFunctionBegin;
2680   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2681   PetscValidType(mat,1);
2682   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2683   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2684   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2685 
2686   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2687   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2688   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2689   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);
2690   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);
2691   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);
2692   MatCheckPreallocated(mat,1);
2693 
2694   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2695   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2696   if (mat->ops->multhermitiantransposeadd) {
2697     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2698   } else {
2699     Vec w,z;
2700     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2701     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2702     ierr = VecConjugate(w);CHKERRQ(ierr);
2703     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2704     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2705     ierr = VecDestroy(&w);CHKERRQ(ierr);
2706     ierr = VecConjugate(z);CHKERRQ(ierr);
2707     if (v2 != v3) {
2708       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2709     } else {
2710       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2711     }
2712     ierr = VecDestroy(&z);CHKERRQ(ierr);
2713   }
2714   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2715   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2716   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2717   PetscFunctionReturn(0);
2718 }
2719 
2720 /*@
2721    MatMultConstrained - The inner multiplication routine for a
2722    constrained matrix P^T A P.
2723 
2724    Neighbor-wise Collective on Mat and Vec
2725 
2726    Input Parameters:
2727 +  mat - the matrix
2728 -  x   - the vector to be multilplied
2729 
2730    Output Parameters:
2731 .  y - the result
2732 
2733    Notes:
2734    The vectors x and y cannot be the same.  I.e., one cannot
2735    call MatMult(A,y,y).
2736 
2737    Level: beginner
2738 
2739 .keywords: matrix, multiply, matrix-vector product, constraint
2740 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2741 @*/
2742 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2743 {
2744   PetscErrorCode ierr;
2745 
2746   PetscFunctionBegin;
2747   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2748   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2749   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2750   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2751   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2752   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2753   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);
2754   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);
2755   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);
2756 
2757   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2758   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2759   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2760   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2761   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2762   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2763   PetscFunctionReturn(0);
2764 }
2765 
2766 /*@
2767    MatMultTransposeConstrained - The inner multiplication routine for a
2768    constrained matrix P^T A^T P.
2769 
2770    Neighbor-wise Collective on Mat and Vec
2771 
2772    Input Parameters:
2773 +  mat - the matrix
2774 -  x   - the vector to be multilplied
2775 
2776    Output Parameters:
2777 .  y - the result
2778 
2779    Notes:
2780    The vectors x and y cannot be the same.  I.e., one cannot
2781    call MatMult(A,y,y).
2782 
2783    Level: beginner
2784 
2785 .keywords: matrix, multiply, matrix-vector product, constraint
2786 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2787 @*/
2788 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2789 {
2790   PetscErrorCode ierr;
2791 
2792   PetscFunctionBegin;
2793   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2794   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2795   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2796   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2797   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2798   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2799   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);
2800   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);
2801 
2802   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2803   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2804   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2805   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2806   PetscFunctionReturn(0);
2807 }
2808 
2809 /*@C
2810    MatGetFactorType - gets the type of factorization it is
2811 
2812    Not Collective
2813 
2814    Input Parameters:
2815 .  mat - the matrix
2816 
2817    Output Parameters:
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(), MatSetFactorType()
2823 @*/
2824 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2825 {
2826   PetscFunctionBegin;
2827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2828   PetscValidType(mat,1);
2829   PetscValidPointer(t,2);
2830   *t = mat->factortype;
2831   PetscFunctionReturn(0);
2832 }
2833 
2834 /*@C
2835    MatSetFactorType - sets the type of factorization it is
2836 
2837    Logically Collective on Mat
2838 
2839    Input Parameters:
2840 +  mat - the matrix
2841 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2842 
2843    Level: intermediate
2844 
2845 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2846 @*/
2847 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2848 {
2849   PetscFunctionBegin;
2850   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2851   PetscValidType(mat,1);
2852   mat->factortype = t;
2853   PetscFunctionReturn(0);
2854 }
2855 
2856 /* ------------------------------------------------------------*/
2857 /*@C
2858    MatGetInfo - Returns information about matrix storage (number of
2859    nonzeros, memory, etc.).
2860 
2861    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2862 
2863    Input Parameters:
2864 .  mat - the matrix
2865 
2866    Output Parameters:
2867 +  flag - flag indicating the type of parameters to be returned
2868    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2869    MAT_GLOBAL_SUM - sum over all processors)
2870 -  info - matrix information context
2871 
2872    Notes:
2873    The MatInfo context contains a variety of matrix data, including
2874    number of nonzeros allocated and used, number of mallocs during
2875    matrix assembly, etc.  Additional information for factored matrices
2876    is provided (such as the fill ratio, number of mallocs during
2877    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2878    when using the runtime options
2879 $       -info -mat_view ::ascii_info
2880 
2881    Example for C/C++ Users:
2882    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2883    data within the MatInfo context.  For example,
2884 .vb
2885       MatInfo info;
2886       Mat     A;
2887       double  mal, nz_a, nz_u;
2888 
2889       MatGetInfo(A,MAT_LOCAL,&info);
2890       mal  = info.mallocs;
2891       nz_a = info.nz_allocated;
2892 .ve
2893 
2894    Example for Fortran Users:
2895    Fortran users should declare info as a double precision
2896    array of dimension MAT_INFO_SIZE, and then extract the parameters
2897    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2898    a complete list of parameter names.
2899 .vb
2900       double  precision info(MAT_INFO_SIZE)
2901       double  precision mal, nz_a
2902       Mat     A
2903       integer ierr
2904 
2905       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2906       mal = info(MAT_INFO_MALLOCS)
2907       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2908 .ve
2909 
2910     Level: intermediate
2911 
2912     Concepts: matrices^getting information on
2913 
2914     Developer Note: fortran interface is not autogenerated as the f90
2915     interface defintion cannot be generated correctly [due to MatInfo]
2916 
2917 .seealso: MatStashGetInfo()
2918 
2919 @*/
2920 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2921 {
2922   PetscErrorCode ierr;
2923 
2924   PetscFunctionBegin;
2925   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2926   PetscValidType(mat,1);
2927   PetscValidPointer(info,3);
2928   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2929   MatCheckPreallocated(mat,1);
2930   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2931   PetscFunctionReturn(0);
2932 }
2933 
2934 /*
2935    This is used by external packages where it is not easy to get the info from the actual
2936    matrix factorization.
2937 */
2938 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2939 {
2940   PetscErrorCode ierr;
2941 
2942   PetscFunctionBegin;
2943   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2944   PetscFunctionReturn(0);
2945 }
2946 
2947 /* ----------------------------------------------------------*/
2948 
2949 /*@C
2950    MatLUFactor - Performs in-place LU factorization of matrix.
2951 
2952    Collective on Mat
2953 
2954    Input Parameters:
2955 +  mat - the matrix
2956 .  row - row permutation
2957 .  col - column permutation
2958 -  info - options for factorization, includes
2959 $          fill - expected fill as ratio of original fill.
2960 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2961 $                   Run with the option -info to determine an optimal value to use
2962 
2963    Notes:
2964    Most users should employ the simplified KSP interface for linear solvers
2965    instead of working directly with matrix algebra routines such as this.
2966    See, e.g., KSPCreate().
2967 
2968    This changes the state of the matrix to a factored matrix; it cannot be used
2969    for example with MatSetValues() unless one first calls MatSetUnfactored().
2970 
2971    Level: developer
2972 
2973    Concepts: matrices^LU factorization
2974 
2975 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2976           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2977 
2978     Developer Note: fortran interface is not autogenerated as the f90
2979     interface defintion cannot be generated correctly [due to MatFactorInfo]
2980 
2981 @*/
2982 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2983 {
2984   PetscErrorCode ierr;
2985   MatFactorInfo  tinfo;
2986 
2987   PetscFunctionBegin;
2988   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2989   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2990   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2991   if (info) PetscValidPointer(info,4);
2992   PetscValidType(mat,1);
2993   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2994   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2995   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2996   MatCheckPreallocated(mat,1);
2997   if (!info) {
2998     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2999     info = &tinfo;
3000   }
3001 
3002   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
3003   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
3004   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
3005   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3006   PetscFunctionReturn(0);
3007 }
3008 
3009 /*@C
3010    MatILUFactor - Performs in-place ILU factorization of matrix.
3011 
3012    Collective on Mat
3013 
3014    Input Parameters:
3015 +  mat - the matrix
3016 .  row - row permutation
3017 .  col - column permutation
3018 -  info - structure containing
3019 $      levels - number of levels of fill.
3020 $      expected fill - as ratio of original fill.
3021 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3022                 missing diagonal entries)
3023 
3024    Notes:
3025    Probably really in-place only when level of fill is zero, otherwise allocates
3026    new space to store factored matrix and deletes previous memory.
3027 
3028    Most users should employ the simplified KSP interface for linear solvers
3029    instead of working directly with matrix algebra routines such as this.
3030    See, e.g., KSPCreate().
3031 
3032    Level: developer
3033 
3034    Concepts: matrices^ILU factorization
3035 
3036 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3037 
3038     Developer Note: fortran interface is not autogenerated as the f90
3039     interface defintion cannot be generated correctly [due to MatFactorInfo]
3040 
3041 @*/
3042 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3043 {
3044   PetscErrorCode ierr;
3045 
3046   PetscFunctionBegin;
3047   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3048   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3049   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3050   PetscValidPointer(info,4);
3051   PetscValidType(mat,1);
3052   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3053   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3054   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3055   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3056   MatCheckPreallocated(mat,1);
3057 
3058   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3059   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3060   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3061   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3062   PetscFunctionReturn(0);
3063 }
3064 
3065 /*@C
3066    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3067    Call this routine before calling MatLUFactorNumeric().
3068 
3069    Collective on Mat
3070 
3071    Input Parameters:
3072 +  fact - the factor matrix obtained with MatGetFactor()
3073 .  mat - the matrix
3074 .  row, col - row and column permutations
3075 -  info - options for factorization, includes
3076 $          fill - expected fill as ratio of original fill.
3077 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3078 $                   Run with the option -info to determine an optimal value to use
3079 
3080 
3081    Notes:
3082     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3083 
3084    Most users should employ the simplified KSP interface for linear solvers
3085    instead of working directly with matrix algebra routines such as this.
3086    See, e.g., KSPCreate().
3087 
3088    Level: developer
3089 
3090    Concepts: matrices^LU symbolic factorization
3091 
3092 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3093 
3094     Developer Note: fortran interface is not autogenerated as the f90
3095     interface defintion cannot be generated correctly [due to MatFactorInfo]
3096 
3097 @*/
3098 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3099 {
3100   PetscErrorCode ierr;
3101 
3102   PetscFunctionBegin;
3103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3104   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3105   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3106   if (info) PetscValidPointer(info,4);
3107   PetscValidType(mat,1);
3108   PetscValidPointer(fact,5);
3109   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3110   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3111   if (!(fact)->ops->lufactorsymbolic) {
3112     MatSolverType spackage;
3113     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3114     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3115   }
3116   MatCheckPreallocated(mat,2);
3117 
3118   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3119   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3120   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3121   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3122   PetscFunctionReturn(0);
3123 }
3124 
3125 /*@C
3126    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3127    Call this routine after first calling MatLUFactorSymbolic().
3128 
3129    Collective on Mat
3130 
3131    Input Parameters:
3132 +  fact - the factor matrix obtained with MatGetFactor()
3133 .  mat - the matrix
3134 -  info - options for factorization
3135 
3136    Notes:
3137    See MatLUFactor() for in-place factorization.  See
3138    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3139 
3140    Most users should employ the simplified KSP interface for linear solvers
3141    instead of working directly with matrix algebra routines such as this.
3142    See, e.g., KSPCreate().
3143 
3144    Level: developer
3145 
3146    Concepts: matrices^LU numeric factorization
3147 
3148 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3149 
3150     Developer Note: fortran interface is not autogenerated as the f90
3151     interface defintion cannot be generated correctly [due to MatFactorInfo]
3152 
3153 @*/
3154 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3155 {
3156   PetscErrorCode ierr;
3157 
3158   PetscFunctionBegin;
3159   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3160   PetscValidType(mat,1);
3161   PetscValidPointer(fact,2);
3162   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3163   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3164   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);
3165 
3166   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3167   MatCheckPreallocated(mat,2);
3168   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3169   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3170   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3171   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3172   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3173   PetscFunctionReturn(0);
3174 }
3175 
3176 /*@C
3177    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3178    symmetric matrix.
3179 
3180    Collective on Mat
3181 
3182    Input Parameters:
3183 +  mat - the matrix
3184 .  perm - row and column permutations
3185 -  f - expected fill as ratio of original fill
3186 
3187    Notes:
3188    See MatLUFactor() for the nonsymmetric case.  See also
3189    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3190 
3191    Most users should employ the simplified KSP interface for linear solvers
3192    instead of working directly with matrix algebra routines such as this.
3193    See, e.g., KSPCreate().
3194 
3195    Level: developer
3196 
3197    Concepts: matrices^Cholesky factorization
3198 
3199 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3200           MatGetOrdering()
3201 
3202     Developer Note: fortran interface is not autogenerated as the f90
3203     interface defintion cannot be generated correctly [due to MatFactorInfo]
3204 
3205 @*/
3206 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3207 {
3208   PetscErrorCode ierr;
3209 
3210   PetscFunctionBegin;
3211   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3212   PetscValidType(mat,1);
3213   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3214   if (info) PetscValidPointer(info,3);
3215   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3216   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3217   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3218   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);
3219   MatCheckPreallocated(mat,1);
3220 
3221   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3222   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3223   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3224   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3225   PetscFunctionReturn(0);
3226 }
3227 
3228 /*@C
3229    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3230    of a symmetric matrix.
3231 
3232    Collective on Mat
3233 
3234    Input Parameters:
3235 +  fact - the factor matrix obtained with MatGetFactor()
3236 .  mat - the matrix
3237 .  perm - row and column permutations
3238 -  info - options for factorization, includes
3239 $          fill - expected fill as ratio of original fill.
3240 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3241 $                   Run with the option -info to determine an optimal value to use
3242 
3243    Notes:
3244    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3245    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3246 
3247    Most users should employ the simplified KSP interface for linear solvers
3248    instead of working directly with matrix algebra routines such as this.
3249    See, e.g., KSPCreate().
3250 
3251    Level: developer
3252 
3253    Concepts: matrices^Cholesky symbolic factorization
3254 
3255 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3256           MatGetOrdering()
3257 
3258     Developer Note: fortran interface is not autogenerated as the f90
3259     interface defintion cannot be generated correctly [due to MatFactorInfo]
3260 
3261 @*/
3262 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3263 {
3264   PetscErrorCode ierr;
3265 
3266   PetscFunctionBegin;
3267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3268   PetscValidType(mat,1);
3269   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3270   if (info) PetscValidPointer(info,3);
3271   PetscValidPointer(fact,4);
3272   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3273   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3274   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3275   if (!(fact)->ops->choleskyfactorsymbolic) {
3276     MatSolverType spackage;
3277     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3278     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3279   }
3280   MatCheckPreallocated(mat,2);
3281 
3282   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3283   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3284   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3285   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3286   PetscFunctionReturn(0);
3287 }
3288 
3289 /*@C
3290    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3291    of a symmetric matrix. Call this routine after first calling
3292    MatCholeskyFactorSymbolic().
3293 
3294    Collective on Mat
3295 
3296    Input Parameters:
3297 +  fact - the factor matrix obtained with MatGetFactor()
3298 .  mat - the initial matrix
3299 .  info - options for factorization
3300 -  fact - the symbolic factor of mat
3301 
3302 
3303    Notes:
3304    Most users should employ the simplified KSP interface for linear solvers
3305    instead of working directly with matrix algebra routines such as this.
3306    See, e.g., KSPCreate().
3307 
3308    Level: developer
3309 
3310    Concepts: matrices^Cholesky numeric factorization
3311 
3312 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3313 
3314     Developer Note: fortran interface is not autogenerated as the f90
3315     interface defintion cannot be generated correctly [due to MatFactorInfo]
3316 
3317 @*/
3318 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3319 {
3320   PetscErrorCode ierr;
3321 
3322   PetscFunctionBegin;
3323   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3324   PetscValidType(mat,1);
3325   PetscValidPointer(fact,2);
3326   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3327   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3328   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3329   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);
3330   MatCheckPreallocated(mat,2);
3331 
3332   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3333   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3334   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3335   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3336   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3337   PetscFunctionReturn(0);
3338 }
3339 
3340 /* ----------------------------------------------------------------*/
3341 /*@
3342    MatSolve - Solves A x = b, given a factored matrix.
3343 
3344    Neighbor-wise Collective on Mat and Vec
3345 
3346    Input Parameters:
3347 +  mat - the factored matrix
3348 -  b - the right-hand-side vector
3349 
3350    Output Parameter:
3351 .  x - the result vector
3352 
3353    Notes:
3354    The vectors b and x cannot be the same.  I.e., one cannot
3355    call MatSolve(A,x,x).
3356 
3357    Notes:
3358    Most users should employ the simplified KSP interface for linear solvers
3359    instead of working directly with matrix algebra routines such as this.
3360    See, e.g., KSPCreate().
3361 
3362    Level: developer
3363 
3364    Concepts: matrices^triangular solves
3365 
3366 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3367 @*/
3368 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3369 {
3370   PetscErrorCode ierr;
3371 
3372   PetscFunctionBegin;
3373   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3374   PetscValidType(mat,1);
3375   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3376   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3377   PetscCheckSameComm(mat,1,b,2);
3378   PetscCheckSameComm(mat,1,x,3);
3379   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3380   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);
3381   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);
3382   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);
3383   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3384   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3385   MatCheckPreallocated(mat,1);
3386 
3387   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3388   if (mat->factorerrortype) {
3389     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3390     ierr = VecSetInf(x);CHKERRQ(ierr);
3391   } else {
3392     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3393     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3394   }
3395   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3396   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3397   PetscFunctionReturn(0);
3398 }
3399 
3400 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3401 {
3402   PetscErrorCode ierr;
3403   Vec            b,x;
3404   PetscInt       m,N,i;
3405   PetscScalar    *bb,*xx;
3406   PetscBool      flg;
3407 
3408   PetscFunctionBegin;
3409   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3410   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3411   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3412   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3413 
3414   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3415   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3416   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3417   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3418   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3419   for (i=0; i<N; i++) {
3420     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3421     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3422     if (trans) {
3423       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3424     } else {
3425       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3426     }
3427     ierr = VecResetArray(x);CHKERRQ(ierr);
3428     ierr = VecResetArray(b);CHKERRQ(ierr);
3429   }
3430   ierr = VecDestroy(&b);CHKERRQ(ierr);
3431   ierr = VecDestroy(&x);CHKERRQ(ierr);
3432   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3433   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3434   PetscFunctionReturn(0);
3435 }
3436 
3437 /*@
3438    MatMatSolve - Solves A X = B, given a factored matrix.
3439 
3440    Neighbor-wise Collective on Mat
3441 
3442    Input Parameters:
3443 +  A - the factored matrix
3444 -  B - the right-hand-side matrix  (dense matrix)
3445 
3446    Output Parameter:
3447 .  X - the result matrix (dense matrix)
3448 
3449    Notes:
3450    The matrices b and x cannot be the same.  I.e., one cannot
3451    call MatMatSolve(A,x,x).
3452 
3453    Notes:
3454    Most users should usually employ the simplified KSP interface for linear solvers
3455    instead of working directly with matrix algebra routines such as this.
3456    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3457    at a time.
3458 
3459    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3460    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3461 
3462    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3463 
3464    Level: developer
3465 
3466    Concepts: matrices^triangular solves
3467 
3468 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3469 @*/
3470 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3471 {
3472   PetscErrorCode ierr;
3473 
3474   PetscFunctionBegin;
3475   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3476   PetscValidType(A,1);
3477   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3478   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3479   PetscCheckSameComm(A,1,B,2);
3480   PetscCheckSameComm(A,1,X,3);
3481   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3482   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);
3483   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);
3484   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");
3485   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3486   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3487   MatCheckPreallocated(A,1);
3488 
3489   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3490   if (!A->ops->matsolve) {
3491     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3492     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3493   } else {
3494     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3495   }
3496   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3497   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3498   PetscFunctionReturn(0);
3499 }
3500 
3501 /*@
3502    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3503 
3504    Neighbor-wise Collective on Mat
3505 
3506    Input Parameters:
3507 +  A - the factored matrix
3508 -  B - the right-hand-side matrix  (dense matrix)
3509 
3510    Output Parameter:
3511 .  X - the result matrix (dense matrix)
3512 
3513    Notes:
3514    The matrices B and X cannot be the same.  I.e., one cannot
3515    call MatMatSolveTranspose(A,X,X).
3516 
3517    Notes:
3518    Most users should usually employ the simplified KSP interface for linear solvers
3519    instead of working directly with matrix algebra routines such as this.
3520    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3521    at a time.
3522 
3523    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3524 
3525    Level: developer
3526 
3527    Concepts: matrices^triangular solves
3528 
3529 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3530 @*/
3531 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3532 {
3533   PetscErrorCode ierr;
3534 
3535   PetscFunctionBegin;
3536   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3537   PetscValidType(A,1);
3538   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3539   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3540   PetscCheckSameComm(A,1,B,2);
3541   PetscCheckSameComm(A,1,X,3);
3542   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3543   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);
3544   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);
3545   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);
3546   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");
3547   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3548   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3549   MatCheckPreallocated(A,1);
3550 
3551   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3552   if (!A->ops->matsolvetranspose) {
3553     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3554     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3555   } else {
3556     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3557   }
3558   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3559   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3560   PetscFunctionReturn(0);
3561 }
3562 
3563 /*@
3564    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3565 
3566    Neighbor-wise Collective on Mat
3567 
3568    Input Parameters:
3569 +  A - the factored matrix
3570 -  Bt - the transpose of right-hand-side matrix
3571 
3572    Output Parameter:
3573 .  X - the result matrix (dense matrix)
3574 
3575    Notes:
3576    Most users should usually employ the simplified KSP interface for linear solvers
3577    instead of working directly with matrix algebra routines such as this.
3578    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3579    at a time.
3580 
3581    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().
3582 
3583    Level: developer
3584 
3585    Concepts: matrices^triangular solves
3586 
3587 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3588 @*/
3589 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3590 {
3591   PetscErrorCode ierr;
3592 
3593   PetscFunctionBegin;
3594   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3595   PetscValidType(A,1);
3596   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3597   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3598   PetscCheckSameComm(A,1,Bt,2);
3599   PetscCheckSameComm(A,1,X,3);
3600 
3601   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3602   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);
3603   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);
3604   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");
3605   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3606   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3607   MatCheckPreallocated(A,1);
3608 
3609   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3610   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3611   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3612   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3613   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3614   PetscFunctionReturn(0);
3615 }
3616 
3617 /*@
3618    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3619                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3620 
3621    Neighbor-wise Collective on Mat and Vec
3622 
3623    Input Parameters:
3624 +  mat - the factored matrix
3625 -  b - the right-hand-side vector
3626 
3627    Output Parameter:
3628 .  x - the result vector
3629 
3630    Notes:
3631    MatSolve() should be used for most applications, as it performs
3632    a forward solve followed by a backward solve.
3633 
3634    The vectors b and x cannot be the same,  i.e., one cannot
3635    call MatForwardSolve(A,x,x).
3636 
3637    For matrix in seqsbaij format with block size larger than 1,
3638    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3639    MatForwardSolve() solves U^T*D y = b, and
3640    MatBackwardSolve() solves U x = y.
3641    Thus they do not provide a symmetric preconditioner.
3642 
3643    Most users should employ the simplified KSP interface for linear solvers
3644    instead of working directly with matrix algebra routines such as this.
3645    See, e.g., KSPCreate().
3646 
3647    Level: developer
3648 
3649    Concepts: matrices^forward solves
3650 
3651 .seealso: MatSolve(), MatBackwardSolve()
3652 @*/
3653 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3654 {
3655   PetscErrorCode ierr;
3656 
3657   PetscFunctionBegin;
3658   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3659   PetscValidType(mat,1);
3660   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3661   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3662   PetscCheckSameComm(mat,1,b,2);
3663   PetscCheckSameComm(mat,1,x,3);
3664   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3665   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);
3666   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);
3667   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);
3668   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3669   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3670   MatCheckPreallocated(mat,1);
3671 
3672   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3673   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3674   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3675   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3676   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3677   PetscFunctionReturn(0);
3678 }
3679 
3680 /*@
3681    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3682                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3683 
3684    Neighbor-wise Collective on Mat and Vec
3685 
3686    Input Parameters:
3687 +  mat - the factored matrix
3688 -  b - the right-hand-side vector
3689 
3690    Output Parameter:
3691 .  x - the result vector
3692 
3693    Notes:
3694    MatSolve() should be used for most applications, as it performs
3695    a forward solve followed by a backward solve.
3696 
3697    The vectors b and x cannot be the same.  I.e., one cannot
3698    call MatBackwardSolve(A,x,x).
3699 
3700    For matrix in seqsbaij format with block size larger than 1,
3701    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3702    MatForwardSolve() solves U^T*D y = b, and
3703    MatBackwardSolve() solves U x = y.
3704    Thus they do not provide a symmetric preconditioner.
3705 
3706    Most users should employ the simplified KSP interface for linear solvers
3707    instead of working directly with matrix algebra routines such as this.
3708    See, e.g., KSPCreate().
3709 
3710    Level: developer
3711 
3712    Concepts: matrices^backward solves
3713 
3714 .seealso: MatSolve(), MatForwardSolve()
3715 @*/
3716 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3717 {
3718   PetscErrorCode ierr;
3719 
3720   PetscFunctionBegin;
3721   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3722   PetscValidType(mat,1);
3723   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3724   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3725   PetscCheckSameComm(mat,1,b,2);
3726   PetscCheckSameComm(mat,1,x,3);
3727   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3728   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);
3729   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);
3730   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);
3731   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3732   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3733   MatCheckPreallocated(mat,1);
3734 
3735   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3736   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3737   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3738   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3739   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3740   PetscFunctionReturn(0);
3741 }
3742 
3743 /*@
3744    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3745 
3746    Neighbor-wise Collective on Mat and Vec
3747 
3748    Input Parameters:
3749 +  mat - the factored matrix
3750 .  b - the right-hand-side vector
3751 -  y - the vector to be added to
3752 
3753    Output Parameter:
3754 .  x - the result vector
3755 
3756    Notes:
3757    The vectors b and x cannot be the same.  I.e., one cannot
3758    call MatSolveAdd(A,x,y,x).
3759 
3760    Most users should employ the simplified KSP interface for linear solvers
3761    instead of working directly with matrix algebra routines such as this.
3762    See, e.g., KSPCreate().
3763 
3764    Level: developer
3765 
3766    Concepts: matrices^triangular solves
3767 
3768 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3769 @*/
3770 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3771 {
3772   PetscScalar    one = 1.0;
3773   Vec            tmp;
3774   PetscErrorCode ierr;
3775 
3776   PetscFunctionBegin;
3777   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3778   PetscValidType(mat,1);
3779   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3780   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3781   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3782   PetscCheckSameComm(mat,1,b,2);
3783   PetscCheckSameComm(mat,1,y,2);
3784   PetscCheckSameComm(mat,1,x,3);
3785   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3786   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);
3787   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);
3788   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);
3789   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);
3790   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);
3791   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3792   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3793   MatCheckPreallocated(mat,1);
3794 
3795   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3796   if (mat->ops->solveadd) {
3797     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3798   } else {
3799     /* do the solve then the add manually */
3800     if (x != y) {
3801       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3802       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3803     } else {
3804       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3805       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3806       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3807       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3808       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3809       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3810     }
3811   }
3812   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3813   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3814   PetscFunctionReturn(0);
3815 }
3816 
3817 /*@
3818    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3819 
3820    Neighbor-wise Collective on Mat and Vec
3821 
3822    Input Parameters:
3823 +  mat - the factored matrix
3824 -  b - the right-hand-side vector
3825 
3826    Output Parameter:
3827 .  x - the result vector
3828 
3829    Notes:
3830    The vectors b and x cannot be the same.  I.e., one cannot
3831    call MatSolveTranspose(A,x,x).
3832 
3833    Most users should employ the simplified KSP interface for linear solvers
3834    instead of working directly with matrix algebra routines such as this.
3835    See, e.g., KSPCreate().
3836 
3837    Level: developer
3838 
3839    Concepts: matrices^triangular solves
3840 
3841 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3842 @*/
3843 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3844 {
3845   PetscErrorCode ierr;
3846 
3847   PetscFunctionBegin;
3848   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3849   PetscValidType(mat,1);
3850   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3851   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3852   PetscCheckSameComm(mat,1,b,2);
3853   PetscCheckSameComm(mat,1,x,3);
3854   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3855   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);
3856   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);
3857   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3858   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3859   MatCheckPreallocated(mat,1);
3860   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3861   if (mat->factorerrortype) {
3862     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3863     ierr = VecSetInf(x);CHKERRQ(ierr);
3864   } else {
3865     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3866     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3867   }
3868   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3869   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3870   PetscFunctionReturn(0);
3871 }
3872 
3873 /*@
3874    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3875                       factored matrix.
3876 
3877    Neighbor-wise Collective on Mat and Vec
3878 
3879    Input Parameters:
3880 +  mat - the factored matrix
3881 .  b - the right-hand-side vector
3882 -  y - the vector to be added to
3883 
3884    Output Parameter:
3885 .  x - the result vector
3886 
3887    Notes:
3888    The vectors b and x cannot be the same.  I.e., one cannot
3889    call MatSolveTransposeAdd(A,x,y,x).
3890 
3891    Most users should employ the simplified KSP interface for linear solvers
3892    instead of working directly with matrix algebra routines such as this.
3893    See, e.g., KSPCreate().
3894 
3895    Level: developer
3896 
3897    Concepts: matrices^triangular solves
3898 
3899 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3900 @*/
3901 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3902 {
3903   PetscScalar    one = 1.0;
3904   PetscErrorCode ierr;
3905   Vec            tmp;
3906 
3907   PetscFunctionBegin;
3908   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3909   PetscValidType(mat,1);
3910   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3911   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3912   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3913   PetscCheckSameComm(mat,1,b,2);
3914   PetscCheckSameComm(mat,1,y,3);
3915   PetscCheckSameComm(mat,1,x,4);
3916   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3917   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);
3918   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);
3919   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);
3920   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);
3921   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3922   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3923   MatCheckPreallocated(mat,1);
3924 
3925   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3926   if (mat->ops->solvetransposeadd) {
3927     if (mat->factorerrortype) {
3928       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3929       ierr = VecSetInf(x);CHKERRQ(ierr);
3930     } else {
3931       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3932     }
3933   } else {
3934     /* do the solve then the add manually */
3935     if (x != y) {
3936       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3937       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3938     } else {
3939       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3940       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3941       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3942       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3943       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3944       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3945     }
3946   }
3947   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3948   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3949   PetscFunctionReturn(0);
3950 }
3951 /* ----------------------------------------------------------------*/
3952 
3953 /*@
3954    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3955 
3956    Neighbor-wise Collective on Mat and Vec
3957 
3958    Input Parameters:
3959 +  mat - the matrix
3960 .  b - the right hand side
3961 .  omega - the relaxation factor
3962 .  flag - flag indicating the type of SOR (see below)
3963 .  shift -  diagonal shift
3964 .  its - the number of iterations
3965 -  lits - the number of local iterations
3966 
3967    Output Parameters:
3968 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3969 
3970    SOR Flags:
3971 .     SOR_FORWARD_SWEEP - forward SOR
3972 .     SOR_BACKWARD_SWEEP - backward SOR
3973 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3974 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3975 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3976 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3977 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3978          upper/lower triangular part of matrix to
3979          vector (with omega)
3980 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3981 
3982    Notes:
3983    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3984    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3985    on each processor.
3986 
3987    Application programmers will not generally use MatSOR() directly,
3988    but instead will employ the KSP/PC interface.
3989 
3990    Notes:
3991     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3992 
3993    Notes for Advanced Users:
3994    The flags are implemented as bitwise inclusive or operations.
3995    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3996    to specify a zero initial guess for SSOR.
3997 
3998    Most users should employ the simplified KSP interface for linear solvers
3999    instead of working directly with matrix algebra routines such as this.
4000    See, e.g., KSPCreate().
4001 
4002    Vectors x and b CANNOT be the same
4003 
4004    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
4005 
4006    Level: developer
4007 
4008    Concepts: matrices^relaxation
4009    Concepts: matrices^SOR
4010    Concepts: matrices^Gauss-Seidel
4011 
4012 @*/
4013 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4014 {
4015   PetscErrorCode ierr;
4016 
4017   PetscFunctionBegin;
4018   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4019   PetscValidType(mat,1);
4020   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4021   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4022   PetscCheckSameComm(mat,1,b,2);
4023   PetscCheckSameComm(mat,1,x,8);
4024   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4025   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4026   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4027   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);
4028   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);
4029   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);
4030   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4031   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4032   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4033 
4034   MatCheckPreallocated(mat,1);
4035   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4036   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4037   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4038   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4039   PetscFunctionReturn(0);
4040 }
4041 
4042 /*
4043       Default matrix copy routine.
4044 */
4045 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4046 {
4047   PetscErrorCode    ierr;
4048   PetscInt          i,rstart = 0,rend = 0,nz;
4049   const PetscInt    *cwork;
4050   const PetscScalar *vwork;
4051 
4052   PetscFunctionBegin;
4053   if (B->assembled) {
4054     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4055   }
4056   if (str == SAME_NONZERO_PATTERN) {
4057     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4058     for (i=rstart; i<rend; i++) {
4059       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4060       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4061       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4062     }
4063   } else {
4064     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4065   }
4066   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4067   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4068   PetscFunctionReturn(0);
4069 }
4070 
4071 /*@
4072    MatCopy - Copies a matrix to another matrix.
4073 
4074    Collective on Mat
4075 
4076    Input Parameters:
4077 +  A - the matrix
4078 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4079 
4080    Output Parameter:
4081 .  B - where the copy is put
4082 
4083    Notes:
4084    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4085    same nonzero pattern or the routine will crash.
4086 
4087    MatCopy() copies the matrix entries of a matrix to another existing
4088    matrix (after first zeroing the second matrix).  A related routine is
4089    MatConvert(), which first creates a new matrix and then copies the data.
4090 
4091    Level: intermediate
4092 
4093    Concepts: matrices^copying
4094 
4095 .seealso: MatConvert(), MatDuplicate()
4096 
4097 @*/
4098 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4099 {
4100   PetscErrorCode ierr;
4101   PetscInt       i;
4102 
4103   PetscFunctionBegin;
4104   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4105   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4106   PetscValidType(A,1);
4107   PetscValidType(B,2);
4108   PetscCheckSameComm(A,1,B,2);
4109   MatCheckPreallocated(B,2);
4110   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4111   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4112   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);
4113   MatCheckPreallocated(A,1);
4114   if (A == B) PetscFunctionReturn(0);
4115 
4116   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4117   if (A->ops->copy) {
4118     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4119   } else { /* generic conversion */
4120     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4121   }
4122 
4123   B->stencil.dim = A->stencil.dim;
4124   B->stencil.noc = A->stencil.noc;
4125   for (i=0; i<=A->stencil.dim; i++) {
4126     B->stencil.dims[i]   = A->stencil.dims[i];
4127     B->stencil.starts[i] = A->stencil.starts[i];
4128   }
4129 
4130   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4131   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4132   PetscFunctionReturn(0);
4133 }
4134 
4135 /*@C
4136    MatConvert - Converts a matrix to another matrix, either of the same
4137    or different type.
4138 
4139    Collective on Mat
4140 
4141    Input Parameters:
4142 +  mat - the matrix
4143 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4144    same type as the original matrix.
4145 -  reuse - denotes if the destination matrix is to be created or reused.
4146    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
4147    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).
4148 
4149    Output Parameter:
4150 .  M - pointer to place new matrix
4151 
4152    Notes:
4153    MatConvert() first creates a new matrix and then copies the data from
4154    the first matrix.  A related routine is MatCopy(), which copies the matrix
4155    entries of one matrix to another already existing matrix context.
4156 
4157    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4158    the MPI communicator of the generated matrix is always the same as the communicator
4159    of the input matrix.
4160 
4161    Level: intermediate
4162 
4163    Concepts: matrices^converting between storage formats
4164 
4165 .seealso: MatCopy(), MatDuplicate()
4166 @*/
4167 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4168 {
4169   PetscErrorCode ierr;
4170   PetscBool      sametype,issame,flg;
4171   char           convname[256],mtype[256];
4172   Mat            B;
4173 
4174   PetscFunctionBegin;
4175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4176   PetscValidType(mat,1);
4177   PetscValidPointer(M,3);
4178   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4179   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4180   MatCheckPreallocated(mat,1);
4181 
4182   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4183   if (flg) {
4184     newtype = mtype;
4185   }
4186   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4187   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4188   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4189   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");
4190 
4191   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4192 
4193   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4194     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4195   } else {
4196     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4197     const char     *prefix[3] = {"seq","mpi",""};
4198     PetscInt       i;
4199     /*
4200        Order of precedence:
4201        0) See if newtype is a superclass of the current matrix.
4202        1) See if a specialized converter is known to the current matrix.
4203        2) See if a specialized converter is known to the desired matrix class.
4204        3) See if a good general converter is registered for the desired class
4205           (as of 6/27/03 only MATMPIADJ falls into this category).
4206        4) See if a good general converter is known for the current matrix.
4207        5) Use a really basic converter.
4208     */
4209 
4210     /* 0) See if newtype is a superclass of the current matrix.
4211           i.e mat is mpiaij and newtype is aij */
4212     for (i=0; i<2; i++) {
4213       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4214       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4215       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4216       ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr);
4217       if (flg) {
4218         if (reuse == MAT_INPLACE_MATRIX) {
4219           PetscFunctionReturn(0);
4220         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4221           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4222           PetscFunctionReturn(0);
4223         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4224           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4225           PetscFunctionReturn(0);
4226         }
4227       }
4228     }
4229     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4230     for (i=0; i<3; i++) {
4231       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4232       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4233       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4234       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4235       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4236       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4237       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4238       ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4239       if (conv) goto foundconv;
4240     }
4241 
4242     /* 2)  See if a specialized converter is known to the desired matrix class. */
4243     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4244     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4245     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4246     for (i=0; i<3; i++) {
4247       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4248       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4249       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4250       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4251       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4252       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4253       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4254       ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4255       if (conv) {
4256         ierr = MatDestroy(&B);CHKERRQ(ierr);
4257         goto foundconv;
4258       }
4259     }
4260 
4261     /* 3) See if a good general converter is registered for the desired class */
4262     conv = B->ops->convertfrom;
4263     ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr);
4264     ierr = MatDestroy(&B);CHKERRQ(ierr);
4265     if (conv) goto foundconv;
4266 
4267     /* 4) See if a good general converter is known for the current matrix */
4268     if (mat->ops->convert) {
4269       conv = mat->ops->convert;
4270     }
4271     ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr);
4272     if (conv) goto foundconv;
4273 
4274     /* 5) Use a really basic converter. */
4275     ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr);
4276     conv = MatConvert_Basic;
4277 
4278 foundconv:
4279     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4280     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4281     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4282       /* the block sizes must be same if the mappings are copied over */
4283       (*M)->rmap->bs = mat->rmap->bs;
4284       (*M)->cmap->bs = mat->cmap->bs;
4285       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4286       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4287       (*M)->rmap->mapping = mat->rmap->mapping;
4288       (*M)->cmap->mapping = mat->cmap->mapping;
4289     }
4290     (*M)->stencil.dim = mat->stencil.dim;
4291     (*M)->stencil.noc = mat->stencil.noc;
4292     for (i=0; i<=mat->stencil.dim; i++) {
4293       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4294       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4295     }
4296     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4297   }
4298   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4299 
4300   /* Copy Mat options */
4301   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4302   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4303   PetscFunctionReturn(0);
4304 }
4305 
4306 /*@C
4307    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4308 
4309    Not Collective
4310 
4311    Input Parameter:
4312 .  mat - the matrix, must be a factored matrix
4313 
4314    Output Parameter:
4315 .   type - the string name of the package (do not free this string)
4316 
4317    Notes:
4318       In Fortran you pass in a empty string and the package name will be copied into it.
4319     (Make sure the string is long enough)
4320 
4321    Level: intermediate
4322 
4323 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4324 @*/
4325 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4326 {
4327   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4328 
4329   PetscFunctionBegin;
4330   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4331   PetscValidType(mat,1);
4332   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4333   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4334   if (!conv) {
4335     *type = MATSOLVERPETSC;
4336   } else {
4337     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4338   }
4339   PetscFunctionReturn(0);
4340 }
4341 
4342 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4343 struct _MatSolverTypeForSpecifcType {
4344   MatType                        mtype;
4345   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4346   MatSolverTypeForSpecifcType next;
4347 };
4348 
4349 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4350 struct _MatSolverTypeHolder {
4351   char                           *name;
4352   MatSolverTypeForSpecifcType handlers;
4353   MatSolverTypeHolder         next;
4354 };
4355 
4356 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4357 
4358 /*@C
4359    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4360 
4361    Input Parameters:
4362 +    package - name of the package, for example petsc or superlu
4363 .    mtype - the matrix type that works with this package
4364 .    ftype - the type of factorization supported by the package
4365 -    getfactor - routine that will create the factored matrix ready to be used
4366 
4367     Level: intermediate
4368 
4369 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4370 @*/
4371 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4372 {
4373   PetscErrorCode              ierr;
4374   MatSolverTypeHolder         next = MatSolverTypeHolders,prev = NULL;
4375   PetscBool                   flg;
4376   MatSolverTypeForSpecifcType inext,iprev = NULL;
4377 
4378   PetscFunctionBegin;
4379   ierr = MatInitializePackage();CHKERRQ(ierr);
4380   if (!next) {
4381     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4382     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4383     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4384     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4385     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4386     PetscFunctionReturn(0);
4387   }
4388   while (next) {
4389     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4390     if (flg) {
4391       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4392       inext = next->handlers;
4393       while (inext) {
4394         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4395         if (flg) {
4396           inext->getfactor[(int)ftype-1] = getfactor;
4397           PetscFunctionReturn(0);
4398         }
4399         iprev = inext;
4400         inext = inext->next;
4401       }
4402       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4403       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4404       iprev->next->getfactor[(int)ftype-1] = getfactor;
4405       PetscFunctionReturn(0);
4406     }
4407     prev = next;
4408     next = next->next;
4409   }
4410   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4411   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4412   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4413   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4414   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4415   PetscFunctionReturn(0);
4416 }
4417 
4418 /*@C
4419    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4420 
4421    Input Parameters:
4422 +    package - name of the package, for example petsc or superlu
4423 .    ftype - the type of factorization supported by the package
4424 -    mtype - the matrix type that works with this package
4425 
4426    Output Parameters:
4427 +   foundpackage - PETSC_TRUE if the package was registered
4428 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4429 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4430 
4431     Level: intermediate
4432 
4433 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4434 @*/
4435 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4436 {
4437   PetscErrorCode                 ierr;
4438   MatSolverTypeHolder         next = MatSolverTypeHolders;
4439   PetscBool                      flg;
4440   MatSolverTypeForSpecifcType inext;
4441 
4442   PetscFunctionBegin;
4443   if (foundpackage) *foundpackage = PETSC_FALSE;
4444   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4445   if (getfactor)    *getfactor    = NULL;
4446 
4447   if (package) {
4448     while (next) {
4449       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4450       if (flg) {
4451         if (foundpackage) *foundpackage = PETSC_TRUE;
4452         inext = next->handlers;
4453         while (inext) {
4454           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4455           if (flg) {
4456             if (foundmtype) *foundmtype = PETSC_TRUE;
4457             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4458             PetscFunctionReturn(0);
4459           }
4460           inext = inext->next;
4461         }
4462       }
4463       next = next->next;
4464     }
4465   } else {
4466     while (next) {
4467       inext = next->handlers;
4468       while (inext) {
4469         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4470         if (flg && inext->getfactor[(int)ftype-1]) {
4471           if (foundpackage) *foundpackage = PETSC_TRUE;
4472           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4473           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4474           PetscFunctionReturn(0);
4475         }
4476         inext = inext->next;
4477       }
4478       next = next->next;
4479     }
4480   }
4481   PetscFunctionReturn(0);
4482 }
4483 
4484 PetscErrorCode MatSolverTypeDestroy(void)
4485 {
4486   PetscErrorCode              ierr;
4487   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4488   MatSolverTypeForSpecifcType inext,iprev;
4489 
4490   PetscFunctionBegin;
4491   while (next) {
4492     ierr = PetscFree(next->name);CHKERRQ(ierr);
4493     inext = next->handlers;
4494     while (inext) {
4495       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4496       iprev = inext;
4497       inext = inext->next;
4498       ierr = PetscFree(iprev);CHKERRQ(ierr);
4499     }
4500     prev = next;
4501     next = next->next;
4502     ierr = PetscFree(prev);CHKERRQ(ierr);
4503   }
4504   MatSolverTypeHolders = NULL;
4505   PetscFunctionReturn(0);
4506 }
4507 
4508 /*@C
4509    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4510 
4511    Collective on Mat
4512 
4513    Input Parameters:
4514 +  mat - the matrix
4515 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4516 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4517 
4518    Output Parameters:
4519 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4520 
4521    Notes:
4522       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4523      such as pastix, superlu, mumps etc.
4524 
4525       PETSc must have been ./configure to use the external solver, using the option --download-package
4526 
4527    Level: intermediate
4528 
4529 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4530 @*/
4531 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4532 {
4533   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4534   PetscBool      foundpackage,foundmtype;
4535 
4536   PetscFunctionBegin;
4537   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4538   PetscValidType(mat,1);
4539 
4540   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4541   MatCheckPreallocated(mat,1);
4542 
4543   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4544   if (!foundpackage) {
4545     if (type) {
4546       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4547     } else {
4548       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4549     }
4550   }
4551 
4552   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4553   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);
4554 
4555 #if defined(PETSC_USE_COMPLEX)
4556   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");
4557 #endif
4558 
4559   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4560   PetscFunctionReturn(0);
4561 }
4562 
4563 /*@C
4564    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4565 
4566    Not Collective
4567 
4568    Input Parameters:
4569 +  mat - the matrix
4570 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4571 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4572 
4573    Output Parameter:
4574 .    flg - PETSC_TRUE if the factorization is available
4575 
4576    Notes:
4577       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4578      such as pastix, superlu, mumps etc.
4579 
4580       PETSc must have been ./configure to use the external solver, using the option --download-package
4581 
4582    Level: intermediate
4583 
4584 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4585 @*/
4586 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4587 {
4588   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4589 
4590   PetscFunctionBegin;
4591   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4592   PetscValidType(mat,1);
4593 
4594   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4595   MatCheckPreallocated(mat,1);
4596 
4597   *flg = PETSC_FALSE;
4598   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4599   if (gconv) {
4600     *flg = PETSC_TRUE;
4601   }
4602   PetscFunctionReturn(0);
4603 }
4604 
4605 #include <petscdmtypes.h>
4606 
4607 /*@
4608    MatDuplicate - Duplicates a matrix including the non-zero structure.
4609 
4610    Collective on Mat
4611 
4612    Input Parameters:
4613 +  mat - the matrix
4614 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4615         See the manual page for MatDuplicateOption for an explanation of these options.
4616 
4617    Output Parameter:
4618 .  M - pointer to place new matrix
4619 
4620    Level: intermediate
4621 
4622    Concepts: matrices^duplicating
4623 
4624    Notes:
4625     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4626     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.
4627 
4628 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4629 @*/
4630 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4631 {
4632   PetscErrorCode ierr;
4633   Mat            B;
4634   PetscInt       i;
4635   DM             dm;
4636   void           (*viewf)(void);
4637 
4638   PetscFunctionBegin;
4639   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4640   PetscValidType(mat,1);
4641   PetscValidPointer(M,3);
4642   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4643   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4644   MatCheckPreallocated(mat,1);
4645 
4646   *M = 0;
4647   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4648   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4649   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4650   B    = *M;
4651 
4652   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4653   if (viewf) {
4654     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4655   }
4656 
4657   B->stencil.dim = mat->stencil.dim;
4658   B->stencil.noc = mat->stencil.noc;
4659   for (i=0; i<=mat->stencil.dim; i++) {
4660     B->stencil.dims[i]   = mat->stencil.dims[i];
4661     B->stencil.starts[i] = mat->stencil.starts[i];
4662   }
4663 
4664   B->nooffproczerorows = mat->nooffproczerorows;
4665   B->nooffprocentries  = mat->nooffprocentries;
4666 
4667   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4668   if (dm) {
4669     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4670   }
4671   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4672   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4673   PetscFunctionReturn(0);
4674 }
4675 
4676 /*@
4677    MatGetDiagonal - Gets the diagonal of a matrix.
4678 
4679    Logically Collective on Mat and Vec
4680 
4681    Input Parameters:
4682 +  mat - the matrix
4683 -  v - the vector for storing the diagonal
4684 
4685    Output Parameter:
4686 .  v - the diagonal of the matrix
4687 
4688    Level: intermediate
4689 
4690    Note:
4691    Currently only correct in parallel for square matrices.
4692 
4693    Concepts: matrices^accessing diagonals
4694 
4695 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4696 @*/
4697 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4698 {
4699   PetscErrorCode ierr;
4700 
4701   PetscFunctionBegin;
4702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4703   PetscValidType(mat,1);
4704   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4705   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4706   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4707   MatCheckPreallocated(mat,1);
4708 
4709   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4710   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4711   PetscFunctionReturn(0);
4712 }
4713 
4714 /*@C
4715    MatGetRowMin - Gets the minimum value (of the real part) of each
4716         row of the matrix
4717 
4718    Logically Collective on Mat and Vec
4719 
4720    Input Parameters:
4721 .  mat - the matrix
4722 
4723    Output Parameter:
4724 +  v - the vector for storing the maximums
4725 -  idx - the indices of the column found for each row (optional)
4726 
4727    Level: intermediate
4728 
4729    Notes:
4730     The result of this call are the same as if one converted the matrix to dense format
4731       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4732 
4733     This code is only implemented for a couple of matrix formats.
4734 
4735    Concepts: matrices^getting row maximums
4736 
4737 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4738           MatGetRowMax()
4739 @*/
4740 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4741 {
4742   PetscErrorCode ierr;
4743 
4744   PetscFunctionBegin;
4745   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4746   PetscValidType(mat,1);
4747   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4748   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4749   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4750   MatCheckPreallocated(mat,1);
4751 
4752   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4753   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4754   PetscFunctionReturn(0);
4755 }
4756 
4757 /*@C
4758    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4759         row of the matrix
4760 
4761    Logically Collective on Mat and Vec
4762 
4763    Input Parameters:
4764 .  mat - the matrix
4765 
4766    Output Parameter:
4767 +  v - the vector for storing the minimums
4768 -  idx - the indices of the column found for each row (or NULL if not needed)
4769 
4770    Level: intermediate
4771 
4772    Notes:
4773     if a row is completely empty or has only 0.0 values then the idx[] value for that
4774     row is 0 (the first column).
4775 
4776     This code is only implemented for a couple of matrix formats.
4777 
4778    Concepts: matrices^getting row maximums
4779 
4780 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4781 @*/
4782 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4783 {
4784   PetscErrorCode ierr;
4785 
4786   PetscFunctionBegin;
4787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4788   PetscValidType(mat,1);
4789   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4790   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4791   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4792   MatCheckPreallocated(mat,1);
4793   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4794 
4795   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4796   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4797   PetscFunctionReturn(0);
4798 }
4799 
4800 /*@C
4801    MatGetRowMax - Gets the maximum value (of the real part) of each
4802         row of the matrix
4803 
4804    Logically Collective on Mat and Vec
4805 
4806    Input Parameters:
4807 .  mat - the matrix
4808 
4809    Output Parameter:
4810 +  v - the vector for storing the maximums
4811 -  idx - the indices of the column found for each row (optional)
4812 
4813    Level: intermediate
4814 
4815    Notes:
4816     The result of this call are the same as if one converted the matrix to dense format
4817       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4818 
4819     This code is only implemented for a couple of matrix formats.
4820 
4821    Concepts: matrices^getting row maximums
4822 
4823 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4824 @*/
4825 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4826 {
4827   PetscErrorCode ierr;
4828 
4829   PetscFunctionBegin;
4830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4831   PetscValidType(mat,1);
4832   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4833   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4834   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4835   MatCheckPreallocated(mat,1);
4836 
4837   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4838   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4839   PetscFunctionReturn(0);
4840 }
4841 
4842 /*@C
4843    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4844         row of the matrix
4845 
4846    Logically Collective on Mat and Vec
4847 
4848    Input Parameters:
4849 .  mat - the matrix
4850 
4851    Output Parameter:
4852 +  v - the vector for storing the maximums
4853 -  idx - the indices of the column found for each row (or NULL if not needed)
4854 
4855    Level: intermediate
4856 
4857    Notes:
4858     if a row is completely empty or has only 0.0 values then the idx[] value for that
4859     row is 0 (the first column).
4860 
4861     This code is only implemented for a couple of matrix formats.
4862 
4863    Concepts: matrices^getting row maximums
4864 
4865 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4866 @*/
4867 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4868 {
4869   PetscErrorCode ierr;
4870 
4871   PetscFunctionBegin;
4872   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4873   PetscValidType(mat,1);
4874   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4875   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4876   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4877   MatCheckPreallocated(mat,1);
4878   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4879 
4880   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4881   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4882   PetscFunctionReturn(0);
4883 }
4884 
4885 /*@
4886    MatGetRowSum - Gets the sum of each row of the matrix
4887 
4888    Logically or Neighborhood Collective on Mat and Vec
4889 
4890    Input Parameters:
4891 .  mat - the matrix
4892 
4893    Output Parameter:
4894 .  v - the vector for storing the sum of rows
4895 
4896    Level: intermediate
4897 
4898    Notes:
4899     This code is slow since it is not currently specialized for different formats
4900 
4901    Concepts: matrices^getting row sums
4902 
4903 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4904 @*/
4905 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4906 {
4907   Vec            ones;
4908   PetscErrorCode ierr;
4909 
4910   PetscFunctionBegin;
4911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4912   PetscValidType(mat,1);
4913   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4914   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4915   MatCheckPreallocated(mat,1);
4916   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4917   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4918   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4919   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4920   PetscFunctionReturn(0);
4921 }
4922 
4923 /*@
4924    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4925 
4926    Collective on Mat
4927 
4928    Input Parameter:
4929 +  mat - the matrix to transpose
4930 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4931 
4932    Output Parameters:
4933 .  B - the transpose
4934 
4935    Notes:
4936      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4937 
4938      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4939 
4940      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4941 
4942    Level: intermediate
4943 
4944    Concepts: matrices^transposing
4945 
4946 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4947 @*/
4948 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4949 {
4950   PetscErrorCode ierr;
4951 
4952   PetscFunctionBegin;
4953   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4954   PetscValidType(mat,1);
4955   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4956   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4957   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4958   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4959   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4960   MatCheckPreallocated(mat,1);
4961 
4962   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4963   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4964   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4965   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4966   PetscFunctionReturn(0);
4967 }
4968 
4969 /*@
4970    MatIsTranspose - Test whether a matrix is another one's transpose,
4971         or its own, in which case it tests symmetry.
4972 
4973    Collective on Mat
4974 
4975    Input Parameter:
4976 +  A - the matrix to test
4977 -  B - the matrix to test against, this can equal the first parameter
4978 
4979    Output Parameters:
4980 .  flg - the result
4981 
4982    Notes:
4983    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4984    has a running time of the order of the number of nonzeros; the parallel
4985    test involves parallel copies of the block-offdiagonal parts of the matrix.
4986 
4987    Level: intermediate
4988 
4989    Concepts: matrices^transposing, matrix^symmetry
4990 
4991 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4992 @*/
4993 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4994 {
4995   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4996 
4997   PetscFunctionBegin;
4998   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4999   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5000   PetscValidPointer(flg,3);
5001   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
5002   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
5003   *flg = PETSC_FALSE;
5004   if (f && g) {
5005     if (f == g) {
5006       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5007     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
5008   } else {
5009     MatType mattype;
5010     if (!f) {
5011       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5012     } else {
5013       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5014     }
5015     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
5016   }
5017   PetscFunctionReturn(0);
5018 }
5019 
5020 /*@
5021    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5022 
5023    Collective on Mat
5024 
5025    Input Parameter:
5026 +  mat - the matrix to transpose and complex conjugate
5027 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5028 
5029    Output Parameters:
5030 .  B - the Hermitian
5031 
5032    Level: intermediate
5033 
5034    Concepts: matrices^transposing, complex conjugatex
5035 
5036 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5037 @*/
5038 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5039 {
5040   PetscErrorCode ierr;
5041 
5042   PetscFunctionBegin;
5043   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5044 #if defined(PETSC_USE_COMPLEX)
5045   ierr = MatConjugate(*B);CHKERRQ(ierr);
5046 #endif
5047   PetscFunctionReturn(0);
5048 }
5049 
5050 /*@
5051    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5052 
5053    Collective on Mat
5054 
5055    Input Parameter:
5056 +  A - the matrix to test
5057 -  B - the matrix to test against, this can equal the first parameter
5058 
5059    Output Parameters:
5060 .  flg - the result
5061 
5062    Notes:
5063    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5064    has a running time of the order of the number of nonzeros; the parallel
5065    test involves parallel copies of the block-offdiagonal parts of the matrix.
5066 
5067    Level: intermediate
5068 
5069    Concepts: matrices^transposing, matrix^symmetry
5070 
5071 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5072 @*/
5073 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5074 {
5075   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5076 
5077   PetscFunctionBegin;
5078   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5079   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5080   PetscValidPointer(flg,3);
5081   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5082   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5083   if (f && g) {
5084     if (f==g) {
5085       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5086     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5087   }
5088   PetscFunctionReturn(0);
5089 }
5090 
5091 /*@
5092    MatPermute - Creates a new matrix with rows and columns permuted from the
5093    original.
5094 
5095    Collective on Mat
5096 
5097    Input Parameters:
5098 +  mat - the matrix to permute
5099 .  row - row permutation, each processor supplies only the permutation for its rows
5100 -  col - column permutation, each processor supplies only the permutation for its columns
5101 
5102    Output Parameters:
5103 .  B - the permuted matrix
5104 
5105    Level: advanced
5106 
5107    Note:
5108    The index sets map from row/col of permuted matrix to row/col of original matrix.
5109    The index sets should be on the same communicator as Mat and have the same local sizes.
5110 
5111    Concepts: matrices^permuting
5112 
5113 .seealso: MatGetOrdering(), ISAllGather()
5114 
5115 @*/
5116 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5117 {
5118   PetscErrorCode ierr;
5119 
5120   PetscFunctionBegin;
5121   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5122   PetscValidType(mat,1);
5123   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5124   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5125   PetscValidPointer(B,4);
5126   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5127   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5128   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5129   MatCheckPreallocated(mat,1);
5130 
5131   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5132   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5133   PetscFunctionReturn(0);
5134 }
5135 
5136 /*@
5137    MatEqual - Compares two matrices.
5138 
5139    Collective on Mat
5140 
5141    Input Parameters:
5142 +  A - the first matrix
5143 -  B - the second matrix
5144 
5145    Output Parameter:
5146 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5147 
5148    Level: intermediate
5149 
5150    Concepts: matrices^equality between
5151 @*/
5152 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5153 {
5154   PetscErrorCode ierr;
5155 
5156   PetscFunctionBegin;
5157   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5158   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5159   PetscValidType(A,1);
5160   PetscValidType(B,2);
5161   PetscValidIntPointer(flg,3);
5162   PetscCheckSameComm(A,1,B,2);
5163   MatCheckPreallocated(B,2);
5164   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5165   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5166   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);
5167   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5168   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5169   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);
5170   MatCheckPreallocated(A,1);
5171 
5172   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5173   PetscFunctionReturn(0);
5174 }
5175 
5176 /*@
5177    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5178    matrices that are stored as vectors.  Either of the two scaling
5179    matrices can be NULL.
5180 
5181    Collective on Mat
5182 
5183    Input Parameters:
5184 +  mat - the matrix to be scaled
5185 .  l - the left scaling vector (or NULL)
5186 -  r - the right scaling vector (or NULL)
5187 
5188    Notes:
5189    MatDiagonalScale() computes A = LAR, where
5190    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5191    The L scales the rows of the matrix, the R scales the columns of the matrix.
5192 
5193    Level: intermediate
5194 
5195    Concepts: matrices^diagonal scaling
5196    Concepts: diagonal scaling of matrices
5197 
5198 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5199 @*/
5200 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5201 {
5202   PetscErrorCode ierr;
5203 
5204   PetscFunctionBegin;
5205   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5206   PetscValidType(mat,1);
5207   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5208   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5209   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5210   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5211   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5212   MatCheckPreallocated(mat,1);
5213 
5214   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5215   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5216   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5217   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5218 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5219   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5220     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5221   }
5222 #endif
5223   PetscFunctionReturn(0);
5224 }
5225 
5226 /*@
5227     MatScale - Scales all elements of a matrix by a given number.
5228 
5229     Logically Collective on Mat
5230 
5231     Input Parameters:
5232 +   mat - the matrix to be scaled
5233 -   a  - the scaling value
5234 
5235     Output Parameter:
5236 .   mat - the scaled matrix
5237 
5238     Level: intermediate
5239 
5240     Concepts: matrices^scaling all entries
5241 
5242 .seealso: MatDiagonalScale()
5243 @*/
5244 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5245 {
5246   PetscErrorCode ierr;
5247 
5248   PetscFunctionBegin;
5249   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5250   PetscValidType(mat,1);
5251   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5252   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5253   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5254   PetscValidLogicalCollectiveScalar(mat,a,2);
5255   MatCheckPreallocated(mat,1);
5256 
5257   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5258   if (a != (PetscScalar)1.0) {
5259     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5260     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5261 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5262     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5263       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5264     }
5265 #endif
5266   }
5267   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5268   PetscFunctionReturn(0);
5269 }
5270 
5271 /*@
5272    MatNorm - Calculates various norms of a matrix.
5273 
5274    Collective on Mat
5275 
5276    Input Parameters:
5277 +  mat - the matrix
5278 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5279 
5280    Output Parameters:
5281 .  nrm - the resulting norm
5282 
5283    Level: intermediate
5284 
5285    Concepts: matrices^norm
5286    Concepts: norm^of matrix
5287 @*/
5288 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5289 {
5290   PetscErrorCode ierr;
5291 
5292   PetscFunctionBegin;
5293   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5294   PetscValidType(mat,1);
5295   PetscValidScalarPointer(nrm,3);
5296 
5297   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5298   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5299   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5300   MatCheckPreallocated(mat,1);
5301 
5302   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5303   PetscFunctionReturn(0);
5304 }
5305 
5306 /*
5307      This variable is used to prevent counting of MatAssemblyBegin() that
5308    are called from within a MatAssemblyEnd().
5309 */
5310 static PetscInt MatAssemblyEnd_InUse = 0;
5311 /*@
5312    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5313    be called after completing all calls to MatSetValues().
5314 
5315    Collective on Mat
5316 
5317    Input Parameters:
5318 +  mat - the matrix
5319 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5320 
5321    Notes:
5322    MatSetValues() generally caches the values.  The matrix is ready to
5323    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5324    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5325    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5326    using the matrix.
5327 
5328    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5329    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
5330    a global collective operation requring all processes that share the matrix.
5331 
5332    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5333    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5334    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5335 
5336    Level: beginner
5337 
5338    Concepts: matrices^assembling
5339 
5340 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5341 @*/
5342 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5343 {
5344   PetscErrorCode ierr;
5345 
5346   PetscFunctionBegin;
5347   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5348   PetscValidType(mat,1);
5349   MatCheckPreallocated(mat,1);
5350   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5351   if (mat->assembled) {
5352     mat->was_assembled = PETSC_TRUE;
5353     mat->assembled     = PETSC_FALSE;
5354   }
5355   if (!MatAssemblyEnd_InUse) {
5356     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5357     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5358     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5359   } else if (mat->ops->assemblybegin) {
5360     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5361   }
5362   PetscFunctionReturn(0);
5363 }
5364 
5365 /*@
5366    MatAssembled - Indicates if a matrix has been assembled and is ready for
5367      use; for example, in matrix-vector product.
5368 
5369    Not Collective
5370 
5371    Input Parameter:
5372 .  mat - the matrix
5373 
5374    Output Parameter:
5375 .  assembled - PETSC_TRUE or PETSC_FALSE
5376 
5377    Level: advanced
5378 
5379    Concepts: matrices^assembled?
5380 
5381 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5382 @*/
5383 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5384 {
5385   PetscFunctionBegin;
5386   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5387   PetscValidPointer(assembled,2);
5388   *assembled = mat->assembled;
5389   PetscFunctionReturn(0);
5390 }
5391 
5392 /*@
5393    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5394    be called after MatAssemblyBegin().
5395 
5396    Collective on Mat
5397 
5398    Input Parameters:
5399 +  mat - the matrix
5400 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5401 
5402    Options Database Keys:
5403 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5404 .  -mat_view ::ascii_info_detail - Prints more detailed info
5405 .  -mat_view - Prints matrix in ASCII format
5406 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5407 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5408 .  -display <name> - Sets display name (default is host)
5409 .  -draw_pause <sec> - Sets number of seconds to pause after display
5410 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5411 .  -viewer_socket_machine <machine> - Machine to use for socket
5412 .  -viewer_socket_port <port> - Port number to use for socket
5413 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5414 
5415    Notes:
5416    MatSetValues() generally caches the values.  The matrix is ready to
5417    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5418    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5419    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5420    using the matrix.
5421 
5422    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5423    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5424    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5425 
5426    Level: beginner
5427 
5428 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5429 @*/
5430 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5431 {
5432   PetscErrorCode  ierr;
5433   static PetscInt inassm = 0;
5434   PetscBool       flg    = PETSC_FALSE;
5435 
5436   PetscFunctionBegin;
5437   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5438   PetscValidType(mat,1);
5439 
5440   inassm++;
5441   MatAssemblyEnd_InUse++;
5442   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5443     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5444     if (mat->ops->assemblyend) {
5445       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5446     }
5447     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5448   } else if (mat->ops->assemblyend) {
5449     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5450   }
5451 
5452   /* Flush assembly is not a true assembly */
5453   if (type != MAT_FLUSH_ASSEMBLY) {
5454     mat->assembled = PETSC_TRUE; mat->num_ass++;
5455   }
5456   mat->insertmode = NOT_SET_VALUES;
5457   MatAssemblyEnd_InUse--;
5458   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5459   if (!mat->symmetric_eternal) {
5460     mat->symmetric_set              = PETSC_FALSE;
5461     mat->hermitian_set              = PETSC_FALSE;
5462     mat->structurally_symmetric_set = PETSC_FALSE;
5463   }
5464 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5465   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5466     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5467   }
5468 #endif
5469   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5470     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5471 
5472     if (mat->checksymmetryonassembly) {
5473       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5474       if (flg) {
5475         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5476       } else {
5477         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5478       }
5479     }
5480     if (mat->nullsp && mat->checknullspaceonassembly) {
5481       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5482     }
5483   }
5484   inassm--;
5485   PetscFunctionReturn(0);
5486 }
5487 
5488 /*@
5489    MatSetOption - Sets a parameter option for a matrix. Some options
5490    may be specific to certain storage formats.  Some options
5491    determine how values will be inserted (or added). Sorted,
5492    row-oriented input will generally assemble the fastest. The default
5493    is row-oriented.
5494 
5495    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5496 
5497    Input Parameters:
5498 +  mat - the matrix
5499 .  option - the option, one of those listed below (and possibly others),
5500 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5501 
5502   Options Describing Matrix Structure:
5503 +    MAT_SPD - symmetric positive definite
5504 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5505 .    MAT_HERMITIAN - transpose is the complex conjugation
5506 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5507 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5508                             you set to be kept with all future use of the matrix
5509                             including after MatAssemblyBegin/End() which could
5510                             potentially change the symmetry structure, i.e. you
5511                             KNOW the matrix will ALWAYS have the property you set.
5512 
5513 
5514    Options For Use with MatSetValues():
5515    Insert a logically dense subblock, which can be
5516 .    MAT_ROW_ORIENTED - row-oriented (default)
5517 
5518    Note these options reflect the data you pass in with MatSetValues(); it has
5519    nothing to do with how the data is stored internally in the matrix
5520    data structure.
5521 
5522    When (re)assembling a matrix, we can restrict the input for
5523    efficiency/debugging purposes.  These options include:
5524 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5525 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5526 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5527 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5528 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5529 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5530         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5531         performance for very large process counts.
5532 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5533         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5534         functions, instead sending only neighbor messages.
5535 
5536    Notes:
5537    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5538 
5539    Some options are relevant only for particular matrix types and
5540    are thus ignored by others.  Other options are not supported by
5541    certain matrix types and will generate an error message if set.
5542 
5543    If using a Fortran 77 module to compute a matrix, one may need to
5544    use the column-oriented option (or convert to the row-oriented
5545    format).
5546 
5547    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5548    that would generate a new entry in the nonzero structure is instead
5549    ignored.  Thus, if memory has not alredy been allocated for this particular
5550    data, then the insertion is ignored. For dense matrices, in which
5551    the entire array is allocated, no entries are ever ignored.
5552    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5553 
5554    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5555    that would generate a new entry in the nonzero structure instead produces
5556    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
5557 
5558    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5559    that would generate a new entry that has not been preallocated will
5560    instead produce an error. (Currently supported for AIJ and BAIJ formats
5561    only.) This is a useful flag when debugging matrix memory preallocation.
5562    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5563 
5564    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5565    other processors should be dropped, rather than stashed.
5566    This is useful if you know that the "owning" processor is also
5567    always generating the correct matrix entries, so that PETSc need
5568    not transfer duplicate entries generated on another processor.
5569 
5570    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5571    searches during matrix assembly. When this flag is set, the hash table
5572    is created during the first Matrix Assembly. This hash table is
5573    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5574    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5575    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5576    supported by MATMPIBAIJ format only.
5577 
5578    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5579    are kept in the nonzero structure
5580 
5581    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5582    a zero location in the matrix
5583 
5584    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5585 
5586    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5587         zero row routines and thus improves performance for very large process counts.
5588 
5589    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5590         part of the matrix (since they should match the upper triangular part).
5591 
5592    Notes:
5593     Can only be called after MatSetSizes() and MatSetType() have been set.
5594 
5595    Level: intermediate
5596 
5597    Concepts: matrices^setting options
5598 
5599 .seealso:  MatOption, Mat
5600 
5601 @*/
5602 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5603 {
5604   PetscErrorCode ierr;
5605 
5606   PetscFunctionBegin;
5607   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5608   PetscValidType(mat,1);
5609   if (op > 0) {
5610     PetscValidLogicalCollectiveEnum(mat,op,2);
5611     PetscValidLogicalCollectiveBool(mat,flg,3);
5612   }
5613 
5614   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);
5615   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()");
5616 
5617   switch (op) {
5618   case MAT_NO_OFF_PROC_ENTRIES:
5619     mat->nooffprocentries = flg;
5620     PetscFunctionReturn(0);
5621     break;
5622   case MAT_SUBSET_OFF_PROC_ENTRIES:
5623     mat->assembly_subset = flg;
5624     if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */
5625 #if !defined(PETSC_HAVE_MPIUNI)
5626       ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr);
5627 #endif
5628       mat->stash.first_assembly_done = PETSC_FALSE;
5629     }
5630     PetscFunctionReturn(0);
5631   case MAT_NO_OFF_PROC_ZERO_ROWS:
5632     mat->nooffproczerorows = flg;
5633     PetscFunctionReturn(0);
5634     break;
5635   case MAT_SPD:
5636     mat->spd_set = PETSC_TRUE;
5637     mat->spd     = flg;
5638     if (flg) {
5639       mat->symmetric                  = PETSC_TRUE;
5640       mat->structurally_symmetric     = PETSC_TRUE;
5641       mat->symmetric_set              = PETSC_TRUE;
5642       mat->structurally_symmetric_set = PETSC_TRUE;
5643     }
5644     break;
5645   case MAT_SYMMETRIC:
5646     mat->symmetric = flg;
5647     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5648     mat->symmetric_set              = PETSC_TRUE;
5649     mat->structurally_symmetric_set = flg;
5650 #if !defined(PETSC_USE_COMPLEX)
5651     mat->hermitian     = flg;
5652     mat->hermitian_set = PETSC_TRUE;
5653 #endif
5654     break;
5655   case MAT_HERMITIAN:
5656     mat->hermitian = flg;
5657     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5658     mat->hermitian_set              = PETSC_TRUE;
5659     mat->structurally_symmetric_set = flg;
5660 #if !defined(PETSC_USE_COMPLEX)
5661     mat->symmetric     = flg;
5662     mat->symmetric_set = PETSC_TRUE;
5663 #endif
5664     break;
5665   case MAT_STRUCTURALLY_SYMMETRIC:
5666     mat->structurally_symmetric     = flg;
5667     mat->structurally_symmetric_set = PETSC_TRUE;
5668     break;
5669   case MAT_SYMMETRY_ETERNAL:
5670     mat->symmetric_eternal = flg;
5671     break;
5672   case MAT_STRUCTURE_ONLY:
5673     mat->structure_only = flg;
5674     break;
5675   default:
5676     break;
5677   }
5678   if (mat->ops->setoption) {
5679     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5680   }
5681   PetscFunctionReturn(0);
5682 }
5683 
5684 /*@
5685    MatGetOption - Gets a parameter option that has been set for a matrix.
5686 
5687    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5688 
5689    Input Parameters:
5690 +  mat - the matrix
5691 -  option - the option, this only responds to certain options, check the code for which ones
5692 
5693    Output Parameter:
5694 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5695 
5696     Notes:
5697     Can only be called after MatSetSizes() and MatSetType() have been set.
5698 
5699    Level: intermediate
5700 
5701    Concepts: matrices^setting options
5702 
5703 .seealso:  MatOption, MatSetOption()
5704 
5705 @*/
5706 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5707 {
5708   PetscFunctionBegin;
5709   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5710   PetscValidType(mat,1);
5711 
5712   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);
5713   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()");
5714 
5715   switch (op) {
5716   case MAT_NO_OFF_PROC_ENTRIES:
5717     *flg = mat->nooffprocentries;
5718     break;
5719   case MAT_NO_OFF_PROC_ZERO_ROWS:
5720     *flg = mat->nooffproczerorows;
5721     break;
5722   case MAT_SYMMETRIC:
5723     *flg = mat->symmetric;
5724     break;
5725   case MAT_HERMITIAN:
5726     *flg = mat->hermitian;
5727     break;
5728   case MAT_STRUCTURALLY_SYMMETRIC:
5729     *flg = mat->structurally_symmetric;
5730     break;
5731   case MAT_SYMMETRY_ETERNAL:
5732     *flg = mat->symmetric_eternal;
5733     break;
5734   case MAT_SPD:
5735     *flg = mat->spd;
5736     break;
5737   default:
5738     break;
5739   }
5740   PetscFunctionReturn(0);
5741 }
5742 
5743 /*@
5744    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5745    this routine retains the old nonzero structure.
5746 
5747    Logically Collective on Mat
5748 
5749    Input Parameters:
5750 .  mat - the matrix
5751 
5752    Level: intermediate
5753 
5754    Notes:
5755     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.
5756    See the Performance chapter of the users manual for information on preallocating matrices.
5757 
5758    Concepts: matrices^zeroing
5759 
5760 .seealso: MatZeroRows()
5761 @*/
5762 PetscErrorCode MatZeroEntries(Mat mat)
5763 {
5764   PetscErrorCode ierr;
5765 
5766   PetscFunctionBegin;
5767   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5768   PetscValidType(mat,1);
5769   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5770   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");
5771   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5772   MatCheckPreallocated(mat,1);
5773 
5774   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5775   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5776   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5777   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5778 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5779   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5780     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5781   }
5782 #endif
5783   PetscFunctionReturn(0);
5784 }
5785 
5786 /*@
5787    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5788    of a set of rows and columns of a matrix.
5789 
5790    Collective on Mat
5791 
5792    Input Parameters:
5793 +  mat - the matrix
5794 .  numRows - the number of rows to remove
5795 .  rows - the global row indices
5796 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5797 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5798 -  b - optional vector of right hand side, that will be adjusted by provided solution
5799 
5800    Notes:
5801    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5802 
5803    The user can set a value in the diagonal entry (or for the AIJ and
5804    row formats can optionally remove the main diagonal entry from the
5805    nonzero structure as well, by passing 0.0 as the final argument).
5806 
5807    For the parallel case, all processes that share the matrix (i.e.,
5808    those in the communicator used for matrix creation) MUST call this
5809    routine, regardless of whether any rows being zeroed are owned by
5810    them.
5811 
5812    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5813    list only rows local to itself).
5814 
5815    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5816 
5817    Level: intermediate
5818 
5819    Concepts: matrices^zeroing rows
5820 
5821 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5822           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5823 @*/
5824 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5825 {
5826   PetscErrorCode ierr;
5827 
5828   PetscFunctionBegin;
5829   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5830   PetscValidType(mat,1);
5831   if (numRows) PetscValidIntPointer(rows,3);
5832   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5833   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5834   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5835   MatCheckPreallocated(mat,1);
5836 
5837   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5838   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5839   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5840 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5841   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5842     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5843   }
5844 #endif
5845   PetscFunctionReturn(0);
5846 }
5847 
5848 /*@
5849    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5850    of a set of rows and columns of a matrix.
5851 
5852    Collective on Mat
5853 
5854    Input Parameters:
5855 +  mat - the matrix
5856 .  is - the rows to zero
5857 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5858 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5859 -  b - optional vector of right hand side, that will be adjusted by provided solution
5860 
5861    Notes:
5862    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5863 
5864    The user can set a value in the diagonal entry (or for the AIJ and
5865    row formats can optionally remove the main diagonal entry from the
5866    nonzero structure as well, by passing 0.0 as the final argument).
5867 
5868    For the parallel case, all processes that share the matrix (i.e.,
5869    those in the communicator used for matrix creation) MUST call this
5870    routine, regardless of whether any rows being zeroed are owned by
5871    them.
5872 
5873    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5874    list only rows local to itself).
5875 
5876    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5877 
5878    Level: intermediate
5879 
5880    Concepts: matrices^zeroing rows
5881 
5882 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5883           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5884 @*/
5885 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5886 {
5887   PetscErrorCode ierr;
5888   PetscInt       numRows;
5889   const PetscInt *rows;
5890 
5891   PetscFunctionBegin;
5892   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5893   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5894   PetscValidType(mat,1);
5895   PetscValidType(is,2);
5896   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5897   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5898   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5899   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5900   PetscFunctionReturn(0);
5901 }
5902 
5903 /*@
5904    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5905    of a set of rows of a matrix.
5906 
5907    Collective on Mat
5908 
5909    Input Parameters:
5910 +  mat - the matrix
5911 .  numRows - the number of rows to remove
5912 .  rows - the global row indices
5913 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5914 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5915 -  b - optional vector of right hand side, that will be adjusted by provided solution
5916 
5917    Notes:
5918    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5919    but does not release memory.  For the dense and block diagonal
5920    formats this does not alter the nonzero structure.
5921 
5922    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5923    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5924    merely zeroed.
5925 
5926    The user can set a value in the diagonal entry (or for the AIJ and
5927    row formats can optionally remove the main diagonal entry from the
5928    nonzero structure as well, by passing 0.0 as the final argument).
5929 
5930    For the parallel case, all processes that share the matrix (i.e.,
5931    those in the communicator used for matrix creation) MUST call this
5932    routine, regardless of whether any rows being zeroed are owned by
5933    them.
5934 
5935    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5936    list only rows local to itself).
5937 
5938    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5939    owns that are to be zeroed. This saves a global synchronization in the implementation.
5940 
5941    Level: intermediate
5942 
5943    Concepts: matrices^zeroing rows
5944 
5945 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5946           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5947 @*/
5948 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5949 {
5950   PetscErrorCode ierr;
5951 
5952   PetscFunctionBegin;
5953   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5954   PetscValidType(mat,1);
5955   if (numRows) PetscValidIntPointer(rows,3);
5956   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5957   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5958   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5959   MatCheckPreallocated(mat,1);
5960 
5961   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5962   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5963   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5964 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5965   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5966     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5967   }
5968 #endif
5969   PetscFunctionReturn(0);
5970 }
5971 
5972 /*@
5973    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5974    of a set of rows of a matrix.
5975 
5976    Collective on Mat
5977 
5978    Input Parameters:
5979 +  mat - the matrix
5980 .  is - index set of rows to remove
5981 .  diag - value put in all diagonals of eliminated rows
5982 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5983 -  b - optional vector of right hand side, that will be adjusted by provided solution
5984 
5985    Notes:
5986    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5987    but does not release memory.  For the dense and block diagonal
5988    formats this does not alter the nonzero structure.
5989 
5990    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5991    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5992    merely zeroed.
5993 
5994    The user can set a value in the diagonal entry (or for the AIJ and
5995    row formats can optionally remove the main diagonal entry from the
5996    nonzero structure as well, by passing 0.0 as the final argument).
5997 
5998    For the parallel case, all processes that share the matrix (i.e.,
5999    those in the communicator used for matrix creation) MUST call this
6000    routine, regardless of whether any rows being zeroed are owned by
6001    them.
6002 
6003    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6004    list only rows local to itself).
6005 
6006    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6007    owns that are to be zeroed. This saves a global synchronization in the implementation.
6008 
6009    Level: intermediate
6010 
6011    Concepts: matrices^zeroing rows
6012 
6013 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6014           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6015 @*/
6016 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6017 {
6018   PetscInt       numRows;
6019   const PetscInt *rows;
6020   PetscErrorCode ierr;
6021 
6022   PetscFunctionBegin;
6023   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6024   PetscValidType(mat,1);
6025   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6026   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6027   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6028   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6029   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6030   PetscFunctionReturn(0);
6031 }
6032 
6033 /*@
6034    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6035    of a set of rows of a matrix. These rows must be local to the process.
6036 
6037    Collective on Mat
6038 
6039    Input Parameters:
6040 +  mat - the matrix
6041 .  numRows - the number of rows to remove
6042 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6043 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6044 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6045 -  b - optional vector of right hand side, that will be adjusted by provided solution
6046 
6047    Notes:
6048    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6049    but does not release memory.  For the dense and block diagonal
6050    formats this does not alter the nonzero structure.
6051 
6052    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6053    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6054    merely zeroed.
6055 
6056    The user can set a value in the diagonal entry (or for the AIJ and
6057    row formats can optionally remove the main diagonal entry from the
6058    nonzero structure as well, by passing 0.0 as the final argument).
6059 
6060    For the parallel case, all processes that share the matrix (i.e.,
6061    those in the communicator used for matrix creation) MUST call this
6062    routine, regardless of whether any rows being zeroed are owned by
6063    them.
6064 
6065    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6066    list only rows local to itself).
6067 
6068    The grid coordinates are across the entire grid, not just the local portion
6069 
6070    In Fortran idxm and idxn should be declared as
6071 $     MatStencil idxm(4,m)
6072    and the values inserted using
6073 $    idxm(MatStencil_i,1) = i
6074 $    idxm(MatStencil_j,1) = j
6075 $    idxm(MatStencil_k,1) = k
6076 $    idxm(MatStencil_c,1) = c
6077    etc
6078 
6079    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6080    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6081    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6082    DM_BOUNDARY_PERIODIC boundary type.
6083 
6084    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
6085    a single value per point) you can skip filling those indices.
6086 
6087    Level: intermediate
6088 
6089    Concepts: matrices^zeroing rows
6090 
6091 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6092           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6093 @*/
6094 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6095 {
6096   PetscInt       dim     = mat->stencil.dim;
6097   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6098   PetscInt       *dims   = mat->stencil.dims+1;
6099   PetscInt       *starts = mat->stencil.starts;
6100   PetscInt       *dxm    = (PetscInt*) rows;
6101   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6102   PetscErrorCode ierr;
6103 
6104   PetscFunctionBegin;
6105   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6106   PetscValidType(mat,1);
6107   if (numRows) PetscValidIntPointer(rows,3);
6108 
6109   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6110   for (i = 0; i < numRows; ++i) {
6111     /* Skip unused dimensions (they are ordered k, j, i, c) */
6112     for (j = 0; j < 3-sdim; ++j) dxm++;
6113     /* Local index in X dir */
6114     tmp = *dxm++ - starts[0];
6115     /* Loop over remaining dimensions */
6116     for (j = 0; j < dim-1; ++j) {
6117       /* If nonlocal, set index to be negative */
6118       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6119       /* Update local index */
6120       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6121     }
6122     /* Skip component slot if necessary */
6123     if (mat->stencil.noc) dxm++;
6124     /* Local row number */
6125     if (tmp >= 0) {
6126       jdxm[numNewRows++] = tmp;
6127     }
6128   }
6129   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6130   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6131   PetscFunctionReturn(0);
6132 }
6133 
6134 /*@
6135    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6136    of a set of rows and columns of a matrix.
6137 
6138    Collective on Mat
6139 
6140    Input Parameters:
6141 +  mat - the matrix
6142 .  numRows - the number of rows/columns to remove
6143 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6144 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6145 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6146 -  b - optional vector of right hand side, that will be adjusted by provided solution
6147 
6148    Notes:
6149    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6150    but does not release memory.  For the dense and block diagonal
6151    formats this does not alter the nonzero structure.
6152 
6153    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6154    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6155    merely zeroed.
6156 
6157    The user can set a value in the diagonal entry (or for the AIJ and
6158    row formats can optionally remove the main diagonal entry from the
6159    nonzero structure as well, by passing 0.0 as the final argument).
6160 
6161    For the parallel case, all processes that share the matrix (i.e.,
6162    those in the communicator used for matrix creation) MUST call this
6163    routine, regardless of whether any rows being zeroed are owned by
6164    them.
6165 
6166    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6167    list only rows local to itself, but the row/column numbers are given in local numbering).
6168 
6169    The grid coordinates are across the entire grid, not just the local portion
6170 
6171    In Fortran idxm and idxn should be declared as
6172 $     MatStencil idxm(4,m)
6173    and the values inserted using
6174 $    idxm(MatStencil_i,1) = i
6175 $    idxm(MatStencil_j,1) = j
6176 $    idxm(MatStencil_k,1) = k
6177 $    idxm(MatStencil_c,1) = c
6178    etc
6179 
6180    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6181    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6182    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6183    DM_BOUNDARY_PERIODIC boundary type.
6184 
6185    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
6186    a single value per point) you can skip filling those indices.
6187 
6188    Level: intermediate
6189 
6190    Concepts: matrices^zeroing rows
6191 
6192 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6193           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6194 @*/
6195 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6196 {
6197   PetscInt       dim     = mat->stencil.dim;
6198   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6199   PetscInt       *dims   = mat->stencil.dims+1;
6200   PetscInt       *starts = mat->stencil.starts;
6201   PetscInt       *dxm    = (PetscInt*) rows;
6202   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6203   PetscErrorCode ierr;
6204 
6205   PetscFunctionBegin;
6206   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6207   PetscValidType(mat,1);
6208   if (numRows) PetscValidIntPointer(rows,3);
6209 
6210   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6211   for (i = 0; i < numRows; ++i) {
6212     /* Skip unused dimensions (they are ordered k, j, i, c) */
6213     for (j = 0; j < 3-sdim; ++j) dxm++;
6214     /* Local index in X dir */
6215     tmp = *dxm++ - starts[0];
6216     /* Loop over remaining dimensions */
6217     for (j = 0; j < dim-1; ++j) {
6218       /* If nonlocal, set index to be negative */
6219       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6220       /* Update local index */
6221       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6222     }
6223     /* Skip component slot if necessary */
6224     if (mat->stencil.noc) dxm++;
6225     /* Local row number */
6226     if (tmp >= 0) {
6227       jdxm[numNewRows++] = tmp;
6228     }
6229   }
6230   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6231   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6232   PetscFunctionReturn(0);
6233 }
6234 
6235 /*@C
6236    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6237    of a set of rows of a matrix; using local numbering of rows.
6238 
6239    Collective on Mat
6240 
6241    Input Parameters:
6242 +  mat - the matrix
6243 .  numRows - the number of rows to remove
6244 .  rows - the global row indices
6245 .  diag - value put in all diagonals of eliminated rows
6246 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6247 -  b - optional vector of right hand side, that will be adjusted by provided solution
6248 
6249    Notes:
6250    Before calling MatZeroRowsLocal(), the user must first set the
6251    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6252 
6253    For the AIJ matrix formats this removes the old nonzero structure,
6254    but does not release memory.  For the dense and block diagonal
6255    formats this does not alter the nonzero structure.
6256 
6257    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6258    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6259    merely zeroed.
6260 
6261    The user can set a value in the diagonal entry (or for the AIJ and
6262    row formats can optionally remove the main diagonal entry from the
6263    nonzero structure as well, by passing 0.0 as the final argument).
6264 
6265    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6266    owns that are to be zeroed. This saves a global synchronization in the implementation.
6267 
6268    Level: intermediate
6269 
6270    Concepts: matrices^zeroing
6271 
6272 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6273           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6274 @*/
6275 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6276 {
6277   PetscErrorCode ierr;
6278 
6279   PetscFunctionBegin;
6280   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6281   PetscValidType(mat,1);
6282   if (numRows) PetscValidIntPointer(rows,3);
6283   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6284   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6285   MatCheckPreallocated(mat,1);
6286 
6287   if (mat->ops->zerorowslocal) {
6288     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6289   } else {
6290     IS             is, newis;
6291     const PetscInt *newRows;
6292 
6293     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6294     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6295     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6296     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6297     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6298     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6299     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6300     ierr = ISDestroy(&is);CHKERRQ(ierr);
6301   }
6302   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6303 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6304   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6305     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6306   }
6307 #endif
6308   PetscFunctionReturn(0);
6309 }
6310 
6311 /*@
6312    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6313    of a set of rows of a matrix; using local numbering of rows.
6314 
6315    Collective on Mat
6316 
6317    Input Parameters:
6318 +  mat - the matrix
6319 .  is - index set of rows to remove
6320 .  diag - value put in all diagonals of eliminated rows
6321 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6322 -  b - optional vector of right hand side, that will be adjusted by provided solution
6323 
6324    Notes:
6325    Before calling MatZeroRowsLocalIS(), the user must first set the
6326    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6327 
6328    For the AIJ matrix formats this removes the old nonzero structure,
6329    but does not release memory.  For the dense and block diagonal
6330    formats this does not alter the nonzero structure.
6331 
6332    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6333    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6334    merely zeroed.
6335 
6336    The user can set a value in the diagonal entry (or for the AIJ and
6337    row formats can optionally remove the main diagonal entry from the
6338    nonzero structure as well, by passing 0.0 as the final argument).
6339 
6340    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6341    owns that are to be zeroed. This saves a global synchronization in the implementation.
6342 
6343    Level: intermediate
6344 
6345    Concepts: matrices^zeroing
6346 
6347 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6348           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6349 @*/
6350 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6351 {
6352   PetscErrorCode ierr;
6353   PetscInt       numRows;
6354   const PetscInt *rows;
6355 
6356   PetscFunctionBegin;
6357   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6358   PetscValidType(mat,1);
6359   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6360   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6361   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6362   MatCheckPreallocated(mat,1);
6363 
6364   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6365   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6366   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6367   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6368   PetscFunctionReturn(0);
6369 }
6370 
6371 /*@
6372    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6373    of a set of rows and columns of a matrix; using local numbering of rows.
6374 
6375    Collective on Mat
6376 
6377    Input Parameters:
6378 +  mat - the matrix
6379 .  numRows - the number of rows to remove
6380 .  rows - the global row indices
6381 .  diag - value put in all diagonals of eliminated rows
6382 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6383 -  b - optional vector of right hand side, that will be adjusted by provided solution
6384 
6385    Notes:
6386    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6387    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6388 
6389    The user can set a value in the diagonal entry (or for the AIJ and
6390    row formats can optionally remove the main diagonal entry from the
6391    nonzero structure as well, by passing 0.0 as the final argument).
6392 
6393    Level: intermediate
6394 
6395    Concepts: matrices^zeroing
6396 
6397 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6398           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6399 @*/
6400 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6401 {
6402   PetscErrorCode ierr;
6403   IS             is, newis;
6404   const PetscInt *newRows;
6405 
6406   PetscFunctionBegin;
6407   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6408   PetscValidType(mat,1);
6409   if (numRows) PetscValidIntPointer(rows,3);
6410   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6411   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6412   MatCheckPreallocated(mat,1);
6413 
6414   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6415   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6416   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6417   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6418   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6419   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6420   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6421   ierr = ISDestroy(&is);CHKERRQ(ierr);
6422   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6423 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6424   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6425     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6426   }
6427 #endif
6428   PetscFunctionReturn(0);
6429 }
6430 
6431 /*@
6432    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6433    of a set of rows and columns of a matrix; using local numbering of rows.
6434 
6435    Collective on Mat
6436 
6437    Input Parameters:
6438 +  mat - the matrix
6439 .  is - index set of rows to remove
6440 .  diag - value put in all diagonals of eliminated rows
6441 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6442 -  b - optional vector of right hand side, that will be adjusted by provided solution
6443 
6444    Notes:
6445    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6446    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6447 
6448    The user can set a value in the diagonal entry (or for the AIJ and
6449    row formats can optionally remove the main diagonal entry from the
6450    nonzero structure as well, by passing 0.0 as the final argument).
6451 
6452    Level: intermediate
6453 
6454    Concepts: matrices^zeroing
6455 
6456 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6457           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6458 @*/
6459 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6460 {
6461   PetscErrorCode ierr;
6462   PetscInt       numRows;
6463   const PetscInt *rows;
6464 
6465   PetscFunctionBegin;
6466   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6467   PetscValidType(mat,1);
6468   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6469   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6470   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6471   MatCheckPreallocated(mat,1);
6472 
6473   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6474   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6475   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6476   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6477   PetscFunctionReturn(0);
6478 }
6479 
6480 /*@C
6481    MatGetSize - Returns the numbers of rows and columns in a matrix.
6482 
6483    Not Collective
6484 
6485    Input Parameter:
6486 .  mat - the matrix
6487 
6488    Output Parameters:
6489 +  m - the number of global rows
6490 -  n - the number of global columns
6491 
6492    Note: both output parameters can be NULL on input.
6493 
6494    Level: beginner
6495 
6496    Concepts: matrices^size
6497 
6498 .seealso: MatGetLocalSize()
6499 @*/
6500 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6501 {
6502   PetscFunctionBegin;
6503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6504   if (m) *m = mat->rmap->N;
6505   if (n) *n = mat->cmap->N;
6506   PetscFunctionReturn(0);
6507 }
6508 
6509 /*@C
6510    MatGetLocalSize - Returns the number of rows and columns in a matrix
6511    stored locally.  This information may be implementation dependent, so
6512    use with care.
6513 
6514    Not Collective
6515 
6516    Input Parameters:
6517 .  mat - the matrix
6518 
6519    Output Parameters:
6520 +  m - the number of local rows
6521 -  n - the number of local columns
6522 
6523    Note: both output parameters can be NULL on input.
6524 
6525    Level: beginner
6526 
6527    Concepts: matrices^local size
6528 
6529 .seealso: MatGetSize()
6530 @*/
6531 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6532 {
6533   PetscFunctionBegin;
6534   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6535   if (m) PetscValidIntPointer(m,2);
6536   if (n) PetscValidIntPointer(n,3);
6537   if (m) *m = mat->rmap->n;
6538   if (n) *n = mat->cmap->n;
6539   PetscFunctionReturn(0);
6540 }
6541 
6542 /*@C
6543    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6544    this processor. (The columns of the "diagonal block")
6545 
6546    Not Collective, unless matrix has not been allocated, then collective on Mat
6547 
6548    Input Parameters:
6549 .  mat - the matrix
6550 
6551    Output Parameters:
6552 +  m - the global index of the first local column
6553 -  n - one more than the global index of the last local column
6554 
6555    Notes:
6556     both output parameters can be NULL on input.
6557 
6558    Level: developer
6559 
6560    Concepts: matrices^column ownership
6561 
6562 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6563 
6564 @*/
6565 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6566 {
6567   PetscFunctionBegin;
6568   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6569   PetscValidType(mat,1);
6570   if (m) PetscValidIntPointer(m,2);
6571   if (n) PetscValidIntPointer(n,3);
6572   MatCheckPreallocated(mat,1);
6573   if (m) *m = mat->cmap->rstart;
6574   if (n) *n = mat->cmap->rend;
6575   PetscFunctionReturn(0);
6576 }
6577 
6578 /*@C
6579    MatGetOwnershipRange - Returns the range of matrix rows owned by
6580    this processor, assuming that the matrix is laid out with the first
6581    n1 rows on the first processor, the next n2 rows on the second, etc.
6582    For certain parallel layouts this range may not be well defined.
6583 
6584    Not Collective
6585 
6586    Input Parameters:
6587 .  mat - the matrix
6588 
6589    Output Parameters:
6590 +  m - the global index of the first local row
6591 -  n - one more than the global index of the last local row
6592 
6593    Note: Both output parameters can be NULL on input.
6594 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6595 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6596 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6597 
6598    Level: beginner
6599 
6600    Concepts: matrices^row ownership
6601 
6602 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6603 
6604 @*/
6605 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6606 {
6607   PetscFunctionBegin;
6608   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6609   PetscValidType(mat,1);
6610   if (m) PetscValidIntPointer(m,2);
6611   if (n) PetscValidIntPointer(n,3);
6612   MatCheckPreallocated(mat,1);
6613   if (m) *m = mat->rmap->rstart;
6614   if (n) *n = mat->rmap->rend;
6615   PetscFunctionReturn(0);
6616 }
6617 
6618 /*@C
6619    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6620    each process
6621 
6622    Not Collective, unless matrix has not been allocated, then collective on Mat
6623 
6624    Input Parameters:
6625 .  mat - the matrix
6626 
6627    Output Parameters:
6628 .  ranges - start of each processors portion plus one more than the total length at the end
6629 
6630    Level: beginner
6631 
6632    Concepts: matrices^row ownership
6633 
6634 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6635 
6636 @*/
6637 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6638 {
6639   PetscErrorCode ierr;
6640 
6641   PetscFunctionBegin;
6642   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6643   PetscValidType(mat,1);
6644   MatCheckPreallocated(mat,1);
6645   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6646   PetscFunctionReturn(0);
6647 }
6648 
6649 /*@C
6650    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6651    this processor. (The columns of the "diagonal blocks" for each process)
6652 
6653    Not Collective, unless matrix has not been allocated, then collective on Mat
6654 
6655    Input Parameters:
6656 .  mat - the matrix
6657 
6658    Output Parameters:
6659 .  ranges - start of each processors portion plus one more then the total length at the end
6660 
6661    Level: beginner
6662 
6663    Concepts: matrices^column ownership
6664 
6665 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6666 
6667 @*/
6668 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6669 {
6670   PetscErrorCode ierr;
6671 
6672   PetscFunctionBegin;
6673   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6674   PetscValidType(mat,1);
6675   MatCheckPreallocated(mat,1);
6676   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6677   PetscFunctionReturn(0);
6678 }
6679 
6680 /*@C
6681    MatGetOwnershipIS - Get row and column ownership as index sets
6682 
6683    Not Collective
6684 
6685    Input Arguments:
6686 .  A - matrix of type Elemental
6687 
6688    Output Arguments:
6689 +  rows - rows in which this process owns elements
6690 .  cols - columns in which this process owns elements
6691 
6692    Level: intermediate
6693 
6694 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6695 @*/
6696 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6697 {
6698   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6699 
6700   PetscFunctionBegin;
6701   MatCheckPreallocated(A,1);
6702   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6703   if (f) {
6704     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6705   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6706     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6707     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6708   }
6709   PetscFunctionReturn(0);
6710 }
6711 
6712 /*@C
6713    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6714    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6715    to complete the factorization.
6716 
6717    Collective on Mat
6718 
6719    Input Parameters:
6720 +  mat - the matrix
6721 .  row - row permutation
6722 .  column - column permutation
6723 -  info - structure containing
6724 $      levels - number of levels of fill.
6725 $      expected fill - as ratio of original fill.
6726 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6727                 missing diagonal entries)
6728 
6729    Output Parameters:
6730 .  fact - new matrix that has been symbolically factored
6731 
6732    Notes:
6733     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6734 
6735    Most users should employ the simplified KSP interface for linear solvers
6736    instead of working directly with matrix algebra routines such as this.
6737    See, e.g., KSPCreate().
6738 
6739    Level: developer
6740 
6741   Concepts: matrices^symbolic LU factorization
6742   Concepts: matrices^factorization
6743   Concepts: LU^symbolic factorization
6744 
6745 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6746           MatGetOrdering(), MatFactorInfo
6747 
6748     Note: this uses the definition of level of fill as in Y. Saad, 2003
6749 
6750     Developer Note: fortran interface is not autogenerated as the f90
6751     interface defintion cannot be generated correctly [due to MatFactorInfo]
6752 
6753    References:
6754      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6755 @*/
6756 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6757 {
6758   PetscErrorCode ierr;
6759 
6760   PetscFunctionBegin;
6761   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6762   PetscValidType(mat,1);
6763   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6764   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6765   PetscValidPointer(info,4);
6766   PetscValidPointer(fact,5);
6767   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6768   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6769   if (!(fact)->ops->ilufactorsymbolic) {
6770     MatSolverType spackage;
6771     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6772     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6773   }
6774   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6775   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6776   MatCheckPreallocated(mat,2);
6777 
6778   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6779   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6780   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6781   PetscFunctionReturn(0);
6782 }
6783 
6784 /*@C
6785    MatICCFactorSymbolic - Performs symbolic incomplete
6786    Cholesky factorization for a symmetric matrix.  Use
6787    MatCholeskyFactorNumeric() to complete the factorization.
6788 
6789    Collective on Mat
6790 
6791    Input Parameters:
6792 +  mat - the matrix
6793 .  perm - row and column permutation
6794 -  info - structure containing
6795 $      levels - number of levels of fill.
6796 $      expected fill - as ratio of original fill.
6797 
6798    Output Parameter:
6799 .  fact - the factored matrix
6800 
6801    Notes:
6802    Most users should employ the KSP interface for linear solvers
6803    instead of working directly with matrix algebra routines such as this.
6804    See, e.g., KSPCreate().
6805 
6806    Level: developer
6807 
6808   Concepts: matrices^symbolic incomplete Cholesky factorization
6809   Concepts: matrices^factorization
6810   Concepts: Cholsky^symbolic factorization
6811 
6812 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6813 
6814     Note: this uses the definition of level of fill as in Y. Saad, 2003
6815 
6816     Developer Note: fortran interface is not autogenerated as the f90
6817     interface defintion cannot be generated correctly [due to MatFactorInfo]
6818 
6819    References:
6820      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6821 @*/
6822 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6823 {
6824   PetscErrorCode ierr;
6825 
6826   PetscFunctionBegin;
6827   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6828   PetscValidType(mat,1);
6829   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6830   PetscValidPointer(info,3);
6831   PetscValidPointer(fact,4);
6832   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6833   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6834   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6835   if (!(fact)->ops->iccfactorsymbolic) {
6836     MatSolverType spackage;
6837     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6838     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6839   }
6840   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6841   MatCheckPreallocated(mat,2);
6842 
6843   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6844   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6845   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6846   PetscFunctionReturn(0);
6847 }
6848 
6849 /*@C
6850    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6851    points to an array of valid matrices, they may be reused to store the new
6852    submatrices.
6853 
6854    Collective on Mat
6855 
6856    Input Parameters:
6857 +  mat - the matrix
6858 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6859 .  irow, icol - index sets of rows and columns to extract
6860 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6861 
6862    Output Parameter:
6863 .  submat - the array of submatrices
6864 
6865    Notes:
6866    MatCreateSubMatrices() can extract ONLY sequential submatrices
6867    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6868    to extract a parallel submatrix.
6869 
6870    Some matrix types place restrictions on the row and column
6871    indices, such as that they be sorted or that they be equal to each other.
6872 
6873    The index sets may not have duplicate entries.
6874 
6875    When extracting submatrices from a parallel matrix, each processor can
6876    form a different submatrix by setting the rows and columns of its
6877    individual index sets according to the local submatrix desired.
6878 
6879    When finished using the submatrices, the user should destroy
6880    them with MatDestroySubMatrices().
6881 
6882    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6883    original matrix has not changed from that last call to MatCreateSubMatrices().
6884 
6885    This routine creates the matrices in submat; you should NOT create them before
6886    calling it. It also allocates the array of matrix pointers submat.
6887 
6888    For BAIJ matrices the index sets must respect the block structure, that is if they
6889    request one row/column in a block, they must request all rows/columns that are in
6890    that block. For example, if the block size is 2 you cannot request just row 0 and
6891    column 0.
6892 
6893    Fortran Note:
6894    The Fortran interface is slightly different from that given below; it
6895    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6896 
6897    Level: advanced
6898 
6899    Concepts: matrices^accessing submatrices
6900    Concepts: submatrices
6901 
6902 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6903 @*/
6904 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6905 {
6906   PetscErrorCode ierr;
6907   PetscInt       i;
6908   PetscBool      eq;
6909 
6910   PetscFunctionBegin;
6911   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6912   PetscValidType(mat,1);
6913   if (n) {
6914     PetscValidPointer(irow,3);
6915     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6916     PetscValidPointer(icol,4);
6917     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6918   }
6919   PetscValidPointer(submat,6);
6920   if (n && scall == MAT_REUSE_MATRIX) {
6921     PetscValidPointer(*submat,6);
6922     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6923   }
6924   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6925   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6926   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6927   MatCheckPreallocated(mat,1);
6928 
6929   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6930   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6931   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6932   for (i=0; i<n; i++) {
6933     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6934     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6935       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6936       if (eq) {
6937         if (mat->symmetric) {
6938           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6939         } else if (mat->hermitian) {
6940           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6941         } else if (mat->structurally_symmetric) {
6942           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6943         }
6944       }
6945     }
6946   }
6947   PetscFunctionReturn(0);
6948 }
6949 
6950 /*@C
6951    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6952 
6953    Collective on Mat
6954 
6955    Input Parameters:
6956 +  mat - the matrix
6957 .  n   - the number of submatrixes to be extracted
6958 .  irow, icol - index sets of rows and columns to extract
6959 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6960 
6961    Output Parameter:
6962 .  submat - the array of submatrices
6963 
6964    Level: advanced
6965 
6966    Concepts: matrices^accessing submatrices
6967    Concepts: submatrices
6968 
6969 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6970 @*/
6971 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6972 {
6973   PetscErrorCode ierr;
6974   PetscInt       i;
6975   PetscBool      eq;
6976 
6977   PetscFunctionBegin;
6978   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6979   PetscValidType(mat,1);
6980   if (n) {
6981     PetscValidPointer(irow,3);
6982     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6983     PetscValidPointer(icol,4);
6984     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6985   }
6986   PetscValidPointer(submat,6);
6987   if (n && scall == MAT_REUSE_MATRIX) {
6988     PetscValidPointer(*submat,6);
6989     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6990   }
6991   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6992   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6993   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6994   MatCheckPreallocated(mat,1);
6995 
6996   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6997   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6998   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6999   for (i=0; i<n; i++) {
7000     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
7001       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
7002       if (eq) {
7003         if (mat->symmetric) {
7004           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7005         } else if (mat->hermitian) {
7006           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
7007         } else if (mat->structurally_symmetric) {
7008           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
7009         }
7010       }
7011     }
7012   }
7013   PetscFunctionReturn(0);
7014 }
7015 
7016 /*@C
7017    MatDestroyMatrices - Destroys an array of matrices.
7018 
7019    Collective on Mat
7020 
7021    Input Parameters:
7022 +  n - the number of local matrices
7023 -  mat - the matrices (note that this is a pointer to the array of matrices)
7024 
7025    Level: advanced
7026 
7027     Notes:
7028     Frees not only the matrices, but also the array that contains the matrices
7029            In Fortran will not free the array.
7030 
7031 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7032 @*/
7033 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7034 {
7035   PetscErrorCode ierr;
7036   PetscInt       i;
7037 
7038   PetscFunctionBegin;
7039   if (!*mat) PetscFunctionReturn(0);
7040   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7041   PetscValidPointer(mat,2);
7042 
7043   for (i=0; i<n; i++) {
7044     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7045   }
7046 
7047   /* memory is allocated even if n = 0 */
7048   ierr = PetscFree(*mat);CHKERRQ(ierr);
7049   PetscFunctionReturn(0);
7050 }
7051 
7052 /*@C
7053    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7054 
7055    Collective on Mat
7056 
7057    Input Parameters:
7058 +  n - the number of local matrices
7059 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7060                        sequence of MatCreateSubMatrices())
7061 
7062    Level: advanced
7063 
7064     Notes:
7065     Frees not only the matrices, but also the array that contains the matrices
7066            In Fortran will not free the array.
7067 
7068 .seealso: MatCreateSubMatrices()
7069 @*/
7070 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7071 {
7072   PetscErrorCode ierr;
7073   Mat            mat0;
7074 
7075   PetscFunctionBegin;
7076   if (!*mat) PetscFunctionReturn(0);
7077   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7078   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7079   PetscValidPointer(mat,2);
7080 
7081   mat0 = (*mat)[0];
7082   if (mat0 && mat0->ops->destroysubmatrices) {
7083     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7084   } else {
7085     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7086   }
7087   PetscFunctionReturn(0);
7088 }
7089 
7090 /*@C
7091    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7092 
7093    Collective on Mat
7094 
7095    Input Parameters:
7096 .  mat - the matrix
7097 
7098    Output Parameter:
7099 .  matstruct - the sequential matrix with the nonzero structure of mat
7100 
7101   Level: intermediate
7102 
7103 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7104 @*/
7105 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7106 {
7107   PetscErrorCode ierr;
7108 
7109   PetscFunctionBegin;
7110   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7111   PetscValidPointer(matstruct,2);
7112 
7113   PetscValidType(mat,1);
7114   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7115   MatCheckPreallocated(mat,1);
7116 
7117   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7118   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7119   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7120   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7121   PetscFunctionReturn(0);
7122 }
7123 
7124 /*@C
7125    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7126 
7127    Collective on Mat
7128 
7129    Input Parameters:
7130 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7131                        sequence of MatGetSequentialNonzeroStructure())
7132 
7133    Level: advanced
7134 
7135     Notes:
7136     Frees not only the matrices, but also the array that contains the matrices
7137 
7138 .seealso: MatGetSeqNonzeroStructure()
7139 @*/
7140 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7141 {
7142   PetscErrorCode ierr;
7143 
7144   PetscFunctionBegin;
7145   PetscValidPointer(mat,1);
7146   ierr = MatDestroy(mat);CHKERRQ(ierr);
7147   PetscFunctionReturn(0);
7148 }
7149 
7150 /*@
7151    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7152    replaces the index sets by larger ones that represent submatrices with
7153    additional overlap.
7154 
7155    Collective on Mat
7156 
7157    Input Parameters:
7158 +  mat - the matrix
7159 .  n   - the number of index sets
7160 .  is  - the array of index sets (these index sets will changed during the call)
7161 -  ov  - the additional overlap requested
7162 
7163    Options Database:
7164 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7165 
7166    Level: developer
7167 
7168    Concepts: overlap
7169    Concepts: ASM^computing overlap
7170 
7171 .seealso: MatCreateSubMatrices()
7172 @*/
7173 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7174 {
7175   PetscErrorCode ierr;
7176 
7177   PetscFunctionBegin;
7178   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7179   PetscValidType(mat,1);
7180   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7181   if (n) {
7182     PetscValidPointer(is,3);
7183     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7184   }
7185   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7186   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7187   MatCheckPreallocated(mat,1);
7188 
7189   if (!ov) PetscFunctionReturn(0);
7190   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7191   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7192   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7193   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7194   PetscFunctionReturn(0);
7195 }
7196 
7197 
7198 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7199 
7200 /*@
7201    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7202    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7203    additional overlap.
7204 
7205    Collective on Mat
7206 
7207    Input Parameters:
7208 +  mat - the matrix
7209 .  n   - the number of index sets
7210 .  is  - the array of index sets (these index sets will changed during the call)
7211 -  ov  - the additional overlap requested
7212 
7213    Options Database:
7214 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7215 
7216    Level: developer
7217 
7218    Concepts: overlap
7219    Concepts: ASM^computing overlap
7220 
7221 .seealso: MatCreateSubMatrices()
7222 @*/
7223 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7224 {
7225   PetscInt       i;
7226   PetscErrorCode ierr;
7227 
7228   PetscFunctionBegin;
7229   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7230   PetscValidType(mat,1);
7231   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7232   if (n) {
7233     PetscValidPointer(is,3);
7234     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7235   }
7236   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7237   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7238   MatCheckPreallocated(mat,1);
7239   if (!ov) PetscFunctionReturn(0);
7240   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7241   for(i=0; i<n; i++){
7242 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7243   }
7244   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7245   PetscFunctionReturn(0);
7246 }
7247 
7248 
7249 
7250 
7251 /*@
7252    MatGetBlockSize - Returns the matrix block size.
7253 
7254    Not Collective
7255 
7256    Input Parameter:
7257 .  mat - the matrix
7258 
7259    Output Parameter:
7260 .  bs - block size
7261 
7262    Notes:
7263     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7264 
7265    If the block size has not been set yet this routine returns 1.
7266 
7267    Level: intermediate
7268 
7269    Concepts: matrices^block size
7270 
7271 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7272 @*/
7273 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7274 {
7275   PetscFunctionBegin;
7276   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7277   PetscValidIntPointer(bs,2);
7278   *bs = PetscAbs(mat->rmap->bs);
7279   PetscFunctionReturn(0);
7280 }
7281 
7282 /*@
7283    MatGetBlockSizes - Returns the matrix block row and column sizes.
7284 
7285    Not Collective
7286 
7287    Input Parameter:
7288 .  mat - the matrix
7289 
7290    Output Parameter:
7291 .  rbs - row block size
7292 .  cbs - column block size
7293 
7294    Notes:
7295     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7296     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7297 
7298    If a block size has not been set yet this routine returns 1.
7299 
7300    Level: intermediate
7301 
7302    Concepts: matrices^block size
7303 
7304 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7305 @*/
7306 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7307 {
7308   PetscFunctionBegin;
7309   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7310   if (rbs) PetscValidIntPointer(rbs,2);
7311   if (cbs) PetscValidIntPointer(cbs,3);
7312   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7313   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7314   PetscFunctionReturn(0);
7315 }
7316 
7317 /*@
7318    MatSetBlockSize - Sets the matrix block size.
7319 
7320    Logically Collective on Mat
7321 
7322    Input Parameters:
7323 +  mat - the matrix
7324 -  bs - block size
7325 
7326    Notes:
7327     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7328     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7329 
7330     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7331     is compatible with the matrix local sizes.
7332 
7333    Level: intermediate
7334 
7335    Concepts: matrices^block size
7336 
7337 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7338 @*/
7339 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7340 {
7341   PetscErrorCode ierr;
7342 
7343   PetscFunctionBegin;
7344   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7345   PetscValidLogicalCollectiveInt(mat,bs,2);
7346   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7347   PetscFunctionReturn(0);
7348 }
7349 
7350 /*@
7351    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7352 
7353    Logically Collective on Mat
7354 
7355    Input Parameters:
7356 +  mat - the matrix
7357 .  nblocks - the number of blocks on this process
7358 -  bsizes - the block sizes
7359 
7360    Notes:
7361     Currently used by PCVPBJACOBI for SeqAIJ matrices
7362 
7363    Level: intermediate
7364 
7365    Concepts: matrices^block size
7366 
7367 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7368 @*/
7369 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7370 {
7371   PetscErrorCode ierr;
7372   PetscInt       i,ncnt = 0, nlocal;
7373 
7374   PetscFunctionBegin;
7375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7376   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7377   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7378   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7379   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);
7380   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7381   mat->nblocks = nblocks;
7382   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7383   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7384   PetscFunctionReturn(0);
7385 }
7386 
7387 /*@C
7388    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7389 
7390    Logically Collective on Mat
7391 
7392    Input Parameters:
7393 .  mat - the matrix
7394 
7395    Output Parameters:
7396 +  nblocks - the number of blocks on this process
7397 -  bsizes - the block sizes
7398 
7399    Notes: Currently not supported from Fortran
7400 
7401    Level: intermediate
7402 
7403    Concepts: matrices^block size
7404 
7405 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7406 @*/
7407 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7408 {
7409   PetscFunctionBegin;
7410   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7411   *nblocks = mat->nblocks;
7412   *bsizes  = mat->bsizes;
7413   PetscFunctionReturn(0);
7414 }
7415 
7416 /*@
7417    MatSetBlockSizes - Sets the matrix block row and column sizes.
7418 
7419    Logically Collective on Mat
7420 
7421    Input Parameters:
7422 +  mat - the matrix
7423 -  rbs - row block size
7424 -  cbs - column block size
7425 
7426    Notes:
7427     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7428     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7429     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7430 
7431     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7432     are compatible with the matrix local sizes.
7433 
7434     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7435 
7436    Level: intermediate
7437 
7438    Concepts: matrices^block size
7439 
7440 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7441 @*/
7442 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7443 {
7444   PetscErrorCode ierr;
7445 
7446   PetscFunctionBegin;
7447   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7448   PetscValidLogicalCollectiveInt(mat,rbs,2);
7449   PetscValidLogicalCollectiveInt(mat,cbs,3);
7450   if (mat->ops->setblocksizes) {
7451     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7452   }
7453   if (mat->rmap->refcnt) {
7454     ISLocalToGlobalMapping l2g = NULL;
7455     PetscLayout            nmap = NULL;
7456 
7457     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7458     if (mat->rmap->mapping) {
7459       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7460     }
7461     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7462     mat->rmap = nmap;
7463     mat->rmap->mapping = l2g;
7464   }
7465   if (mat->cmap->refcnt) {
7466     ISLocalToGlobalMapping l2g = NULL;
7467     PetscLayout            nmap = NULL;
7468 
7469     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7470     if (mat->cmap->mapping) {
7471       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7472     }
7473     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7474     mat->cmap = nmap;
7475     mat->cmap->mapping = l2g;
7476   }
7477   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7478   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7479   PetscFunctionReturn(0);
7480 }
7481 
7482 /*@
7483    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7484 
7485    Logically Collective on Mat
7486 
7487    Input Parameters:
7488 +  mat - the matrix
7489 .  fromRow - matrix from which to copy row block size
7490 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7491 
7492    Level: developer
7493 
7494    Concepts: matrices^block size
7495 
7496 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7497 @*/
7498 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7499 {
7500   PetscErrorCode ierr;
7501 
7502   PetscFunctionBegin;
7503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7504   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7505   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7506   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7507   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7508   PetscFunctionReturn(0);
7509 }
7510 
7511 /*@
7512    MatResidual - Default routine to calculate the residual.
7513 
7514    Collective on Mat and Vec
7515 
7516    Input Parameters:
7517 +  mat - the matrix
7518 .  b   - the right-hand-side
7519 -  x   - the approximate solution
7520 
7521    Output Parameter:
7522 .  r - location to store the residual
7523 
7524    Level: developer
7525 
7526 .keywords: MG, default, multigrid, residual
7527 
7528 .seealso: PCMGSetResidual()
7529 @*/
7530 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7531 {
7532   PetscErrorCode ierr;
7533 
7534   PetscFunctionBegin;
7535   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7536   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7537   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7538   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7539   PetscValidType(mat,1);
7540   MatCheckPreallocated(mat,1);
7541   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7542   if (!mat->ops->residual) {
7543     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7544     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7545   } else {
7546     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7547   }
7548   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7549   PetscFunctionReturn(0);
7550 }
7551 
7552 /*@C
7553     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7554 
7555    Collective on Mat
7556 
7557     Input Parameters:
7558 +   mat - the matrix
7559 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7560 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7561 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7562                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7563                  always used.
7564 
7565     Output Parameters:
7566 +   n - number of rows in the (possibly compressed) matrix
7567 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7568 .   ja - the column indices
7569 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7570            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7571 
7572     Level: developer
7573 
7574     Notes:
7575     You CANNOT change any of the ia[] or ja[] values.
7576 
7577     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7578 
7579     Fortran Notes:
7580     In Fortran use
7581 $
7582 $      PetscInt ia(1), ja(1)
7583 $      PetscOffset iia, jja
7584 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7585 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7586 
7587      or
7588 $
7589 $    PetscInt, pointer :: ia(:),ja(:)
7590 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7591 $    ! Access the ith and jth entries via ia(i) and ja(j)
7592 
7593 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7594 @*/
7595 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7596 {
7597   PetscErrorCode ierr;
7598 
7599   PetscFunctionBegin;
7600   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7601   PetscValidType(mat,1);
7602   PetscValidIntPointer(n,5);
7603   if (ia) PetscValidIntPointer(ia,6);
7604   if (ja) PetscValidIntPointer(ja,7);
7605   PetscValidIntPointer(done,8);
7606   MatCheckPreallocated(mat,1);
7607   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7608   else {
7609     *done = PETSC_TRUE;
7610     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7611     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7612     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7613   }
7614   PetscFunctionReturn(0);
7615 }
7616 
7617 /*@C
7618     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7619 
7620     Collective on Mat
7621 
7622     Input Parameters:
7623 +   mat - the matrix
7624 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7625 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7626                 symmetrized
7627 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7628                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7629                  always used.
7630 .   n - number of columns in the (possibly compressed) matrix
7631 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7632 -   ja - the row indices
7633 
7634     Output Parameters:
7635 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7636 
7637     Level: developer
7638 
7639 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7640 @*/
7641 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7642 {
7643   PetscErrorCode ierr;
7644 
7645   PetscFunctionBegin;
7646   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7647   PetscValidType(mat,1);
7648   PetscValidIntPointer(n,4);
7649   if (ia) PetscValidIntPointer(ia,5);
7650   if (ja) PetscValidIntPointer(ja,6);
7651   PetscValidIntPointer(done,7);
7652   MatCheckPreallocated(mat,1);
7653   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7654   else {
7655     *done = PETSC_TRUE;
7656     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7657   }
7658   PetscFunctionReturn(0);
7659 }
7660 
7661 /*@C
7662     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7663     MatGetRowIJ().
7664 
7665     Collective on Mat
7666 
7667     Input Parameters:
7668 +   mat - the matrix
7669 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7670 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7671                 symmetrized
7672 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7673                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7674                  always used.
7675 .   n - size of (possibly compressed) matrix
7676 .   ia - the row pointers
7677 -   ja - the column indices
7678 
7679     Output Parameters:
7680 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7681 
7682     Note:
7683     This routine zeros out n, ia, and ja. This is to prevent accidental
7684     us of the array after it has been restored. If you pass NULL, it will
7685     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7686 
7687     Level: developer
7688 
7689 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7690 @*/
7691 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7692 {
7693   PetscErrorCode ierr;
7694 
7695   PetscFunctionBegin;
7696   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7697   PetscValidType(mat,1);
7698   if (ia) PetscValidIntPointer(ia,6);
7699   if (ja) PetscValidIntPointer(ja,7);
7700   PetscValidIntPointer(done,8);
7701   MatCheckPreallocated(mat,1);
7702 
7703   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7704   else {
7705     *done = PETSC_TRUE;
7706     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7707     if (n)  *n = 0;
7708     if (ia) *ia = NULL;
7709     if (ja) *ja = NULL;
7710   }
7711   PetscFunctionReturn(0);
7712 }
7713 
7714 /*@C
7715     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7716     MatGetColumnIJ().
7717 
7718     Collective on Mat
7719 
7720     Input Parameters:
7721 +   mat - the matrix
7722 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7723 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7724                 symmetrized
7725 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7726                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7727                  always used.
7728 
7729     Output Parameters:
7730 +   n - size of (possibly compressed) matrix
7731 .   ia - the column pointers
7732 .   ja - the row indices
7733 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7734 
7735     Level: developer
7736 
7737 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7738 @*/
7739 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7740 {
7741   PetscErrorCode ierr;
7742 
7743   PetscFunctionBegin;
7744   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7745   PetscValidType(mat,1);
7746   if (ia) PetscValidIntPointer(ia,5);
7747   if (ja) PetscValidIntPointer(ja,6);
7748   PetscValidIntPointer(done,7);
7749   MatCheckPreallocated(mat,1);
7750 
7751   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7752   else {
7753     *done = PETSC_TRUE;
7754     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7755     if (n)  *n = 0;
7756     if (ia) *ia = NULL;
7757     if (ja) *ja = NULL;
7758   }
7759   PetscFunctionReturn(0);
7760 }
7761 
7762 /*@C
7763     MatColoringPatch -Used inside matrix coloring routines that
7764     use MatGetRowIJ() and/or MatGetColumnIJ().
7765 
7766     Collective on Mat
7767 
7768     Input Parameters:
7769 +   mat - the matrix
7770 .   ncolors - max color value
7771 .   n   - number of entries in colorarray
7772 -   colorarray - array indicating color for each column
7773 
7774     Output Parameters:
7775 .   iscoloring - coloring generated using colorarray information
7776 
7777     Level: developer
7778 
7779 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7780 
7781 @*/
7782 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7783 {
7784   PetscErrorCode ierr;
7785 
7786   PetscFunctionBegin;
7787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7788   PetscValidType(mat,1);
7789   PetscValidIntPointer(colorarray,4);
7790   PetscValidPointer(iscoloring,5);
7791   MatCheckPreallocated(mat,1);
7792 
7793   if (!mat->ops->coloringpatch) {
7794     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7795   } else {
7796     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7797   }
7798   PetscFunctionReturn(0);
7799 }
7800 
7801 
7802 /*@
7803    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7804 
7805    Logically Collective on Mat
7806 
7807    Input Parameter:
7808 .  mat - the factored matrix to be reset
7809 
7810    Notes:
7811    This routine should be used only with factored matrices formed by in-place
7812    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7813    format).  This option can save memory, for example, when solving nonlinear
7814    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7815    ILU(0) preconditioner.
7816 
7817    Note that one can specify in-place ILU(0) factorization by calling
7818 .vb
7819      PCType(pc,PCILU);
7820      PCFactorSeUseInPlace(pc);
7821 .ve
7822    or by using the options -pc_type ilu -pc_factor_in_place
7823 
7824    In-place factorization ILU(0) can also be used as a local
7825    solver for the blocks within the block Jacobi or additive Schwarz
7826    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7827    for details on setting local solver options.
7828 
7829    Most users should employ the simplified KSP interface for linear solvers
7830    instead of working directly with matrix algebra routines such as this.
7831    See, e.g., KSPCreate().
7832 
7833    Level: developer
7834 
7835 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7836 
7837    Concepts: matrices^unfactored
7838 
7839 @*/
7840 PetscErrorCode MatSetUnfactored(Mat mat)
7841 {
7842   PetscErrorCode ierr;
7843 
7844   PetscFunctionBegin;
7845   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7846   PetscValidType(mat,1);
7847   MatCheckPreallocated(mat,1);
7848   mat->factortype = MAT_FACTOR_NONE;
7849   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7850   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7851   PetscFunctionReturn(0);
7852 }
7853 
7854 /*MC
7855     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7856 
7857     Synopsis:
7858     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7859 
7860     Not collective
7861 
7862     Input Parameter:
7863 .   x - matrix
7864 
7865     Output Parameters:
7866 +   xx_v - the Fortran90 pointer to the array
7867 -   ierr - error code
7868 
7869     Example of Usage:
7870 .vb
7871       PetscScalar, pointer xx_v(:,:)
7872       ....
7873       call MatDenseGetArrayF90(x,xx_v,ierr)
7874       a = xx_v(3)
7875       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7876 .ve
7877 
7878     Level: advanced
7879 
7880 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7881 
7882     Concepts: matrices^accessing array
7883 
7884 M*/
7885 
7886 /*MC
7887     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7888     accessed with MatDenseGetArrayF90().
7889 
7890     Synopsis:
7891     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7892 
7893     Not collective
7894 
7895     Input Parameters:
7896 +   x - matrix
7897 -   xx_v - the Fortran90 pointer to the array
7898 
7899     Output Parameter:
7900 .   ierr - error code
7901 
7902     Example of Usage:
7903 .vb
7904        PetscScalar, pointer xx_v(:,:)
7905        ....
7906        call MatDenseGetArrayF90(x,xx_v,ierr)
7907        a = xx_v(3)
7908        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7909 .ve
7910 
7911     Level: advanced
7912 
7913 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7914 
7915 M*/
7916 
7917 
7918 /*MC
7919     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7920 
7921     Synopsis:
7922     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7923 
7924     Not collective
7925 
7926     Input Parameter:
7927 .   x - matrix
7928 
7929     Output Parameters:
7930 +   xx_v - the Fortran90 pointer to the array
7931 -   ierr - error code
7932 
7933     Example of Usage:
7934 .vb
7935       PetscScalar, pointer xx_v(:)
7936       ....
7937       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7938       a = xx_v(3)
7939       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7940 .ve
7941 
7942     Level: advanced
7943 
7944 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7945 
7946     Concepts: matrices^accessing array
7947 
7948 M*/
7949 
7950 /*MC
7951     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7952     accessed with MatSeqAIJGetArrayF90().
7953 
7954     Synopsis:
7955     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7956 
7957     Not collective
7958 
7959     Input Parameters:
7960 +   x - matrix
7961 -   xx_v - the Fortran90 pointer to the array
7962 
7963     Output Parameter:
7964 .   ierr - error code
7965 
7966     Example of Usage:
7967 .vb
7968        PetscScalar, pointer xx_v(:)
7969        ....
7970        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7971        a = xx_v(3)
7972        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7973 .ve
7974 
7975     Level: advanced
7976 
7977 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7978 
7979 M*/
7980 
7981 
7982 /*@
7983     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7984                       as the original matrix.
7985 
7986     Collective on Mat
7987 
7988     Input Parameters:
7989 +   mat - the original matrix
7990 .   isrow - parallel IS containing the rows this processor should obtain
7991 .   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.
7992 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7993 
7994     Output Parameter:
7995 .   newmat - the new submatrix, of the same type as the old
7996 
7997     Level: advanced
7998 
7999     Notes:
8000     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
8001 
8002     Some matrix types place restrictions on the row and column indices, such
8003     as that they be sorted or that they be equal to each other.
8004 
8005     The index sets may not have duplicate entries.
8006 
8007       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
8008    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
8009    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
8010    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
8011    you are finished using it.
8012 
8013     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
8014     the input matrix.
8015 
8016     If iscol is NULL then all columns are obtained (not supported in Fortran).
8017 
8018    Example usage:
8019    Consider the following 8x8 matrix with 34 non-zero values, that is
8020    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8021    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8022    as follows:
8023 
8024 .vb
8025             1  2  0  |  0  3  0  |  0  4
8026     Proc0   0  5  6  |  7  0  0  |  8  0
8027             9  0 10  | 11  0  0  | 12  0
8028     -------------------------------------
8029            13  0 14  | 15 16 17  |  0  0
8030     Proc1   0 18  0  | 19 20 21  |  0  0
8031             0  0  0  | 22 23  0  | 24  0
8032     -------------------------------------
8033     Proc2  25 26 27  |  0  0 28  | 29  0
8034            30  0  0  | 31 32 33  |  0 34
8035 .ve
8036 
8037     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8038 
8039 .vb
8040             2  0  |  0  3  0  |  0
8041     Proc0   5  6  |  7  0  0  |  8
8042     -------------------------------
8043     Proc1  18  0  | 19 20 21  |  0
8044     -------------------------------
8045     Proc2  26 27  |  0  0 28  | 29
8046             0  0  | 31 32 33  |  0
8047 .ve
8048 
8049 
8050     Concepts: matrices^submatrices
8051 
8052 .seealso: MatCreateSubMatrices()
8053 @*/
8054 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8055 {
8056   PetscErrorCode ierr;
8057   PetscMPIInt    size;
8058   Mat            *local;
8059   IS             iscoltmp;
8060 
8061   PetscFunctionBegin;
8062   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8063   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8064   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8065   PetscValidPointer(newmat,5);
8066   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8067   PetscValidType(mat,1);
8068   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8069   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8070 
8071   MatCheckPreallocated(mat,1);
8072   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8073 
8074   if (!iscol || isrow == iscol) {
8075     PetscBool   stride;
8076     PetscMPIInt grabentirematrix = 0,grab;
8077     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8078     if (stride) {
8079       PetscInt first,step,n,rstart,rend;
8080       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8081       if (step == 1) {
8082         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8083         if (rstart == first) {
8084           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8085           if (n == rend-rstart) {
8086             grabentirematrix = 1;
8087           }
8088         }
8089       }
8090     }
8091     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8092     if (grab) {
8093       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8094       if (cll == MAT_INITIAL_MATRIX) {
8095         *newmat = mat;
8096         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8097       }
8098       PetscFunctionReturn(0);
8099     }
8100   }
8101 
8102   if (!iscol) {
8103     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8104   } else {
8105     iscoltmp = iscol;
8106   }
8107 
8108   /* if original matrix is on just one processor then use submatrix generated */
8109   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8110     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8111     goto setproperties;
8112   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8113     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8114     *newmat = *local;
8115     ierr    = PetscFree(local);CHKERRQ(ierr);
8116     goto setproperties;
8117   } else if (!mat->ops->createsubmatrix) {
8118     /* Create a new matrix type that implements the operation using the full matrix */
8119     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8120     switch (cll) {
8121     case MAT_INITIAL_MATRIX:
8122       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8123       break;
8124     case MAT_REUSE_MATRIX:
8125       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8126       break;
8127     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8128     }
8129     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8130     goto setproperties;
8131   }
8132 
8133   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8134   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8135   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8136   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8137 
8138   /* Propagate symmetry information for diagonal blocks */
8139 setproperties:
8140   if (isrow == iscoltmp) {
8141     if (mat->symmetric_set && mat->symmetric) {
8142       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8143     }
8144     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8145       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8146     }
8147     if (mat->hermitian_set && mat->hermitian) {
8148       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8149     }
8150     if (mat->spd_set && mat->spd) {
8151       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8152     }
8153   }
8154 
8155   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8156   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8157   PetscFunctionReturn(0);
8158 }
8159 
8160 /*@
8161    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8162    used during the assembly process to store values that belong to
8163    other processors.
8164 
8165    Not Collective
8166 
8167    Input Parameters:
8168 +  mat   - the matrix
8169 .  size  - the initial size of the stash.
8170 -  bsize - the initial size of the block-stash(if used).
8171 
8172    Options Database Keys:
8173 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8174 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8175 
8176    Level: intermediate
8177 
8178    Notes:
8179      The block-stash is used for values set with MatSetValuesBlocked() while
8180      the stash is used for values set with MatSetValues()
8181 
8182      Run with the option -info and look for output of the form
8183      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8184      to determine the appropriate value, MM, to use for size and
8185      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8186      to determine the value, BMM to use for bsize
8187 
8188    Concepts: stash^setting matrix size
8189    Concepts: matrices^stash
8190 
8191 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8192 
8193 @*/
8194 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8195 {
8196   PetscErrorCode ierr;
8197 
8198   PetscFunctionBegin;
8199   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8200   PetscValidType(mat,1);
8201   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8202   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8203   PetscFunctionReturn(0);
8204 }
8205 
8206 /*@
8207    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8208      the matrix
8209 
8210    Neighbor-wise Collective on Mat
8211 
8212    Input Parameters:
8213 +  mat   - the matrix
8214 .  x,y - the vectors
8215 -  w - where the result is stored
8216 
8217    Level: intermediate
8218 
8219    Notes:
8220     w may be the same vector as y.
8221 
8222     This allows one to use either the restriction or interpolation (its transpose)
8223     matrix to do the interpolation
8224 
8225     Concepts: interpolation
8226 
8227 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8228 
8229 @*/
8230 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8231 {
8232   PetscErrorCode ierr;
8233   PetscInt       M,N,Ny;
8234 
8235   PetscFunctionBegin;
8236   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8237   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8238   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8239   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8240   PetscValidType(A,1);
8241   MatCheckPreallocated(A,1);
8242   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8243   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8244   if (M == Ny) {
8245     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8246   } else {
8247     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8248   }
8249   PetscFunctionReturn(0);
8250 }
8251 
8252 /*@
8253    MatInterpolate - y = A*x or A'*x depending on the shape of
8254      the matrix
8255 
8256    Neighbor-wise Collective on Mat
8257 
8258    Input Parameters:
8259 +  mat   - the matrix
8260 -  x,y - the vectors
8261 
8262    Level: intermediate
8263 
8264    Notes:
8265     This allows one to use either the restriction or interpolation (its transpose)
8266     matrix to do the interpolation
8267 
8268    Concepts: matrices^interpolation
8269 
8270 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8271 
8272 @*/
8273 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8274 {
8275   PetscErrorCode ierr;
8276   PetscInt       M,N,Ny;
8277 
8278   PetscFunctionBegin;
8279   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8280   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8281   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8282   PetscValidType(A,1);
8283   MatCheckPreallocated(A,1);
8284   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8285   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8286   if (M == Ny) {
8287     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8288   } else {
8289     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8290   }
8291   PetscFunctionReturn(0);
8292 }
8293 
8294 /*@
8295    MatRestrict - y = A*x or A'*x
8296 
8297    Neighbor-wise Collective on Mat
8298 
8299    Input Parameters:
8300 +  mat   - the matrix
8301 -  x,y - the vectors
8302 
8303    Level: intermediate
8304 
8305    Notes:
8306     This allows one to use either the restriction or interpolation (its transpose)
8307     matrix to do the restriction
8308 
8309    Concepts: matrices^restriction
8310 
8311 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8312 
8313 @*/
8314 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8315 {
8316   PetscErrorCode ierr;
8317   PetscInt       M,N,Ny;
8318 
8319   PetscFunctionBegin;
8320   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8321   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8322   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8323   PetscValidType(A,1);
8324   MatCheckPreallocated(A,1);
8325 
8326   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8327   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8328   if (M == Ny) {
8329     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8330   } else {
8331     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8332   }
8333   PetscFunctionReturn(0);
8334 }
8335 
8336 /*@
8337    MatGetNullSpace - retrieves the null space of a matrix.
8338 
8339    Logically Collective on Mat and MatNullSpace
8340 
8341    Input Parameters:
8342 +  mat - the matrix
8343 -  nullsp - the null space object
8344 
8345    Level: developer
8346 
8347    Concepts: null space^attaching to matrix
8348 
8349 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8350 @*/
8351 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8352 {
8353   PetscFunctionBegin;
8354   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8355   PetscValidPointer(nullsp,2);
8356   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8357   PetscFunctionReturn(0);
8358 }
8359 
8360 /*@
8361    MatSetNullSpace - attaches a null space to a matrix.
8362 
8363    Logically Collective on Mat and MatNullSpace
8364 
8365    Input Parameters:
8366 +  mat - the matrix
8367 -  nullsp - the null space object
8368 
8369    Level: advanced
8370 
8371    Notes:
8372       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8373 
8374       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8375       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8376 
8377       You can remove the null space by calling this routine with an nullsp of NULL
8378 
8379 
8380       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8381    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).
8382    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
8383    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
8384    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).
8385 
8386       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8387 
8388     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
8389     routine also automatically calls MatSetTransposeNullSpace().
8390 
8391    Concepts: null space^attaching to matrix
8392 
8393 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8394 @*/
8395 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8396 {
8397   PetscErrorCode ierr;
8398 
8399   PetscFunctionBegin;
8400   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8401   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8402   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8403   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8404   mat->nullsp = nullsp;
8405   if (mat->symmetric_set && mat->symmetric) {
8406     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8407   }
8408   PetscFunctionReturn(0);
8409 }
8410 
8411 /*@
8412    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8413 
8414    Logically Collective on Mat and MatNullSpace
8415 
8416    Input Parameters:
8417 +  mat - the matrix
8418 -  nullsp - the null space object
8419 
8420    Level: developer
8421 
8422    Concepts: null space^attaching to matrix
8423 
8424 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8425 @*/
8426 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8427 {
8428   PetscFunctionBegin;
8429   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8430   PetscValidType(mat,1);
8431   PetscValidPointer(nullsp,2);
8432   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8433   PetscFunctionReturn(0);
8434 }
8435 
8436 /*@
8437    MatSetTransposeNullSpace - attaches a null space to a matrix.
8438 
8439    Logically Collective on Mat and MatNullSpace
8440 
8441    Input Parameters:
8442 +  mat - the matrix
8443 -  nullsp - the null space object
8444 
8445    Level: advanced
8446 
8447    Notes:
8448       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.
8449       You must also call MatSetNullSpace()
8450 
8451 
8452       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8453    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).
8454    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
8455    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
8456    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).
8457 
8458       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8459 
8460    Concepts: null space^attaching to matrix
8461 
8462 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8463 @*/
8464 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8465 {
8466   PetscErrorCode ierr;
8467 
8468   PetscFunctionBegin;
8469   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8470   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8471   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8472   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8473   mat->transnullsp = nullsp;
8474   PetscFunctionReturn(0);
8475 }
8476 
8477 /*@
8478    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8479         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8480 
8481    Logically Collective on Mat and MatNullSpace
8482 
8483    Input Parameters:
8484 +  mat - the matrix
8485 -  nullsp - the null space object
8486 
8487    Level: advanced
8488 
8489    Notes:
8490       Overwrites any previous near null space that may have been attached
8491 
8492       You can remove the null space by calling this routine with an nullsp of NULL
8493 
8494    Concepts: null space^attaching to matrix
8495 
8496 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8497 @*/
8498 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8499 {
8500   PetscErrorCode ierr;
8501 
8502   PetscFunctionBegin;
8503   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8504   PetscValidType(mat,1);
8505   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8506   MatCheckPreallocated(mat,1);
8507   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8508   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8509   mat->nearnullsp = nullsp;
8510   PetscFunctionReturn(0);
8511 }
8512 
8513 /*@
8514    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8515 
8516    Not Collective
8517 
8518    Input Parameters:
8519 .  mat - the matrix
8520 
8521    Output Parameters:
8522 .  nullsp - the null space object, NULL if not set
8523 
8524    Level: developer
8525 
8526    Concepts: null space^attaching to matrix
8527 
8528 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8529 @*/
8530 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8531 {
8532   PetscFunctionBegin;
8533   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8534   PetscValidType(mat,1);
8535   PetscValidPointer(nullsp,2);
8536   MatCheckPreallocated(mat,1);
8537   *nullsp = mat->nearnullsp;
8538   PetscFunctionReturn(0);
8539 }
8540 
8541 /*@C
8542    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8543 
8544    Collective on Mat
8545 
8546    Input Parameters:
8547 +  mat - the matrix
8548 .  row - row/column permutation
8549 .  fill - expected fill factor >= 1.0
8550 -  level - level of fill, for ICC(k)
8551 
8552    Notes:
8553    Probably really in-place only when level of fill is zero, otherwise allocates
8554    new space to store factored matrix and deletes previous memory.
8555 
8556    Most users should employ the simplified KSP interface for linear solvers
8557    instead of working directly with matrix algebra routines such as this.
8558    See, e.g., KSPCreate().
8559 
8560    Level: developer
8561 
8562    Concepts: matrices^incomplete Cholesky factorization
8563    Concepts: Cholesky factorization
8564 
8565 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8566 
8567     Developer Note: fortran interface is not autogenerated as the f90
8568     interface defintion cannot be generated correctly [due to MatFactorInfo]
8569 
8570 @*/
8571 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8572 {
8573   PetscErrorCode ierr;
8574 
8575   PetscFunctionBegin;
8576   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8577   PetscValidType(mat,1);
8578   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8579   PetscValidPointer(info,3);
8580   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8581   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8582   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8583   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8584   MatCheckPreallocated(mat,1);
8585   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8586   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8587   PetscFunctionReturn(0);
8588 }
8589 
8590 /*@
8591    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8592          ghosted ones.
8593 
8594    Not Collective
8595 
8596    Input Parameters:
8597 +  mat - the matrix
8598 -  diag = the diagonal values, including ghost ones
8599 
8600    Level: developer
8601 
8602    Notes:
8603     Works only for MPIAIJ and MPIBAIJ matrices
8604 
8605 .seealso: MatDiagonalScale()
8606 @*/
8607 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8608 {
8609   PetscErrorCode ierr;
8610   PetscMPIInt    size;
8611 
8612   PetscFunctionBegin;
8613   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8614   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8615   PetscValidType(mat,1);
8616 
8617   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8618   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8619   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8620   if (size == 1) {
8621     PetscInt n,m;
8622     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8623     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8624     if (m == n) {
8625       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8626     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8627   } else {
8628     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8629   }
8630   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8631   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8632   PetscFunctionReturn(0);
8633 }
8634 
8635 /*@
8636    MatGetInertia - Gets the inertia from a factored matrix
8637 
8638    Collective on Mat
8639 
8640    Input Parameter:
8641 .  mat - the matrix
8642 
8643    Output Parameters:
8644 +   nneg - number of negative eigenvalues
8645 .   nzero - number of zero eigenvalues
8646 -   npos - number of positive eigenvalues
8647 
8648    Level: advanced
8649 
8650    Notes:
8651     Matrix must have been factored by MatCholeskyFactor()
8652 
8653 
8654 @*/
8655 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8656 {
8657   PetscErrorCode ierr;
8658 
8659   PetscFunctionBegin;
8660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8661   PetscValidType(mat,1);
8662   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8663   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8664   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8665   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8666   PetscFunctionReturn(0);
8667 }
8668 
8669 /* ----------------------------------------------------------------*/
8670 /*@C
8671    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8672 
8673    Neighbor-wise Collective on Mat and Vecs
8674 
8675    Input Parameters:
8676 +  mat - the factored matrix
8677 -  b - the right-hand-side vectors
8678 
8679    Output Parameter:
8680 .  x - the result vectors
8681 
8682    Notes:
8683    The vectors b and x cannot be the same.  I.e., one cannot
8684    call MatSolves(A,x,x).
8685 
8686    Notes:
8687    Most users should employ the simplified KSP interface for linear solvers
8688    instead of working directly with matrix algebra routines such as this.
8689    See, e.g., KSPCreate().
8690 
8691    Level: developer
8692 
8693    Concepts: matrices^triangular solves
8694 
8695 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8696 @*/
8697 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8698 {
8699   PetscErrorCode ierr;
8700 
8701   PetscFunctionBegin;
8702   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8703   PetscValidType(mat,1);
8704   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8705   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8706   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8707 
8708   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8709   MatCheckPreallocated(mat,1);
8710   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8711   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8712   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8713   PetscFunctionReturn(0);
8714 }
8715 
8716 /*@
8717    MatIsSymmetric - Test whether a matrix is symmetric
8718 
8719    Collective on Mat
8720 
8721    Input Parameter:
8722 +  A - the matrix to test
8723 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8724 
8725    Output Parameters:
8726 .  flg - the result
8727 
8728    Notes:
8729     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8730 
8731    Level: intermediate
8732 
8733    Concepts: matrix^symmetry
8734 
8735 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8736 @*/
8737 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8738 {
8739   PetscErrorCode ierr;
8740 
8741   PetscFunctionBegin;
8742   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8743   PetscValidPointer(flg,2);
8744 
8745   if (!A->symmetric_set) {
8746     if (!A->ops->issymmetric) {
8747       MatType mattype;
8748       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8749       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8750     }
8751     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8752     if (!tol) {
8753       A->symmetric_set = PETSC_TRUE;
8754       A->symmetric     = *flg;
8755       if (A->symmetric) {
8756         A->structurally_symmetric_set = PETSC_TRUE;
8757         A->structurally_symmetric     = PETSC_TRUE;
8758       }
8759     }
8760   } else if (A->symmetric) {
8761     *flg = PETSC_TRUE;
8762   } else if (!tol) {
8763     *flg = PETSC_FALSE;
8764   } else {
8765     if (!A->ops->issymmetric) {
8766       MatType mattype;
8767       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8768       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8769     }
8770     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8771   }
8772   PetscFunctionReturn(0);
8773 }
8774 
8775 /*@
8776    MatIsHermitian - Test whether a matrix is Hermitian
8777 
8778    Collective on Mat
8779 
8780    Input Parameter:
8781 +  A - the matrix to test
8782 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8783 
8784    Output Parameters:
8785 .  flg - the result
8786 
8787    Level: intermediate
8788 
8789    Concepts: matrix^symmetry
8790 
8791 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8792           MatIsSymmetricKnown(), MatIsSymmetric()
8793 @*/
8794 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8795 {
8796   PetscErrorCode ierr;
8797 
8798   PetscFunctionBegin;
8799   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8800   PetscValidPointer(flg,2);
8801 
8802   if (!A->hermitian_set) {
8803     if (!A->ops->ishermitian) {
8804       MatType mattype;
8805       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8806       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8807     }
8808     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8809     if (!tol) {
8810       A->hermitian_set = PETSC_TRUE;
8811       A->hermitian     = *flg;
8812       if (A->hermitian) {
8813         A->structurally_symmetric_set = PETSC_TRUE;
8814         A->structurally_symmetric     = PETSC_TRUE;
8815       }
8816     }
8817   } else if (A->hermitian) {
8818     *flg = PETSC_TRUE;
8819   } else if (!tol) {
8820     *flg = PETSC_FALSE;
8821   } else {
8822     if (!A->ops->ishermitian) {
8823       MatType mattype;
8824       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8825       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8826     }
8827     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8828   }
8829   PetscFunctionReturn(0);
8830 }
8831 
8832 /*@
8833    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8834 
8835    Not Collective
8836 
8837    Input Parameter:
8838 .  A - the matrix to check
8839 
8840    Output Parameters:
8841 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8842 -  flg - the result
8843 
8844    Level: advanced
8845 
8846    Concepts: matrix^symmetry
8847 
8848    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8849          if you want it explicitly checked
8850 
8851 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8852 @*/
8853 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8854 {
8855   PetscFunctionBegin;
8856   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8857   PetscValidPointer(set,2);
8858   PetscValidPointer(flg,3);
8859   if (A->symmetric_set) {
8860     *set = PETSC_TRUE;
8861     *flg = A->symmetric;
8862   } else {
8863     *set = PETSC_FALSE;
8864   }
8865   PetscFunctionReturn(0);
8866 }
8867 
8868 /*@
8869    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8870 
8871    Not Collective
8872 
8873    Input Parameter:
8874 .  A - the matrix to check
8875 
8876    Output Parameters:
8877 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8878 -  flg - the result
8879 
8880    Level: advanced
8881 
8882    Concepts: matrix^symmetry
8883 
8884    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8885          if you want it explicitly checked
8886 
8887 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8888 @*/
8889 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8890 {
8891   PetscFunctionBegin;
8892   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8893   PetscValidPointer(set,2);
8894   PetscValidPointer(flg,3);
8895   if (A->hermitian_set) {
8896     *set = PETSC_TRUE;
8897     *flg = A->hermitian;
8898   } else {
8899     *set = PETSC_FALSE;
8900   }
8901   PetscFunctionReturn(0);
8902 }
8903 
8904 /*@
8905    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8906 
8907    Collective on Mat
8908 
8909    Input Parameter:
8910 .  A - the matrix to test
8911 
8912    Output Parameters:
8913 .  flg - the result
8914 
8915    Level: intermediate
8916 
8917    Concepts: matrix^symmetry
8918 
8919 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8920 @*/
8921 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8922 {
8923   PetscErrorCode ierr;
8924 
8925   PetscFunctionBegin;
8926   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8927   PetscValidPointer(flg,2);
8928   if (!A->structurally_symmetric_set) {
8929     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8930     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8931 
8932     A->structurally_symmetric_set = PETSC_TRUE;
8933   }
8934   *flg = A->structurally_symmetric;
8935   PetscFunctionReturn(0);
8936 }
8937 
8938 /*@
8939    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8940        to be communicated to other processors during the MatAssemblyBegin/End() process
8941 
8942     Not collective
8943 
8944    Input Parameter:
8945 .   vec - the vector
8946 
8947    Output Parameters:
8948 +   nstash   - the size of the stash
8949 .   reallocs - the number of additional mallocs incurred.
8950 .   bnstash   - the size of the block stash
8951 -   breallocs - the number of additional mallocs incurred.in the block stash
8952 
8953    Level: advanced
8954 
8955 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8956 
8957 @*/
8958 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8959 {
8960   PetscErrorCode ierr;
8961 
8962   PetscFunctionBegin;
8963   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8964   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8965   PetscFunctionReturn(0);
8966 }
8967 
8968 /*@C
8969    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8970      parallel layout
8971 
8972    Collective on Mat
8973 
8974    Input Parameter:
8975 .  mat - the matrix
8976 
8977    Output Parameter:
8978 +   right - (optional) vector that the matrix can be multiplied against
8979 -   left - (optional) vector that the matrix vector product can be stored in
8980 
8981    Notes:
8982     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().
8983 
8984   Notes:
8985     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8986 
8987   Level: advanced
8988 
8989 .seealso: MatCreate(), VecDestroy()
8990 @*/
8991 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8992 {
8993   PetscErrorCode ierr;
8994 
8995   PetscFunctionBegin;
8996   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8997   PetscValidType(mat,1);
8998   if (mat->ops->getvecs) {
8999     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
9000   } else {
9001     PetscInt rbs,cbs;
9002     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
9003     if (right) {
9004       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
9005       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
9006       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9007       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
9008       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
9009       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
9010     }
9011     if (left) {
9012       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
9013       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
9014       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
9015       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
9016       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
9017       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
9018     }
9019   }
9020   PetscFunctionReturn(0);
9021 }
9022 
9023 /*@C
9024    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9025      with default values.
9026 
9027    Not Collective
9028 
9029    Input Parameters:
9030 .    info - the MatFactorInfo data structure
9031 
9032 
9033    Notes:
9034     The solvers are generally used through the KSP and PC objects, for example
9035           PCLU, PCILU, PCCHOLESKY, PCICC
9036 
9037    Level: developer
9038 
9039 .seealso: MatFactorInfo
9040 
9041     Developer Note: fortran interface is not autogenerated as the f90
9042     interface defintion cannot be generated correctly [due to MatFactorInfo]
9043 
9044 @*/
9045 
9046 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9047 {
9048   PetscErrorCode ierr;
9049 
9050   PetscFunctionBegin;
9051   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9052   PetscFunctionReturn(0);
9053 }
9054 
9055 /*@
9056    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9057 
9058    Collective on Mat
9059 
9060    Input Parameters:
9061 +  mat - the factored matrix
9062 -  is - the index set defining the Schur indices (0-based)
9063 
9064    Notes:
9065     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9066 
9067    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9068 
9069    Level: developer
9070 
9071    Concepts:
9072 
9073 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9074           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9075 
9076 @*/
9077 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9078 {
9079   PetscErrorCode ierr,(*f)(Mat,IS);
9080 
9081   PetscFunctionBegin;
9082   PetscValidType(mat,1);
9083   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9084   PetscValidType(is,2);
9085   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9086   PetscCheckSameComm(mat,1,is,2);
9087   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9088   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9089   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");
9090   if (mat->schur) {
9091     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9092   }
9093   ierr = (*f)(mat,is);CHKERRQ(ierr);
9094   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9095   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9096   PetscFunctionReturn(0);
9097 }
9098 
9099 /*@
9100   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9101 
9102    Logically Collective on Mat
9103 
9104    Input Parameters:
9105 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9106 .  S - location where to return the Schur complement, can be NULL
9107 -  status - the status of the Schur complement matrix, can be NULL
9108 
9109    Notes:
9110    You must call MatFactorSetSchurIS() before calling this routine.
9111 
9112    The routine provides a copy of the Schur matrix stored within the solver data structures.
9113    The caller must destroy the object when it is no longer needed.
9114    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9115 
9116    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)
9117 
9118    Developer Notes:
9119     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9120    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9121 
9122    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9123 
9124    Level: advanced
9125 
9126    References:
9127 
9128 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9129 @*/
9130 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9131 {
9132   PetscErrorCode ierr;
9133 
9134   PetscFunctionBegin;
9135   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9136   if (S) PetscValidPointer(S,2);
9137   if (status) PetscValidPointer(status,3);
9138   if (S) {
9139     PetscErrorCode (*f)(Mat,Mat*);
9140 
9141     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9142     if (f) {
9143       ierr = (*f)(F,S);CHKERRQ(ierr);
9144     } else {
9145       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9146     }
9147   }
9148   if (status) *status = F->schur_status;
9149   PetscFunctionReturn(0);
9150 }
9151 
9152 /*@
9153   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9154 
9155    Logically Collective on Mat
9156 
9157    Input Parameters:
9158 +  F - the factored matrix obtained by calling MatGetFactor()
9159 .  *S - location where to return the Schur complement, can be NULL
9160 -  status - the status of the Schur complement matrix, can be NULL
9161 
9162    Notes:
9163    You must call MatFactorSetSchurIS() before calling this routine.
9164 
9165    Schur complement mode is currently implemented for sequential matrices.
9166    The routine returns a the Schur Complement stored within the data strutures of the solver.
9167    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9168    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9169 
9170    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9171 
9172    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9173 
9174    Level: advanced
9175 
9176    References:
9177 
9178 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9179 @*/
9180 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9181 {
9182   PetscFunctionBegin;
9183   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9184   if (S) PetscValidPointer(S,2);
9185   if (status) PetscValidPointer(status,3);
9186   if (S) *S = F->schur;
9187   if (status) *status = F->schur_status;
9188   PetscFunctionReturn(0);
9189 }
9190 
9191 /*@
9192   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9193 
9194    Logically Collective on Mat
9195 
9196    Input Parameters:
9197 +  F - the factored matrix obtained by calling MatGetFactor()
9198 .  *S - location where the Schur complement is stored
9199 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9200 
9201    Notes:
9202 
9203    Level: advanced
9204 
9205    References:
9206 
9207 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9208 @*/
9209 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9210 {
9211   PetscErrorCode ierr;
9212 
9213   PetscFunctionBegin;
9214   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9215   if (S) {
9216     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9217     *S = NULL;
9218   }
9219   F->schur_status = status;
9220   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9221   PetscFunctionReturn(0);
9222 }
9223 
9224 /*@
9225   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9226 
9227    Logically Collective on Mat
9228 
9229    Input Parameters:
9230 +  F - the factored matrix obtained by calling MatGetFactor()
9231 .  rhs - location where the right hand side of the Schur complement system is stored
9232 -  sol - location where the solution of the Schur complement system has to be returned
9233 
9234    Notes:
9235    The sizes of the vectors should match the size of the Schur complement
9236 
9237    Must be called after MatFactorSetSchurIS()
9238 
9239    Level: advanced
9240 
9241    References:
9242 
9243 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9244 @*/
9245 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9246 {
9247   PetscErrorCode ierr;
9248 
9249   PetscFunctionBegin;
9250   PetscValidType(F,1);
9251   PetscValidType(rhs,2);
9252   PetscValidType(sol,3);
9253   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9254   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9255   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9256   PetscCheckSameComm(F,1,rhs,2);
9257   PetscCheckSameComm(F,1,sol,3);
9258   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9259   switch (F->schur_status) {
9260   case MAT_FACTOR_SCHUR_FACTORED:
9261     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9262     break;
9263   case MAT_FACTOR_SCHUR_INVERTED:
9264     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9265     break;
9266   default:
9267     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9268     break;
9269   }
9270   PetscFunctionReturn(0);
9271 }
9272 
9273 /*@
9274   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9275 
9276    Logically Collective on Mat
9277 
9278    Input Parameters:
9279 +  F - the factored matrix obtained by calling MatGetFactor()
9280 .  rhs - location where the right hand side of the Schur complement system is stored
9281 -  sol - location where the solution of the Schur complement system has to be returned
9282 
9283    Notes:
9284    The sizes of the vectors should match the size of the Schur complement
9285 
9286    Must be called after MatFactorSetSchurIS()
9287 
9288    Level: advanced
9289 
9290    References:
9291 
9292 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9293 @*/
9294 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9295 {
9296   PetscErrorCode ierr;
9297 
9298   PetscFunctionBegin;
9299   PetscValidType(F,1);
9300   PetscValidType(rhs,2);
9301   PetscValidType(sol,3);
9302   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9303   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9304   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9305   PetscCheckSameComm(F,1,rhs,2);
9306   PetscCheckSameComm(F,1,sol,3);
9307   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9308   switch (F->schur_status) {
9309   case MAT_FACTOR_SCHUR_FACTORED:
9310     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9311     break;
9312   case MAT_FACTOR_SCHUR_INVERTED:
9313     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9314     break;
9315   default:
9316     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9317     break;
9318   }
9319   PetscFunctionReturn(0);
9320 }
9321 
9322 /*@
9323   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9324 
9325    Logically Collective on Mat
9326 
9327    Input Parameters:
9328 +  F - the factored matrix obtained by calling MatGetFactor()
9329 
9330    Notes:
9331     Must be called after MatFactorSetSchurIS().
9332 
9333    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9334 
9335    Level: advanced
9336 
9337    References:
9338 
9339 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9340 @*/
9341 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9342 {
9343   PetscErrorCode ierr;
9344 
9345   PetscFunctionBegin;
9346   PetscValidType(F,1);
9347   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9348   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9349   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9350   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9351   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9352   PetscFunctionReturn(0);
9353 }
9354 
9355 /*@
9356   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9357 
9358    Logically Collective on Mat
9359 
9360    Input Parameters:
9361 +  F - the factored matrix obtained by calling MatGetFactor()
9362 
9363    Notes:
9364     Must be called after MatFactorSetSchurIS().
9365 
9366    Level: advanced
9367 
9368    References:
9369 
9370 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9371 @*/
9372 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9373 {
9374   PetscErrorCode ierr;
9375 
9376   PetscFunctionBegin;
9377   PetscValidType(F,1);
9378   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9379   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9380   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9381   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9382   PetscFunctionReturn(0);
9383 }
9384 
9385 static PetscErrorCode MatPtAP_fallback(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9386 {
9387   Mat            AP;
9388   PetscErrorCode ierr;
9389 
9390   PetscFunctionBegin;
9391   ierr = PetscInfo(A,"Using fallback PtAP implementation\n");CHKERRQ(ierr);
9392   ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr);
9393   ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr);
9394   ierr = MatDestroy(&AP);CHKERRQ(ierr);
9395   PetscFunctionReturn(0);
9396 }
9397 
9398 /*@
9399    MatPtAP - Creates the matrix product C = P^T * A * P
9400 
9401    Neighbor-wise Collective on Mat
9402 
9403    Input Parameters:
9404 +  A - the matrix
9405 .  P - the projection matrix
9406 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9407 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9408           if the result is a dense matrix this is irrelevent
9409 
9410    Output Parameters:
9411 .  C - the product matrix
9412 
9413    Notes:
9414    C will be created and must be destroyed by the user with MatDestroy().
9415 
9416    For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult().
9417 
9418    Level: intermediate
9419 
9420 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9421 @*/
9422 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9423 {
9424   PetscErrorCode ierr;
9425   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9426   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9427   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9428   PetscBool      sametype;
9429 
9430   PetscFunctionBegin;
9431   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9432   PetscValidType(A,1);
9433   MatCheckPreallocated(A,1);
9434   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9435   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9436   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9437   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9438   PetscValidType(P,2);
9439   MatCheckPreallocated(P,2);
9440   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9441   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9442 
9443   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);
9444   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);
9445   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9446   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9447 
9448   if (scall == MAT_REUSE_MATRIX) {
9449     PetscValidPointer(*C,5);
9450     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9451 
9452     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9453     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9454     if ((*C)->ops->ptapnumeric) {
9455       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9456     } else {
9457       ierr = MatPtAP_fallback(A,P,scall,fill,C);
9458     }
9459     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9460     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9461     PetscFunctionReturn(0);
9462   }
9463 
9464   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9465   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9466 
9467   fA = A->ops->ptap;
9468   fP = P->ops->ptap;
9469   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9470   if (fP == fA && sametype) {
9471     ptap = fA;
9472   } else {
9473     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9474     char ptapname[256];
9475     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9476     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9477     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9478     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9479     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9480     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9481   }
9482 
9483   if (!ptap) ptap = MatPtAP_fallback;
9484   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9485   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9486   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9487   if (A->symmetric_set && A->symmetric) {
9488     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9489   }
9490   PetscFunctionReturn(0);
9491 }
9492 
9493 /*@
9494    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9495 
9496    Neighbor-wise Collective on Mat
9497 
9498    Input Parameters:
9499 +  A - the matrix
9500 -  P - the projection matrix
9501 
9502    Output Parameters:
9503 .  C - the product matrix
9504 
9505    Notes:
9506    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9507    the user using MatDeatroy().
9508 
9509    This routine is currently only implemented for pairs of AIJ matrices and classes
9510    which inherit from AIJ.  C will be of type MATAIJ.
9511 
9512    Level: intermediate
9513 
9514 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9515 @*/
9516 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9517 {
9518   PetscErrorCode ierr;
9519 
9520   PetscFunctionBegin;
9521   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9522   PetscValidType(A,1);
9523   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9524   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9525   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9526   PetscValidType(P,2);
9527   MatCheckPreallocated(P,2);
9528   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9529   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9530   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9531   PetscValidType(C,3);
9532   MatCheckPreallocated(C,3);
9533   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9534   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);
9535   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);
9536   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);
9537   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);
9538   MatCheckPreallocated(A,1);
9539 
9540   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9541   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9542   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9543   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9544   PetscFunctionReturn(0);
9545 }
9546 
9547 /*@
9548    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9549 
9550    Neighbor-wise Collective on Mat
9551 
9552    Input Parameters:
9553 +  A - the matrix
9554 -  P - the projection matrix
9555 
9556    Output Parameters:
9557 .  C - the (i,j) structure of the product matrix
9558 
9559    Notes:
9560    C will be created and must be destroyed by the user with MatDestroy().
9561 
9562    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9563    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9564    this (i,j) structure by calling MatPtAPNumeric().
9565 
9566    Level: intermediate
9567 
9568 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9569 @*/
9570 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9571 {
9572   PetscErrorCode ierr;
9573 
9574   PetscFunctionBegin;
9575   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9576   PetscValidType(A,1);
9577   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9578   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9579   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9580   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9581   PetscValidType(P,2);
9582   MatCheckPreallocated(P,2);
9583   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9584   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9585   PetscValidPointer(C,3);
9586 
9587   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);
9588   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);
9589   MatCheckPreallocated(A,1);
9590 
9591   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9592   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9593   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9594   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9595 
9596   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9597   PetscFunctionReturn(0);
9598 }
9599 
9600 /*@
9601    MatRARt - Creates the matrix product C = R * A * R^T
9602 
9603    Neighbor-wise Collective on Mat
9604 
9605    Input Parameters:
9606 +  A - the matrix
9607 .  R - the projection matrix
9608 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9609 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9610           if the result is a dense matrix this is irrelevent
9611 
9612    Output Parameters:
9613 .  C - the product matrix
9614 
9615    Notes:
9616    C will be created and must be destroyed by the user with MatDestroy().
9617 
9618    This routine is currently only implemented for pairs of AIJ matrices and classes
9619    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9620    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9621    We recommend using MatPtAP().
9622 
9623    Level: intermediate
9624 
9625 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9626 @*/
9627 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9628 {
9629   PetscErrorCode ierr;
9630 
9631   PetscFunctionBegin;
9632   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9633   PetscValidType(A,1);
9634   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9635   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9636   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9637   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9638   PetscValidType(R,2);
9639   MatCheckPreallocated(R,2);
9640   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9641   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9642   PetscValidPointer(C,3);
9643   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);
9644 
9645   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9646   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9647   MatCheckPreallocated(A,1);
9648 
9649   if (!A->ops->rart) {
9650     Mat Rt;
9651     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9652     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9653     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9654     PetscFunctionReturn(0);
9655   }
9656   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9657   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9658   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9659   PetscFunctionReturn(0);
9660 }
9661 
9662 /*@
9663    MatRARtNumeric - Computes 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 product matrix
9673 
9674    Notes:
9675    C must have been created by calling MatRARtSymbolic and must be destroyed by
9676    the user using MatDestroy().
9677 
9678    This routine is currently only implemented for pairs of AIJ matrices and classes
9679    which inherit from AIJ.  C will be of type MATAIJ.
9680 
9681    Level: intermediate
9682 
9683 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9684 @*/
9685 PetscErrorCode MatRARtNumeric(Mat A,Mat R,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   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9695   PetscValidType(R,2);
9696   MatCheckPreallocated(R,2);
9697   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9698   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9699   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9700   PetscValidType(C,3);
9701   MatCheckPreallocated(C,3);
9702   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9703   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);
9704   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);
9705   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);
9706   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);
9707   MatCheckPreallocated(A,1);
9708 
9709   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9710   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9711   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9712   PetscFunctionReturn(0);
9713 }
9714 
9715 /*@
9716    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9717 
9718    Neighbor-wise Collective on Mat
9719 
9720    Input Parameters:
9721 +  A - the matrix
9722 -  R - the projection matrix
9723 
9724    Output Parameters:
9725 .  C - the (i,j) structure of the product matrix
9726 
9727    Notes:
9728    C will be created and must be destroyed by the user with MatDestroy().
9729 
9730    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9731    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9732    this (i,j) structure by calling MatRARtNumeric().
9733 
9734    Level: intermediate
9735 
9736 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9737 @*/
9738 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9739 {
9740   PetscErrorCode ierr;
9741 
9742   PetscFunctionBegin;
9743   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9744   PetscValidType(A,1);
9745   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9746   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9747   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9748   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9749   PetscValidType(R,2);
9750   MatCheckPreallocated(R,2);
9751   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9752   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9753   PetscValidPointer(C,3);
9754 
9755   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);
9756   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);
9757   MatCheckPreallocated(A,1);
9758   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9759   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9760   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9761 
9762   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9763   PetscFunctionReturn(0);
9764 }
9765 
9766 /*@
9767    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9768 
9769    Neighbor-wise Collective on Mat
9770 
9771    Input Parameters:
9772 +  A - the left matrix
9773 .  B - the right matrix
9774 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9775 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9776           if the result is a dense matrix this is irrelevent
9777 
9778    Output Parameters:
9779 .  C - the product matrix
9780 
9781    Notes:
9782    Unless scall is MAT_REUSE_MATRIX C will be created.
9783 
9784    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
9785    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9786 
9787    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9788    actually needed.
9789 
9790    If you have many matrices with the same non-zero structure to multiply, you
9791    should either
9792 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9793 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9794    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
9795    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9796 
9797    Level: intermediate
9798 
9799 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9800 @*/
9801 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9802 {
9803   PetscErrorCode ierr;
9804   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9805   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9806   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9807 
9808   PetscFunctionBegin;
9809   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9810   PetscValidType(A,1);
9811   MatCheckPreallocated(A,1);
9812   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9813   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9814   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9815   PetscValidType(B,2);
9816   MatCheckPreallocated(B,2);
9817   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9818   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9819   PetscValidPointer(C,3);
9820   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9821   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);
9822   if (scall == MAT_REUSE_MATRIX) {
9823     PetscValidPointer(*C,5);
9824     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9825     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9826     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9827     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9828     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9829     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9830     PetscFunctionReturn(0);
9831   }
9832   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9833   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9834 
9835   fA = A->ops->matmult;
9836   fB = B->ops->matmult;
9837   if (fB == fA) {
9838     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9839     mult = fB;
9840   } else {
9841     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9842     char multname[256];
9843     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9844     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9845     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9846     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9847     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9848     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9849     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);
9850   }
9851   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9852   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9853   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9854   PetscFunctionReturn(0);
9855 }
9856 
9857 /*@
9858    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9859    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9860 
9861    Neighbor-wise Collective on Mat
9862 
9863    Input Parameters:
9864 +  A - the left matrix
9865 .  B - the right matrix
9866 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9867       if C is a dense matrix this is irrelevent
9868 
9869    Output Parameters:
9870 .  C - the product matrix
9871 
9872    Notes:
9873    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9874    actually needed.
9875 
9876    This routine is currently implemented for
9877     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9878     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9879     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9880 
9881    Level: intermediate
9882 
9883    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9884      We should incorporate them into PETSc.
9885 
9886 .seealso: MatMatMult(), MatMatMultNumeric()
9887 @*/
9888 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9889 {
9890   PetscErrorCode ierr;
9891   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9892   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9893   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9894 
9895   PetscFunctionBegin;
9896   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9897   PetscValidType(A,1);
9898   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9899   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9900 
9901   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9902   PetscValidType(B,2);
9903   MatCheckPreallocated(B,2);
9904   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9905   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9906   PetscValidPointer(C,3);
9907 
9908   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);
9909   if (fill == PETSC_DEFAULT) fill = 2.0;
9910   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9911   MatCheckPreallocated(A,1);
9912 
9913   Asymbolic = A->ops->matmultsymbolic;
9914   Bsymbolic = B->ops->matmultsymbolic;
9915   if (Asymbolic == Bsymbolic) {
9916     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9917     symbolic = Bsymbolic;
9918   } else { /* dispatch based on the type of A and B */
9919     char symbolicname[256];
9920     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9921     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9922     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9923     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9924     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9925     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9926     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);
9927   }
9928   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9929   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9930   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9931   PetscFunctionReturn(0);
9932 }
9933 
9934 /*@
9935    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9936    Call this routine after first calling MatMatMultSymbolic().
9937 
9938    Neighbor-wise Collective on Mat
9939 
9940    Input Parameters:
9941 +  A - the left matrix
9942 -  B - the right matrix
9943 
9944    Output Parameters:
9945 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9946 
9947    Notes:
9948    C must have been created with MatMatMultSymbolic().
9949 
9950    This routine is currently implemented for
9951     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9952     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9953     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9954 
9955    Level: intermediate
9956 
9957 .seealso: MatMatMult(), MatMatMultSymbolic()
9958 @*/
9959 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9960 {
9961   PetscErrorCode ierr;
9962 
9963   PetscFunctionBegin;
9964   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9965   PetscFunctionReturn(0);
9966 }
9967 
9968 /*@
9969    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9970 
9971    Neighbor-wise Collective on Mat
9972 
9973    Input Parameters:
9974 +  A - the left matrix
9975 .  B - the right matrix
9976 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9977 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9978 
9979    Output Parameters:
9980 .  C - the product matrix
9981 
9982    Notes:
9983    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9984 
9985    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9986 
9987   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9988    actually needed.
9989 
9990    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9991    and for pairs of MPIDense matrices.
9992 
9993    Options Database Keys:
9994 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9995                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9996                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9997 
9998    Level: intermediate
9999 
10000 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
10001 @*/
10002 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10003 {
10004   PetscErrorCode ierr;
10005   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10006   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10007 
10008   PetscFunctionBegin;
10009   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10010   PetscValidType(A,1);
10011   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10012   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10013   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10014   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10015   PetscValidType(B,2);
10016   MatCheckPreallocated(B,2);
10017   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10018   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10019   PetscValidPointer(C,3);
10020   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);
10021   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10022   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10023   MatCheckPreallocated(A,1);
10024 
10025   fA = A->ops->mattransposemult;
10026   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
10027   fB = B->ops->mattransposemult;
10028   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
10029   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);
10030 
10031   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10032   if (scall == MAT_INITIAL_MATRIX) {
10033     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10034     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
10035     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10036   }
10037   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10038   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10039   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10040   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10041   PetscFunctionReturn(0);
10042 }
10043 
10044 /*@
10045    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10046 
10047    Neighbor-wise Collective on Mat
10048 
10049    Input Parameters:
10050 +  A - the left matrix
10051 .  B - the right matrix
10052 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10053 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10054 
10055    Output Parameters:
10056 .  C - the product matrix
10057 
10058    Notes:
10059    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10060 
10061    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10062 
10063   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10064    actually needed.
10065 
10066    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10067    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10068 
10069    Level: intermediate
10070 
10071 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10072 @*/
10073 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10074 {
10075   PetscErrorCode ierr;
10076   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10077   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10078   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10079 
10080   PetscFunctionBegin;
10081   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10082   PetscValidType(A,1);
10083   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10084   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10085   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10086   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10087   PetscValidType(B,2);
10088   MatCheckPreallocated(B,2);
10089   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10090   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10091   PetscValidPointer(C,3);
10092   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);
10093   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10094   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10095   MatCheckPreallocated(A,1);
10096 
10097   fA = A->ops->transposematmult;
10098   fB = B->ops->transposematmult;
10099   if (fB==fA) {
10100     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10101     transposematmult = fA;
10102   } else {
10103     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10104     char multname[256];
10105     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10106     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10107     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10108     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10109     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10110     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10111     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);
10112   }
10113   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10114   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10115   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10116   PetscFunctionReturn(0);
10117 }
10118 
10119 /*@
10120    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10121 
10122    Neighbor-wise Collective on Mat
10123 
10124    Input Parameters:
10125 +  A - the left matrix
10126 .  B - the middle matrix
10127 .  C - the right matrix
10128 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10129 -  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
10130           if the result is a dense matrix this is irrelevent
10131 
10132    Output Parameters:
10133 .  D - the product matrix
10134 
10135    Notes:
10136    Unless scall is MAT_REUSE_MATRIX D will be created.
10137 
10138    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10139 
10140    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10141    actually needed.
10142 
10143    If you have many matrices with the same non-zero structure to multiply, you
10144    should use MAT_REUSE_MATRIX in all calls but the first or
10145 
10146    Level: intermediate
10147 
10148 .seealso: MatMatMult, MatPtAP()
10149 @*/
10150 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10151 {
10152   PetscErrorCode ierr;
10153   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10154   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10155   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10156   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10157 
10158   PetscFunctionBegin;
10159   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10160   PetscValidType(A,1);
10161   MatCheckPreallocated(A,1);
10162   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10163   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10164   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10165   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10166   PetscValidType(B,2);
10167   MatCheckPreallocated(B,2);
10168   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10169   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10170   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10171   PetscValidPointer(C,3);
10172   MatCheckPreallocated(C,3);
10173   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10174   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10175   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);
10176   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);
10177   if (scall == MAT_REUSE_MATRIX) {
10178     PetscValidPointer(*D,6);
10179     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10180     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10181     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10182     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10183     PetscFunctionReturn(0);
10184   }
10185   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10186   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10187 
10188   fA = A->ops->matmatmult;
10189   fB = B->ops->matmatmult;
10190   fC = C->ops->matmatmult;
10191   if (fA == fB && fA == fC) {
10192     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10193     mult = fA;
10194   } else {
10195     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10196     char multname[256];
10197     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10198     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10199     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10200     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10201     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10202     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10203     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10204     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10205     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);
10206   }
10207   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10208   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10209   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10210   PetscFunctionReturn(0);
10211 }
10212 
10213 /*@
10214    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10215 
10216    Collective on Mat
10217 
10218    Input Parameters:
10219 +  mat - the matrix
10220 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10221 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10222 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10223 
10224    Output Parameter:
10225 .  matredundant - redundant matrix
10226 
10227    Notes:
10228    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10229    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10230 
10231    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10232    calling it.
10233 
10234    Level: advanced
10235 
10236    Concepts: subcommunicator
10237    Concepts: duplicate matrix
10238 
10239 .seealso: MatDestroy()
10240 @*/
10241 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10242 {
10243   PetscErrorCode ierr;
10244   MPI_Comm       comm;
10245   PetscMPIInt    size;
10246   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10247   Mat_Redundant  *redund=NULL;
10248   PetscSubcomm   psubcomm=NULL;
10249   MPI_Comm       subcomm_in=subcomm;
10250   Mat            *matseq;
10251   IS             isrow,iscol;
10252   PetscBool      newsubcomm=PETSC_FALSE;
10253 
10254   PetscFunctionBegin;
10255   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10256   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10257     PetscValidPointer(*matredundant,5);
10258     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10259   }
10260 
10261   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10262   if (size == 1 || nsubcomm == 1) {
10263     if (reuse == MAT_INITIAL_MATRIX) {
10264       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10265     } else {
10266       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");
10267       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10268     }
10269     PetscFunctionReturn(0);
10270   }
10271 
10272   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10273   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10274   MatCheckPreallocated(mat,1);
10275 
10276   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10277   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10278     /* create psubcomm, then get subcomm */
10279     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10280     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10281     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10282 
10283     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10284     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10285     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10286     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10287     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10288     newsubcomm = PETSC_TRUE;
10289     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10290   }
10291 
10292   /* get isrow, iscol and a local sequential matrix matseq[0] */
10293   if (reuse == MAT_INITIAL_MATRIX) {
10294     mloc_sub = PETSC_DECIDE;
10295     nloc_sub = PETSC_DECIDE;
10296     if (bs < 1) {
10297       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10298       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10299     } else {
10300       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10301       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10302     }
10303     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10304     rstart = rend - mloc_sub;
10305     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10306     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10307   } else { /* reuse == MAT_REUSE_MATRIX */
10308     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");
10309     /* retrieve subcomm */
10310     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10311     redund = (*matredundant)->redundant;
10312     isrow  = redund->isrow;
10313     iscol  = redund->iscol;
10314     matseq = redund->matseq;
10315   }
10316   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10317 
10318   /* get matredundant over subcomm */
10319   if (reuse == MAT_INITIAL_MATRIX) {
10320     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10321 
10322     /* create a supporting struct and attach it to C for reuse */
10323     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10324     (*matredundant)->redundant = redund;
10325     redund->isrow              = isrow;
10326     redund->iscol              = iscol;
10327     redund->matseq             = matseq;
10328     if (newsubcomm) {
10329       redund->subcomm          = subcomm;
10330     } else {
10331       redund->subcomm          = MPI_COMM_NULL;
10332     }
10333   } else {
10334     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10335   }
10336   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10337   PetscFunctionReturn(0);
10338 }
10339 
10340 /*@C
10341    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10342    a given 'mat' object. Each submatrix can span multiple procs.
10343 
10344    Collective on Mat
10345 
10346    Input Parameters:
10347 +  mat - the matrix
10348 .  subcomm - the subcommunicator obtained by com_split(comm)
10349 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10350 
10351    Output Parameter:
10352 .  subMat - 'parallel submatrices each spans a given subcomm
10353 
10354   Notes:
10355   The submatrix partition across processors is dictated by 'subComm' a
10356   communicator obtained by com_split(comm). The comm_split
10357   is not restriced to be grouped with consecutive original ranks.
10358 
10359   Due the comm_split() usage, the parallel layout of the submatrices
10360   map directly to the layout of the original matrix [wrt the local
10361   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10362   into the 'DiagonalMat' of the subMat, hence it is used directly from
10363   the subMat. However the offDiagMat looses some columns - and this is
10364   reconstructed with MatSetValues()
10365 
10366   Level: advanced
10367 
10368   Concepts: subcommunicator
10369   Concepts: submatrices
10370 
10371 .seealso: MatCreateSubMatrices()
10372 @*/
10373 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10374 {
10375   PetscErrorCode ierr;
10376   PetscMPIInt    commsize,subCommSize;
10377 
10378   PetscFunctionBegin;
10379   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10380   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10381   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10382 
10383   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");
10384   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10385   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10386   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10387   PetscFunctionReturn(0);
10388 }
10389 
10390 /*@
10391    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10392 
10393    Not Collective
10394 
10395    Input Arguments:
10396    mat - matrix to extract local submatrix from
10397    isrow - local row indices for submatrix
10398    iscol - local column indices for submatrix
10399 
10400    Output Arguments:
10401    submat - the submatrix
10402 
10403    Level: intermediate
10404 
10405    Notes:
10406    The submat should be returned with MatRestoreLocalSubMatrix().
10407 
10408    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10409    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10410 
10411    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10412    MatSetValuesBlockedLocal() will also be implemented.
10413 
10414    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10415    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10416 
10417 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10418 @*/
10419 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10420 {
10421   PetscErrorCode ierr;
10422 
10423   PetscFunctionBegin;
10424   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10425   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10426   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10427   PetscCheckSameComm(isrow,2,iscol,3);
10428   PetscValidPointer(submat,4);
10429   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10430 
10431   if (mat->ops->getlocalsubmatrix) {
10432     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10433   } else {
10434     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10435   }
10436   PetscFunctionReturn(0);
10437 }
10438 
10439 /*@
10440    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10441 
10442    Not Collective
10443 
10444    Input Arguments:
10445    mat - matrix to extract local submatrix from
10446    isrow - local row indices for submatrix
10447    iscol - local column indices for submatrix
10448    submat - the submatrix
10449 
10450    Level: intermediate
10451 
10452 .seealso: MatGetLocalSubMatrix()
10453 @*/
10454 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10455 {
10456   PetscErrorCode ierr;
10457 
10458   PetscFunctionBegin;
10459   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10460   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10461   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10462   PetscCheckSameComm(isrow,2,iscol,3);
10463   PetscValidPointer(submat,4);
10464   if (*submat) {
10465     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10466   }
10467 
10468   if (mat->ops->restorelocalsubmatrix) {
10469     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10470   } else {
10471     ierr = MatDestroy(submat);CHKERRQ(ierr);
10472   }
10473   *submat = NULL;
10474   PetscFunctionReturn(0);
10475 }
10476 
10477 /* --------------------------------------------------------*/
10478 /*@
10479    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10480 
10481    Collective on Mat
10482 
10483    Input Parameter:
10484 .  mat - the matrix
10485 
10486    Output Parameter:
10487 .  is - if any rows have zero diagonals this contains the list of them
10488 
10489    Level: developer
10490 
10491    Concepts: matrix-vector product
10492 
10493 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10494 @*/
10495 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10496 {
10497   PetscErrorCode ierr;
10498 
10499   PetscFunctionBegin;
10500   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10501   PetscValidType(mat,1);
10502   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10503   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10504 
10505   if (!mat->ops->findzerodiagonals) {
10506     Vec                diag;
10507     const PetscScalar *a;
10508     PetscInt          *rows;
10509     PetscInt           rStart, rEnd, r, nrow = 0;
10510 
10511     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10512     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10513     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10514     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10515     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10516     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10517     nrow = 0;
10518     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10519     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10520     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10521     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10522   } else {
10523     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10524   }
10525   PetscFunctionReturn(0);
10526 }
10527 
10528 /*@
10529    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10530 
10531    Collective on Mat
10532 
10533    Input Parameter:
10534 .  mat - the matrix
10535 
10536    Output Parameter:
10537 .  is - contains the list of rows with off block diagonal entries
10538 
10539    Level: developer
10540 
10541    Concepts: matrix-vector product
10542 
10543 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10544 @*/
10545 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10546 {
10547   PetscErrorCode ierr;
10548 
10549   PetscFunctionBegin;
10550   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10551   PetscValidType(mat,1);
10552   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10553   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10554 
10555   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10556   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10557   PetscFunctionReturn(0);
10558 }
10559 
10560 /*@C
10561   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10562 
10563   Collective on Mat
10564 
10565   Input Parameters:
10566 . mat - the matrix
10567 
10568   Output Parameters:
10569 . values - the block inverses in column major order (FORTRAN-like)
10570 
10571    Note:
10572    This routine is not available from Fortran.
10573 
10574   Level: advanced
10575 
10576 .seealso: MatInvertBockDiagonalMat
10577 @*/
10578 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10579 {
10580   PetscErrorCode ierr;
10581 
10582   PetscFunctionBegin;
10583   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10584   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10585   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10586   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10587   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10588   PetscFunctionReturn(0);
10589 }
10590 
10591 /*@C
10592   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10593 
10594   Collective on Mat
10595 
10596   Input Parameters:
10597 + mat - the matrix
10598 . nblocks - the number of blocks
10599 - bsizes - the size of each block
10600 
10601   Output Parameters:
10602 . values - the block inverses in column major order (FORTRAN-like)
10603 
10604    Note:
10605    This routine is not available from Fortran.
10606 
10607   Level: advanced
10608 
10609 .seealso: MatInvertBockDiagonal()
10610 @*/
10611 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10612 {
10613   PetscErrorCode ierr;
10614 
10615   PetscFunctionBegin;
10616   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10617   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10618   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10619   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10620   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10621   PetscFunctionReturn(0);
10622 }
10623 
10624 /*@
10625   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10626 
10627   Collective on Mat
10628 
10629   Input Parameters:
10630 . A - the matrix
10631 
10632   Output Parameters:
10633 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10634 
10635   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10636 
10637   Level: advanced
10638 
10639 .seealso: MatInvertBockDiagonal()
10640 @*/
10641 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10642 {
10643   PetscErrorCode     ierr;
10644   const PetscScalar *vals;
10645   PetscInt          *dnnz;
10646   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10647 
10648   PetscFunctionBegin;
10649   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10650   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10651   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10652   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10653   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10654   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10655   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10656   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10657   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10658   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10659   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10660   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10661   for (i = rstart/bs; i < rend/bs; i++) {
10662     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10663   }
10664   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10665   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10666   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10667   PetscFunctionReturn(0);
10668 }
10669 
10670 /*@C
10671     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10672     via MatTransposeColoringCreate().
10673 
10674     Collective on MatTransposeColoring
10675 
10676     Input Parameter:
10677 .   c - coloring context
10678 
10679     Level: intermediate
10680 
10681 .seealso: MatTransposeColoringCreate()
10682 @*/
10683 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10684 {
10685   PetscErrorCode       ierr;
10686   MatTransposeColoring matcolor=*c;
10687 
10688   PetscFunctionBegin;
10689   if (!matcolor) PetscFunctionReturn(0);
10690   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10691 
10692   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10693   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10694   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10695   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10696   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10697   if (matcolor->brows>0) {
10698     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10699   }
10700   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10701   PetscFunctionReturn(0);
10702 }
10703 
10704 /*@C
10705     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10706     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10707     MatTransposeColoring to sparse B.
10708 
10709     Collective on MatTransposeColoring
10710 
10711     Input Parameters:
10712 +   B - sparse matrix B
10713 .   Btdense - symbolic dense matrix B^T
10714 -   coloring - coloring context created with MatTransposeColoringCreate()
10715 
10716     Output Parameter:
10717 .   Btdense - dense matrix B^T
10718 
10719     Level: advanced
10720 
10721      Notes:
10722     These are used internally for some implementations of MatRARt()
10723 
10724 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10725 
10726 .keywords: coloring
10727 @*/
10728 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10729 {
10730   PetscErrorCode ierr;
10731 
10732   PetscFunctionBegin;
10733   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10734   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10735   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10736 
10737   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10738   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10739   PetscFunctionReturn(0);
10740 }
10741 
10742 /*@C
10743     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10744     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10745     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10746     Csp from Cden.
10747 
10748     Collective on MatTransposeColoring
10749 
10750     Input Parameters:
10751 +   coloring - coloring context created with MatTransposeColoringCreate()
10752 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10753 
10754     Output Parameter:
10755 .   Csp - sparse matrix
10756 
10757     Level: advanced
10758 
10759      Notes:
10760     These are used internally for some implementations of MatRARt()
10761 
10762 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10763 
10764 .keywords: coloring
10765 @*/
10766 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10767 {
10768   PetscErrorCode ierr;
10769 
10770   PetscFunctionBegin;
10771   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10772   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10773   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10774 
10775   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10776   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10777   PetscFunctionReturn(0);
10778 }
10779 
10780 /*@C
10781    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10782 
10783    Collective on Mat
10784 
10785    Input Parameters:
10786 +  mat - the matrix product C
10787 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10788 
10789     Output Parameter:
10790 .   color - the new coloring context
10791 
10792     Level: intermediate
10793 
10794 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10795            MatTransColoringApplyDenToSp()
10796 @*/
10797 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10798 {
10799   MatTransposeColoring c;
10800   MPI_Comm             comm;
10801   PetscErrorCode       ierr;
10802 
10803   PetscFunctionBegin;
10804   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10805   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10806   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10807 
10808   c->ctype = iscoloring->ctype;
10809   if (mat->ops->transposecoloringcreate) {
10810     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10811   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10812 
10813   *color = c;
10814   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10815   PetscFunctionReturn(0);
10816 }
10817 
10818 /*@
10819       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10820         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10821         same, otherwise it will be larger
10822 
10823      Not Collective
10824 
10825   Input Parameter:
10826 .    A  - the matrix
10827 
10828   Output Parameter:
10829 .    state - the current state
10830 
10831   Notes:
10832     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10833          different matrices
10834 
10835   Level: intermediate
10836 
10837 @*/
10838 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10839 {
10840   PetscFunctionBegin;
10841   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10842   *state = mat->nonzerostate;
10843   PetscFunctionReturn(0);
10844 }
10845 
10846 /*@
10847       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10848                  matrices from each processor
10849 
10850     Collective on MPI_Comm
10851 
10852    Input Parameters:
10853 +    comm - the communicators the parallel matrix will live on
10854 .    seqmat - the input sequential matrices
10855 .    n - number of local columns (or PETSC_DECIDE)
10856 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10857 
10858    Output Parameter:
10859 .    mpimat - the parallel matrix generated
10860 
10861     Level: advanced
10862 
10863    Notes:
10864     The number of columns of the matrix in EACH processor MUST be the same.
10865 
10866 @*/
10867 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10868 {
10869   PetscErrorCode ierr;
10870 
10871   PetscFunctionBegin;
10872   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10873   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");
10874 
10875   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10876   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10877   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10878   PetscFunctionReturn(0);
10879 }
10880 
10881 /*@
10882      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10883                  ranks' ownership ranges.
10884 
10885     Collective on A
10886 
10887    Input Parameters:
10888 +    A   - the matrix to create subdomains from
10889 -    N   - requested number of subdomains
10890 
10891 
10892    Output Parameters:
10893 +    n   - number of subdomains resulting on this rank
10894 -    iss - IS list with indices of subdomains on this rank
10895 
10896     Level: advanced
10897 
10898     Notes:
10899     number of subdomains must be smaller than the communicator size
10900 @*/
10901 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10902 {
10903   MPI_Comm        comm,subcomm;
10904   PetscMPIInt     size,rank,color;
10905   PetscInt        rstart,rend,k;
10906   PetscErrorCode  ierr;
10907 
10908   PetscFunctionBegin;
10909   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10910   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10911   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10912   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);
10913   *n = 1;
10914   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10915   color = rank/k;
10916   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10917   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10918   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10919   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10920   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10921   PetscFunctionReturn(0);
10922 }
10923 
10924 /*@
10925    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10926 
10927    If the interpolation and restriction operators are the same, uses MatPtAP.
10928    If they are not the same, use MatMatMatMult.
10929 
10930    Once the coarse grid problem is constructed, correct for interpolation operators
10931    that are not of full rank, which can legitimately happen in the case of non-nested
10932    geometric multigrid.
10933 
10934    Input Parameters:
10935 +  restrct - restriction operator
10936 .  dA - fine grid matrix
10937 .  interpolate - interpolation operator
10938 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10939 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10940 
10941    Output Parameters:
10942 .  A - the Galerkin coarse matrix
10943 
10944    Options Database Key:
10945 .  -pc_mg_galerkin <both,pmat,mat,none>
10946 
10947    Level: developer
10948 
10949 .keywords: MG, multigrid, Galerkin
10950 
10951 .seealso: MatPtAP(), MatMatMatMult()
10952 @*/
10953 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10954 {
10955   PetscErrorCode ierr;
10956   IS             zerorows;
10957   Vec            diag;
10958 
10959   PetscFunctionBegin;
10960   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10961   /* Construct the coarse grid matrix */
10962   if (interpolate == restrct) {
10963     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10964   } else {
10965     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10966   }
10967 
10968   /* If the interpolation matrix is not of full rank, A will have zero rows.
10969      This can legitimately happen in the case of non-nested geometric multigrid.
10970      In that event, we set the rows of the matrix to the rows of the identity,
10971      ignoring the equations (as the RHS will also be zero). */
10972 
10973   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10974 
10975   if (zerorows != NULL) { /* if there are any zero rows */
10976     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10977     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10978     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10979     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10980     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10981     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10982   }
10983   PetscFunctionReturn(0);
10984 }
10985 
10986 /*@C
10987     MatSetOperation - Allows user to set a matrix operation for any matrix type
10988 
10989    Logically Collective on Mat
10990 
10991     Input Parameters:
10992 +   mat - the matrix
10993 .   op - the name of the operation
10994 -   f - the function that provides the operation
10995 
10996    Level: developer
10997 
10998     Usage:
10999 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
11000 $      ierr = MatCreateXXX(comm,...&A);
11001 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
11002 
11003     Notes:
11004     See the file include/petscmat.h for a complete list of matrix
11005     operations, which all have the form MATOP_<OPERATION>, where
11006     <OPERATION> is the name (in all capital letters) of the
11007     user interface routine (e.g., MatMult() -> MATOP_MULT).
11008 
11009     All user-provided functions (except for MATOP_DESTROY) should have the same calling
11010     sequence as the usual matrix interface routines, since they
11011     are intended to be accessed via the usual matrix interface
11012     routines, e.g.,
11013 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
11014 
11015     In particular each function MUST return an error code of 0 on success and
11016     nonzero on failure.
11017 
11018     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
11019 
11020 .keywords: matrix, set, operation
11021 
11022 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
11023 @*/
11024 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
11025 {
11026   PetscFunctionBegin;
11027   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11028   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
11029     mat->ops->viewnative = mat->ops->view;
11030   }
11031   (((void(**)(void))mat->ops)[op]) = f;
11032   PetscFunctionReturn(0);
11033 }
11034 
11035 /*@C
11036     MatGetOperation - Gets a matrix operation for any matrix type.
11037 
11038     Not Collective
11039 
11040     Input Parameters:
11041 +   mat - the matrix
11042 -   op - the name of the operation
11043 
11044     Output Parameter:
11045 .   f - the function that provides the operation
11046 
11047     Level: developer
11048 
11049     Usage:
11050 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11051 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11052 
11053     Notes:
11054     See the file include/petscmat.h for a complete list of matrix
11055     operations, which all have the form MATOP_<OPERATION>, where
11056     <OPERATION> is the name (in all capital letters) of the
11057     user interface routine (e.g., MatMult() -> MATOP_MULT).
11058 
11059     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11060 
11061 .keywords: matrix, get, operation
11062 
11063 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11064 @*/
11065 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11066 {
11067   PetscFunctionBegin;
11068   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11069   *f = (((void (**)(void))mat->ops)[op]);
11070   PetscFunctionReturn(0);
11071 }
11072 
11073 /*@
11074     MatHasOperation - Determines whether the given matrix supports the particular
11075     operation.
11076 
11077    Not Collective
11078 
11079    Input Parameters:
11080 +  mat - the matrix
11081 -  op - the operation, for example, MATOP_GET_DIAGONAL
11082 
11083    Output Parameter:
11084 .  has - either PETSC_TRUE or PETSC_FALSE
11085 
11086    Level: advanced
11087 
11088    Notes:
11089    See the file include/petscmat.h for a complete list of matrix
11090    operations, which all have the form MATOP_<OPERATION>, where
11091    <OPERATION> is the name (in all capital letters) of the
11092    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11093 
11094 .keywords: matrix, has, operation
11095 
11096 .seealso: MatCreateShell()
11097 @*/
11098 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11099 {
11100   PetscErrorCode ierr;
11101 
11102   PetscFunctionBegin;
11103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11104   PetscValidType(mat,1);
11105   PetscValidPointer(has,3);
11106   if (mat->ops->hasoperation) {
11107     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11108   } else {
11109     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11110     else {
11111       *has = PETSC_FALSE;
11112       if (op == MATOP_CREATE_SUBMATRIX) {
11113         PetscMPIInt size;
11114 
11115         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11116         if (size == 1) {
11117           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11118         }
11119       }
11120     }
11121   }
11122   PetscFunctionReturn(0);
11123 }
11124 
11125 /*@
11126     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11127     of the matrix are congruent
11128 
11129    Collective on mat
11130 
11131    Input Parameters:
11132 .  mat - the matrix
11133 
11134    Output Parameter:
11135 .  cong - either PETSC_TRUE or PETSC_FALSE
11136 
11137    Level: beginner
11138 
11139    Notes:
11140 
11141 .keywords: matrix, has
11142 
11143 .seealso: MatCreate(), MatSetSizes()
11144 @*/
11145 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11146 {
11147   PetscErrorCode ierr;
11148 
11149   PetscFunctionBegin;
11150   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11151   PetscValidType(mat,1);
11152   PetscValidPointer(cong,2);
11153   if (!mat->rmap || !mat->cmap) {
11154     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11155     PetscFunctionReturn(0);
11156   }
11157   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11158     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11159     if (*cong) mat->congruentlayouts = 1;
11160     else       mat->congruentlayouts = 0;
11161   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11162   PetscFunctionReturn(0);
11163 }
11164 
11165 /*@
11166     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11167     e.g., matrx product of MatPtAP.
11168 
11169    Collective on mat
11170 
11171    Input Parameters:
11172 .  mat - the matrix
11173 
11174    Output Parameter:
11175 .  mat - the matrix with intermediate data structures released
11176 
11177    Level: advanced
11178 
11179    Notes:
11180 
11181 .keywords: matrix
11182 
11183 .seealso: MatPtAP(), MatMatMult()
11184 @*/
11185 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11186 {
11187   PetscErrorCode ierr;
11188 
11189   PetscFunctionBegin;
11190   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11191   PetscValidType(mat,1);
11192   if (mat->ops->freeintermediatedatastructures) {
11193     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11194   }
11195   PetscFunctionReturn(0);
11196 }
11197