xref: /petsc/src/mat/interface/matrix.c (revision 0e53113d19f472e664897621ea8792cb0364541f)
1 
2 /*
3    This is where the abstract matrix operations are defined
4 */
5 
6 #include <petsc/private/matimpl.h>        /*I "petscmat.h" I*/
7 #include <petsc/private/isimpl.h>
8 #include <petsc/private/vecimpl.h>
9 
10 /* Logging support */
11 PetscClassId MAT_CLASSID;
12 PetscClassId MAT_COLORING_CLASSID;
13 PetscClassId MAT_FDCOLORING_CLASSID;
14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
15 
16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve;
18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24 PetscLogEvent MAT_TransposeColoringCreate;
25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34 PetscLogEvent MAT_GetMultiProcBlock;
35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch;
36 PetscLogEvent MAT_ViennaCLCopyToGPU;
37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
39 
40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
41 
42 /*@
43    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
44 
45    Logically Collective on Mat
46 
47    Input Parameters:
48 +  x  - the matrix
49 -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50           it will create one internally.
51 
52    Output Parameter:
53 .  x  - the matrix
54 
55    Example of Usage:
56 .vb
57      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58      MatSetRandom(x,rctx);
59      PetscRandomDestroy(rctx);
60 .ve
61 
62    Level: intermediate
63 
64    Concepts: matrix^setting to random
65    Concepts: random^matrix
66 
67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68 @*/
69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70 {
71   PetscErrorCode ierr;
72   PetscRandom    randObj = NULL;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
76   if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2);
77   PetscValidType(x,1);
78 
79   if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name);
80 
81   if (!rctx) {
82     MPI_Comm comm;
83     ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr);
84     ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr);
85     ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr);
86     rctx = randObj;
87   }
88 
89   ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
90   ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr);
91   ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr);
92 
93   ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94   ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
95   ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr);
96   PetscFunctionReturn(0);
97 }
98 
99 /*@
100    MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
101 
102    Logically Collective on Mat
103 
104    Input Parameters:
105 .  mat - the factored matrix
106 
107    Output Parameter:
108 +  pivot - the pivot value computed
109 -  row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
110          the share the matrix
111 
112    Level: advanced
113 
114    Notes:
115     This routine does not work for factorizations done with external packages.
116    This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
117 
118    This can be called on non-factored matrices that come from, for example, matrices used in SOR.
119 
120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
121 @*/
122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
123 {
124   PetscFunctionBegin;
125   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
126   *pivot = mat->factorerror_zeropivot_value;
127   *row   = mat->factorerror_zeropivot_row;
128   PetscFunctionReturn(0);
129 }
130 
131 /*@
132    MatFactorGetError - gets the error code from a factorization
133 
134    Logically Collective on Mat
135 
136    Input Parameters:
137 .  mat - the factored matrix
138 
139    Output Parameter:
140 .  err  - the error code
141 
142    Level: advanced
143 
144    Notes:
145     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
146 
147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
148 @*/
149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
150 {
151   PetscFunctionBegin;
152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
153   *err = mat->factorerrortype;
154   PetscFunctionReturn(0);
155 }
156 
157 /*@
158    MatFactorClearError - clears the error code in a factorization
159 
160    Logically Collective on Mat
161 
162    Input Parameter:
163 .  mat - the factored matrix
164 
165    Level: developer
166 
167    Notes:
168     This can be called on non-factored matrices that come from, for example, matrices used in SOR.
169 
170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
171 @*/
172 PetscErrorCode MatFactorClearError(Mat mat)
173 {
174   PetscFunctionBegin;
175   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
176   mat->factorerrortype             = MAT_FACTOR_NOERROR;
177   mat->factorerror_zeropivot_value = 0.0;
178   mat->factorerror_zeropivot_row   = 0;
179   PetscFunctionReturn(0);
180 }
181 
182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero)
183 {
184   PetscErrorCode    ierr;
185   Vec               r,l;
186   const PetscScalar *al;
187   PetscInt          i,nz,gnz,N,n;
188 
189   PetscFunctionBegin;
190   ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr);
191   if (!cols) { /* nonzero rows */
192     ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr);
193     ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr);
194     ierr = VecSet(l,0.0);CHKERRQ(ierr);
195     ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
196     ierr = MatMult(mat,r,l);CHKERRQ(ierr);
197     ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr);
198   } else { /* nonzero columns */
199     ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
200     ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr);
201     ierr = VecSet(r,0.0);CHKERRQ(ierr);
202     ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
203     ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr);
204     ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr);
205   }
206   if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; }
207   else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; }
208   ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
209   if (gnz != N) {
210     PetscInt *nzr;
211     ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr);
212     if (nz) {
213       if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; }
214       else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; }
215     }
216     ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr);
217   } else *nonzero = NULL;
218   if (!cols) { /* nonzero rows */
219     ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr);
220   } else {
221     ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr);
222   }
223   ierr = VecDestroy(&l);CHKERRQ(ierr);
224   ierr = VecDestroy(&r);CHKERRQ(ierr);
225   PetscFunctionReturn(0);
226 }
227 
228 /*@
229       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
230 
231   Input Parameter:
232 .    A  - the matrix
233 
234   Output Parameter:
235 .    keptrows - the rows that are not completely zero
236 
237   Notes:
238     keptrows is set to NULL if all rows are nonzero.
239 
240   Level: intermediate
241 
242  @*/
243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
244 {
245   PetscErrorCode ierr;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
249   PetscValidType(mat,1);
250   PetscValidPointer(keptrows,2);
251   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
252   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
253   if (!mat->ops->findnonzerorows) {
254     ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr);
255   } else {
256     ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr);
257   }
258   PetscFunctionReturn(0);
259 }
260 
261 /*@
262       MatFindZeroRows - Locate all rows that are completely zero in the matrix
263 
264   Input Parameter:
265 .    A  - the matrix
266 
267   Output Parameter:
268 .    zerorows - the rows that are completely zero
269 
270   Notes:
271     zerorows is set to NULL if no rows are zero.
272 
273   Level: intermediate
274 
275  @*/
276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
277 {
278   PetscErrorCode ierr;
279   IS keptrows;
280   PetscInt m, n;
281 
282   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
283   PetscValidType(mat,1);
284 
285   ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr);
286   /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
287      In keeping with this convention, we set zerorows to NULL if there are no zero
288      rows. */
289   if (keptrows == NULL) {
290     *zerorows = NULL;
291   } else {
292     ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr);
293     ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr);
294     ierr = ISDestroy(&keptrows);CHKERRQ(ierr);
295   }
296   PetscFunctionReturn(0);
297 }
298 
299 /*@
300    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
301 
302    Not Collective
303 
304    Input Parameters:
305 .   A - the matrix
306 
307    Output Parameters:
308 .   a - the diagonal part (which is a SEQUENTIAL matrix)
309 
310    Notes:
311     see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
312           Use caution, as the reference count on the returned matrix is not incremented and it is used as
313 	  part of the containing MPI Mat's normal operation.
314 
315    Level: advanced
316 
317 @*/
318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
319 {
320   PetscErrorCode ierr;
321 
322   PetscFunctionBegin;
323   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
324   PetscValidType(A,1);
325   PetscValidPointer(a,3);
326   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
327   if (!A->ops->getdiagonalblock) {
328     PetscMPIInt size;
329     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr);
330     if (size == 1) {
331       *a = A;
332       PetscFunctionReturn(0);
333     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
334   }
335   ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr);
336   PetscFunctionReturn(0);
337 }
338 
339 /*@
340    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
341 
342    Collective on Mat
343 
344    Input Parameters:
345 .  mat - the matrix
346 
347    Output Parameter:
348 .   trace - the sum of the diagonal entries
349 
350    Level: advanced
351 
352 @*/
353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
354 {
355   PetscErrorCode ierr;
356   Vec            diag;
357 
358   PetscFunctionBegin;
359   ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr);
360   ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr);
361   ierr = VecSum(diag,trace);CHKERRQ(ierr);
362   ierr = VecDestroy(&diag);CHKERRQ(ierr);
363   PetscFunctionReturn(0);
364 }
365 
366 /*@
367    MatRealPart - Zeros out the imaginary part of the matrix
368 
369    Logically Collective on Mat
370 
371    Input Parameters:
372 .  mat - the matrix
373 
374    Level: advanced
375 
376 
377 .seealso: MatImaginaryPart()
378 @*/
379 PetscErrorCode MatRealPart(Mat mat)
380 {
381   PetscErrorCode ierr;
382 
383   PetscFunctionBegin;
384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
385   PetscValidType(mat,1);
386   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
387   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
388   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
389   MatCheckPreallocated(mat,1);
390   ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr);
391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
392   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
393     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
394   }
395 #endif
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
401 
402    Collective on Mat
403 
404    Input Parameter:
405 .  mat - the matrix
406 
407    Output Parameters:
408 +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
409 -   ghosts - the global indices of the ghost points
410 
411    Notes:
412     the nghosts and ghosts are suitable to pass into VecCreateGhost()
413 
414    Level: advanced
415 
416 @*/
417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423   PetscValidType(mat,1);
424   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
426   if (!mat->ops->getghosts) {
427     if (nghosts) *nghosts = 0;
428     if (ghosts) *ghosts = 0;
429   } else {
430     ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr);
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 
436 /*@
437    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
438 
439    Logically Collective on Mat
440 
441    Input Parameters:
442 .  mat - the matrix
443 
444    Level: advanced
445 
446 
447 .seealso: MatRealPart()
448 @*/
449 PetscErrorCode MatImaginaryPart(Mat mat)
450 {
451   PetscErrorCode ierr;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
455   PetscValidType(mat,1);
456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
458   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
459   MatCheckPreallocated(mat,1);
460   ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr);
461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
462   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
463     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
464   }
465 #endif
466   PetscFunctionReturn(0);
467 }
468 
469 /*@
470    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
471 
472    Not Collective
473 
474    Input Parameter:
475 .  mat - the matrix
476 
477    Output Parameters:
478 +  missing - is any diagonal missing
479 -  dd - first diagonal entry that is missing (optional) on this process
480 
481    Level: advanced
482 
483 
484 .seealso: MatRealPart()
485 @*/
486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
487 {
488   PetscErrorCode ierr;
489 
490   PetscFunctionBegin;
491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
492   PetscValidType(mat,1);
493   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
494   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
495   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
496   ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 /*@C
501    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
502    for each row that you get to ensure that your application does
503    not bleed memory.
504 
505    Not Collective
506 
507    Input Parameters:
508 +  mat - the matrix
509 -  row - the row to get
510 
511    Output Parameters:
512 +  ncols -  if not NULL, the number of nonzeros in the row
513 .  cols - if not NULL, the column numbers
514 -  vals - if not NULL, the values
515 
516    Notes:
517    This routine is provided for people who need to have direct access
518    to the structure of a matrix.  We hope that we provide enough
519    high-level matrix routines that few users will need it.
520 
521    MatGetRow() always returns 0-based column indices, regardless of
522    whether the internal representation is 0-based (default) or 1-based.
523 
524    For better efficiency, set cols and/or vals to NULL if you do
525    not wish to extract these quantities.
526 
527    The user can only examine the values extracted with MatGetRow();
528    the values cannot be altered.  To change the matrix entries, one
529    must use MatSetValues().
530 
531    You can only have one call to MatGetRow() outstanding for a particular
532    matrix at a time, per processor. MatGetRow() can only obtain rows
533    associated with the given processor, it cannot get rows from the
534    other processors; for that we suggest using MatCreateSubMatrices(), then
535    MatGetRow() on the submatrix. The row index passed to MatGetRow()
536    is in the global number of rows.
537 
538    Fortran Notes:
539    The calling sequence from Fortran is
540 .vb
541    MatGetRow(matrix,row,ncols,cols,values,ierr)
542          Mat     matrix (input)
543          integer row    (input)
544          integer ncols  (output)
545          integer cols(maxcols) (output)
546          double precision (or double complex) values(maxcols) output
547 .ve
548    where maxcols >= maximum nonzeros in any row of the matrix.
549 
550 
551    Caution:
552    Do not try to change the contents of the output arrays (cols and vals).
553    In some cases, this may corrupt the matrix.
554 
555    Level: advanced
556 
557    Concepts: matrices^row access
558 
559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
560 @*/
561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
562 {
563   PetscErrorCode ierr;
564   PetscInt       incols;
565 
566   PetscFunctionBegin;
567   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
568   PetscValidType(mat,1);
569   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
570   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
571   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
572   MatCheckPreallocated(mat,1);
573   ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
574   ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr);
575   if (ncols) *ncols = incols;
576   ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr);
577   PetscFunctionReturn(0);
578 }
579 
580 /*@
581    MatConjugate - replaces the matrix values with their complex conjugates
582 
583    Logically Collective on Mat
584 
585    Input Parameters:
586 .  mat - the matrix
587 
588    Level: advanced
589 
590 .seealso:  VecConjugate()
591 @*/
592 PetscErrorCode MatConjugate(Mat mat)
593 {
594 #if defined(PETSC_USE_COMPLEX)
595   PetscErrorCode ierr;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
599   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
600   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
601   ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr);
602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
603   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
604     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
605   }
606 #endif
607   PetscFunctionReturn(0);
608 #else
609   return 0;
610 #endif
611 }
612 
613 /*@C
614    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
615 
616    Not Collective
617 
618    Input Parameters:
619 +  mat - the matrix
620 .  row - the row to get
621 .  ncols, cols - the number of nonzeros and their columns
622 -  vals - if nonzero the column values
623 
624    Notes:
625    This routine should be called after you have finished examining the entries.
626 
627    This routine zeros out ncols, cols, and vals. This is to prevent accidental
628    us of the array after it has been restored. If you pass NULL, it will
629    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.
630 
631    Fortran Notes:
632    The calling sequence from Fortran is
633 .vb
634    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
635       Mat     matrix (input)
636       integer row    (input)
637       integer ncols  (output)
638       integer cols(maxcols) (output)
639       double precision (or double complex) values(maxcols) output
640 .ve
641    Where maxcols >= maximum nonzeros in any row of the matrix.
642 
643    In Fortran MatRestoreRow() MUST be called after MatGetRow()
644    before another call to MatGetRow() can be made.
645 
646    Level: advanced
647 
648 .seealso:  MatGetRow()
649 @*/
650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
651 {
652   PetscErrorCode ierr;
653 
654   PetscFunctionBegin;
655   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
656   if (ncols) PetscValidIntPointer(ncols,3);
657   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
658   if (!mat->ops->restorerow) PetscFunctionReturn(0);
659   ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr);
660   if (ncols) *ncols = 0;
661   if (cols)  *cols = NULL;
662   if (vals)  *vals = NULL;
663   PetscFunctionReturn(0);
664 }
665 
666 /*@
667    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
668    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
669 
670    Not Collective
671 
672    Input Parameters:
673 +  mat - the matrix
674 
675    Notes:
676    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.
677 
678    Level: advanced
679 
680    Concepts: matrices^row access
681 
682 .seealso: MatRestoreRowRowUpperTriangular()
683 @*/
684 PetscErrorCode MatGetRowUpperTriangular(Mat mat)
685 {
686   PetscErrorCode ierr;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
690   PetscValidType(mat,1);
691   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
692   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
693   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
694   MatCheckPreallocated(mat,1);
695   ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr);
696   PetscFunctionReturn(0);
697 }
698 
699 /*@
700    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
701 
702    Not Collective
703 
704    Input Parameters:
705 +  mat - the matrix
706 
707    Notes:
708    This routine should be called after you have finished MatGetRow/MatRestoreRow().
709 
710 
711    Level: advanced
712 
713 .seealso:  MatGetRowUpperTriangular()
714 @*/
715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
716 {
717   PetscErrorCode ierr;
718 
719   PetscFunctionBegin;
720   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
721   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
722   if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0);
723   ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr);
724   PetscFunctionReturn(0);
725 }
726 
727 /*@C
728    MatSetOptionsPrefix - Sets the prefix used for searching for all
729    Mat options in the database.
730 
731    Logically Collective on Mat
732 
733    Input Parameter:
734 +  A - the Mat context
735 -  prefix - the prefix to prepend to all option names
736 
737    Notes:
738    A hyphen (-) must NOT be given at the beginning of the prefix name.
739    The first character of all runtime options is AUTOMATICALLY the hyphen.
740 
741    Level: advanced
742 
743 .keywords: Mat, set, options, prefix, database
744 
745 .seealso: MatSetFromOptions()
746 @*/
747 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
748 {
749   PetscErrorCode ierr;
750 
751   PetscFunctionBegin;
752   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
753   ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
754   PetscFunctionReturn(0);
755 }
756 
757 /*@C
758    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
759    Mat options in the database.
760 
761    Logically Collective on Mat
762 
763    Input Parameters:
764 +  A - the Mat context
765 -  prefix - the prefix to prepend to all option names
766 
767    Notes:
768    A hyphen (-) must NOT be given at the beginning of the prefix name.
769    The first character of all runtime options is AUTOMATICALLY the hyphen.
770 
771    Level: advanced
772 
773 .keywords: Mat, append, options, prefix, database
774 
775 .seealso: MatGetOptionsPrefix()
776 @*/
777 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
778 {
779   PetscErrorCode ierr;
780 
781   PetscFunctionBegin;
782   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
783   ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
784   PetscFunctionReturn(0);
785 }
786 
787 /*@C
788    MatGetOptionsPrefix - Sets the prefix used for searching for all
789    Mat options in the database.
790 
791    Not Collective
792 
793    Input Parameter:
794 .  A - the Mat context
795 
796    Output Parameter:
797 .  prefix - pointer to the prefix string used
798 
799    Notes:
800     On the fortran side, the user should pass in a string 'prefix' of
801    sufficient length to hold the prefix.
802 
803    Level: advanced
804 
805 .keywords: Mat, get, options, prefix, database
806 
807 .seealso: MatAppendOptionsPrefix()
808 @*/
809 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
810 {
811   PetscErrorCode ierr;
812 
813   PetscFunctionBegin;
814   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
815   ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr);
816   PetscFunctionReturn(0);
817 }
818 
819 /*@
820    MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users.
821 
822    Collective on Mat
823 
824    Input Parameters:
825 .  A - the Mat context
826 
827    Notes:
828    The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory.
829    Currently support MPIAIJ and SEQAIJ.
830 
831    Level: beginner
832 
833 .keywords: Mat, ResetPreallocation
834 
835 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation()
836 @*/
837 PetscErrorCode MatResetPreallocation(Mat A)
838 {
839   PetscErrorCode ierr;
840 
841   PetscFunctionBegin;
842   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
843   PetscValidType(A,1);
844   ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr);
845   PetscFunctionReturn(0);
846 }
847 
848 
849 /*@
850    MatSetUp - Sets up the internal matrix data structures for the later use.
851 
852    Collective on Mat
853 
854    Input Parameters:
855 .  A - the Mat context
856 
857    Notes:
858    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
859 
860    If a suitable preallocation routine is used, this function does not need to be called.
861 
862    See the Performance chapter of the PETSc users manual for how to preallocate matrices
863 
864    Level: beginner
865 
866 .keywords: Mat, setup
867 
868 .seealso: MatCreate(), MatDestroy()
869 @*/
870 PetscErrorCode MatSetUp(Mat A)
871 {
872   PetscMPIInt    size;
873   PetscErrorCode ierr;
874 
875   PetscFunctionBegin;
876   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
877   if (!((PetscObject)A)->type_name) {
878     ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr);
879     if (size == 1) {
880       ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr);
881     } else {
882       ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr);
883     }
884   }
885   if (!A->preallocated && A->ops->setup) {
886     ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
887     ierr = (*A->ops->setup)(A);CHKERRQ(ierr);
888   }
889   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
890   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
891   A->preallocated = PETSC_TRUE;
892   PetscFunctionReturn(0);
893 }
894 
895 #if defined(PETSC_HAVE_SAWS)
896 #include <petscviewersaws.h>
897 #endif
898 /*@C
899    MatView - Visualizes a matrix object.
900 
901    Collective on Mat
902 
903    Input Parameters:
904 +  mat - the matrix
905 -  viewer - visualization context
906 
907   Notes:
908   The available visualization contexts include
909 +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
910 .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
911 .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
912 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
913 
914    The user can open alternative visualization contexts with
915 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
916 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
917          specified file; corresponding input uses MatLoad()
918 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
919          an X window display
920 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
921          Currently only the sequential dense and AIJ
922          matrix types support the Socket viewer.
923 
924    The user can call PetscViewerPushFormat() to specify the output
925    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
926    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
927 +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
928 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
929 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
930 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
931          format common among all matrix types
932 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
933          format (which is in many cases the same as the default)
934 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
935          size and structure (not the matrix entries)
936 -    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
937          the matrix structure
938 
939    Options Database Keys:
940 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
941 .  -mat_view ::ascii_info_detail - Prints more detailed info
942 .  -mat_view - Prints matrix in ASCII format
943 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
944 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
945 .  -display <name> - Sets display name (default is host)
946 .  -draw_pause <sec> - Sets number of seconds to pause after display
947 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details)
948 .  -viewer_socket_machine <machine> -
949 .  -viewer_socket_port <port> -
950 .  -mat_view binary - save matrix to file in binary format
951 -  -viewer_binary_filename <name> -
952    Level: beginner
953 
954    Notes:
955     The ASCII viewers are only recommended for small matrices on at most a moderate number of processes,
956     the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format.
957 
958     See the manual page for MatLoad() for the exact format of the binary file when the binary
959       viewer is used.
960 
961       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
962       viewer is used.
963 
964       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure,
965       and then use the following mouse functions.
966 + left mouse: zoom in
967 . middle mouse: zoom out
968 - right mouse: continue with the simulation
969 
970    Concepts: matrices^viewing
971    Concepts: matrices^plotting
972    Concepts: matrices^printing
973 
974 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
975           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
976 @*/
977 PetscErrorCode MatView(Mat mat,PetscViewer viewer)
978 {
979   PetscErrorCode    ierr;
980   PetscInt          rows,cols,rbs,cbs;
981   PetscBool         iascii,ibinary;
982   PetscViewerFormat format;
983   PetscMPIInt       size;
984 #if defined(PETSC_HAVE_SAWS)
985   PetscBool         issaws;
986 #endif
987 
988   PetscFunctionBegin;
989   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
990   PetscValidType(mat,1);
991   if (!viewer) {
992     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);
993   }
994   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
995   PetscCheckSameComm(mat,1,viewer,2);
996   MatCheckPreallocated(mat,1);
997   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
998   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
999   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0);
1000   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
1001   if (ibinary) {
1002     PetscBool mpiio;
1003     ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr);
1004     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
1005   }
1006 
1007   ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1008   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1009   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
1010     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
1011   }
1012 
1013 #if defined(PETSC_HAVE_SAWS)
1014   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
1015 #endif
1016   if (iascii) {
1017     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
1018     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr);
1019     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1020       MatNullSpace nullsp,transnullsp;
1021 
1022       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1023       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1024       ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
1025       if (rbs != 1 || cbs != 1) {
1026         if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);}
1027         else            {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);}
1028       } else {
1029         ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr);
1030       }
1031       if (mat->factortype) {
1032         MatSolverType solver;
1033         ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr);
1034         ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr);
1035       }
1036       if (mat->ops->getinfo) {
1037         MatInfo info;
1038         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
1039         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr);
1040         ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr);
1041       }
1042       ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr);
1043       ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr);
1044       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached null space\n");CHKERRQ(ierr);}
1045       if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached transposed null space\n");CHKERRQ(ierr);}
1046       ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr);
1047       if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");CHKERRQ(ierr);}
1048     }
1049 #if defined(PETSC_HAVE_SAWS)
1050   } else if (issaws) {
1051     PetscMPIInt rank;
1052 
1053     ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr);
1054     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
1055     if (!((PetscObject)mat)->amsmem && !rank) {
1056       ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr);
1057     }
1058 #endif
1059   }
1060   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) {
1061     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1062     ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr);
1063     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1064   } else if (mat->ops->view) {
1065     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1066     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
1067     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1068   }
1069   if (iascii) {
1070     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1071     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1072       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1073     }
1074   }
1075   ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr);
1076   PetscFunctionReturn(0);
1077 }
1078 
1079 #if defined(PETSC_USE_DEBUG)
1080 #include <../src/sys/totalview/tv_data_display.h>
1081 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1082 {
1083   TV_add_row("Local rows", "int", &mat->rmap->n);
1084   TV_add_row("Local columns", "int", &mat->cmap->n);
1085   TV_add_row("Global rows", "int", &mat->rmap->N);
1086   TV_add_row("Global columns", "int", &mat->cmap->N);
1087   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1088   return TV_format_OK;
1089 }
1090 #endif
1091 
1092 /*@C
1093    MatLoad - Loads a matrix that has been stored in binary/HDF5 format
1094    with MatView().  The matrix format is determined from the options database.
1095    Generates a parallel MPI matrix if the communicator has more than one
1096    processor.  The default matrix type is AIJ.
1097 
1098    Collective on PetscViewer
1099 
1100    Input Parameters:
1101 +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1102             or some related function before a call to MatLoad()
1103 -  viewer - binary/HDF5 file viewer
1104 
1105    Options Database Keys:
1106    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
1107    block size
1108 .    -matload_block_size <bs>
1109 
1110    Level: beginner
1111 
1112    Notes:
1113    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1114    Mat before calling this routine if you wish to set it from the options database.
1115 
1116    MatLoad() automatically loads into the options database any options
1117    given in the file filename.info where filename is the name of the file
1118    that was passed to the PetscViewerBinaryOpen(). The options in the info
1119    file will be ignored if you use the -viewer_binary_skip_info option.
1120 
1121    If the type or size of newmat is not set before a call to MatLoad, PETSc
1122    sets the default matrix type AIJ and sets the local and global sizes.
1123    If type and/or size is already set, then the same are used.
1124 
1125    In parallel, each processor can load a subset of rows (or the
1126    entire matrix).  This routine is especially useful when a large
1127    matrix is stored on disk and only part of it is desired on each
1128    processor.  For example, a parallel solver may access only some of
1129    the rows from each processor.  The algorithm used here reads
1130    relatively small blocks of data rather than reading the entire
1131    matrix and then subsetting it.
1132 
1133    Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5.
1134    Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(),
1135    or the sequence like
1136 $    PetscViewer v;
1137 $    PetscViewerCreate(PETSC_COMM_WORLD,&v);
1138 $    PetscViewerSetType(v,PETSCVIEWERBINARY);
1139 $    PetscViewerSetFromOptions(v);
1140 $    PetscViewerFileSetMode(v,FILE_MODE_READ);
1141 $    PetscViewerFileSetName(v,"datafile");
1142    The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option
1143 $ -viewer_type {binary,hdf5}
1144 
1145    See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach,
1146    and src/mat/examples/tutorials/ex10.c with the second approach.
1147 
1148    Notes about the PETSc binary format:
1149    In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks
1150    is read onto rank 0 and then shipped to its destination rank, one after another.
1151    Multiple objects, both matrices and vectors, can be stored within the same file.
1152    Their PetscObject name is ignored; they are loaded in the order of their storage.
1153 
1154    Most users should not need to know the details of the binary storage
1155    format, since MatLoad() and MatView() completely hide these details.
1156    But for anyone who's interested, the standard binary matrix storage
1157    format is
1158 
1159 $    int    MAT_FILE_CLASSID
1160 $    int    number of rows
1161 $    int    number of columns
1162 $    int    total number of nonzeros
1163 $    int    *number nonzeros in each row
1164 $    int    *column indices of all nonzeros (starting index is zero)
1165 $    PetscScalar *values of all nonzeros
1166 
1167    PETSc automatically does the byte swapping for
1168 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
1169 linux, Windows and the paragon; thus if you write your own binary
1170 read/write routines you have to swap the bytes; see PetscBinaryRead()
1171 and PetscBinaryWrite() to see how this may be done.
1172 
1173    Notes about the HDF5 (MATLAB MAT-File Version 7.3) format:
1174    In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used.
1175    Each processor's chunk is loaded independently by its owning rank.
1176    Multiple objects, both matrices and vectors, can be stored within the same file.
1177    They are looked up by their PetscObject name.
1178 
1179    As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use
1180    by default the same structure and naming of the AIJ arrays and column count
1181    (see PetscViewerHDF5SetAIJNames())
1182    within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g.
1183 $    save example.mat A b -v7.3
1184    can be directly read by this routine (see Reference 1 for details).
1185    Note that depending on your MATLAB version, this format might be a default,
1186    otherwise you can set it as default in Preferences.
1187 
1188    Unless -nocompression flag is used to save the file in MATLAB,
1189    PETSc must be configured with ZLIB package.
1190 
1191    See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c
1192 
1193    Current HDF5 (MAT-File) limitations:
1194    This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices.
1195 
1196    Corresponding MatView() is not yet implemented.
1197 
1198    The loaded matrix is actually a transpose of the original one in MATLAB,
1199    unless you push PETSC_VIEWER_HDF5_MAT format (see examples above).
1200    With this format, matrix is automatically transposed by PETSc,
1201    unless the matrix is marked as SPD or symmetric
1202    (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC).
1203 
1204    References:
1205 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version
1206 
1207 .keywords: matrix, load, binary, input, HDF5
1208 
1209 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad()
1210 
1211  @*/
1212 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1213 {
1214   PetscErrorCode ierr;
1215   PetscBool      flg;
1216 
1217   PetscFunctionBegin;
1218   PetscValidHeaderSpecific(newmat,MAT_CLASSID,1);
1219   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1220 
1221   if (!((PetscObject)newmat)->type_name) {
1222     ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr);
1223   }
1224 
1225   flg  = PETSC_FALSE;
1226   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr);
1227   if (flg) {
1228     ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
1229     ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
1230   }
1231   flg  = PETSC_FALSE;
1232   ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr);
1233   if (flg) {
1234     ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
1235   }
1236 
1237   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1238   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1239   ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr);
1240   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
1241   PetscFunctionReturn(0);
1242 }
1243 
1244 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1245 {
1246   PetscErrorCode ierr;
1247   Mat_Redundant  *redund = *redundant;
1248   PetscInt       i;
1249 
1250   PetscFunctionBegin;
1251   if (redund){
1252     if (redund->matseq) { /* via MatCreateSubMatrices()  */
1253       ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr);
1254       ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr);
1255       ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr);
1256     } else {
1257       ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr);
1258       ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr);
1259       ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr);
1260       for (i=0; i<redund->nrecvs; i++) {
1261         ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr);
1262         ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr);
1263       }
1264       ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr);
1265     }
1266 
1267     if (redund->subcomm) {
1268       ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr);
1269     }
1270     ierr = PetscFree(redund);CHKERRQ(ierr);
1271   }
1272   PetscFunctionReturn(0);
1273 }
1274 
1275 /*@
1276    MatDestroy - Frees space taken by a matrix.
1277 
1278    Collective on Mat
1279 
1280    Input Parameter:
1281 .  A - the matrix
1282 
1283    Level: beginner
1284 
1285 @*/
1286 PetscErrorCode MatDestroy(Mat *A)
1287 {
1288   PetscErrorCode ierr;
1289 
1290   PetscFunctionBegin;
1291   if (!*A) PetscFunctionReturn(0);
1292   PetscValidHeaderSpecific(*A,MAT_CLASSID,1);
1293   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);}
1294 
1295   /* if memory was published with SAWs then destroy it */
1296   ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr);
1297   if ((*A)->ops->destroy) {
1298     ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr);
1299   }
1300 
1301   ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr);
1302   ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr);
1303   ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr);
1304   ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr);
1305   ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr);
1306   ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr);
1307   ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr);
1308   ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr);
1309   ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr);
1310   ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr);
1311   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
1312   PetscFunctionReturn(0);
1313 }
1314 
1315 /*@C
1316    MatSetValues - Inserts or adds a block of values into a matrix.
1317    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1318    MUST be called after all calls to MatSetValues() have been completed.
1319 
1320    Not Collective
1321 
1322    Input Parameters:
1323 +  mat - the matrix
1324 .  v - a logically two-dimensional array of values
1325 .  m, idxm - the number of rows and their global indices
1326 .  n, idxn - the number of columns and their global indices
1327 -  addv - either ADD_VALUES or INSERT_VALUES, where
1328    ADD_VALUES adds values to any existing entries, and
1329    INSERT_VALUES replaces existing entries with new values
1330 
1331    Notes:
1332    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1333       MatSetUp() before using this routine
1334 
1335    By default the values, v, are row-oriented. See MatSetOption() for other options.
1336 
1337    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1338    options cannot be mixed without intervening calls to the assembly
1339    routines.
1340 
1341    MatSetValues() uses 0-based row and column numbers in Fortran
1342    as well as in C.
1343 
1344    Negative indices may be passed in idxm and idxn, these rows and columns are
1345    simply ignored. This allows easily inserting element stiffness matrices
1346    with homogeneous Dirchlet boundary conditions that you don't want represented
1347    in the matrix.
1348 
1349    Efficiency Alert:
1350    The routine MatSetValuesBlocked() may offer much better efficiency
1351    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1352 
1353    Level: beginner
1354 
1355    Developer Notes:
1356     This is labeled with C so does not automatically generate Fortran stubs and interfaces
1357                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1358 
1359    Concepts: matrices^putting entries in
1360 
1361 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1362           InsertMode, INSERT_VALUES, ADD_VALUES
1363 @*/
1364 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1365 {
1366   PetscErrorCode ierr;
1367 #if defined(PETSC_USE_DEBUG)
1368   PetscInt       i,j;
1369 #endif
1370 
1371   PetscFunctionBeginHot;
1372   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1373   PetscValidType(mat,1);
1374   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1375   PetscValidIntPointer(idxm,3);
1376   PetscValidIntPointer(idxn,5);
1377   PetscValidScalarPointer(v,6);
1378   MatCheckPreallocated(mat,1);
1379   if (mat->insertmode == NOT_SET_VALUES) {
1380     mat->insertmode = addv;
1381   }
1382 #if defined(PETSC_USE_DEBUG)
1383   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1384   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1385   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1386 
1387   for (i=0; i<m; i++) {
1388     for (j=0; j<n; j++) {
1389       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1390 #if defined(PETSC_USE_COMPLEX)
1391         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1392 #else
1393         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1394 #endif
1395     }
1396   }
1397 #endif
1398 
1399   if (mat->assembled) {
1400     mat->was_assembled = PETSC_TRUE;
1401     mat->assembled     = PETSC_FALSE;
1402   }
1403   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1404   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1405   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1406 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1407   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1408     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1409   }
1410 #endif
1411   PetscFunctionReturn(0);
1412 }
1413 
1414 
1415 /*@
1416    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1417         values into a matrix
1418 
1419    Not Collective
1420 
1421    Input Parameters:
1422 +  mat - the matrix
1423 .  row - the (block) row to set
1424 -  v - a logically two-dimensional array of values
1425 
1426    Notes:
1427    By the values, v, are column-oriented (for the block version) and sorted
1428 
1429    All the nonzeros in the row must be provided
1430 
1431    The matrix must have previously had its column indices set
1432 
1433    The row must belong to this process
1434 
1435    Level: intermediate
1436 
1437    Concepts: matrices^putting entries in
1438 
1439 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1440           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1441 @*/
1442 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1443 {
1444   PetscErrorCode ierr;
1445   PetscInt       globalrow;
1446 
1447   PetscFunctionBegin;
1448   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1449   PetscValidType(mat,1);
1450   PetscValidScalarPointer(v,2);
1451   ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr);
1452   ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr);
1453 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1454   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1455     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1456   }
1457 #endif
1458   PetscFunctionReturn(0);
1459 }
1460 
1461 /*@
1462    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1463         values into a matrix
1464 
1465    Not Collective
1466 
1467    Input Parameters:
1468 +  mat - the matrix
1469 .  row - the (block) row to set
1470 -  v - a logically two-dimensional (column major) array of values for  block matrices with blocksize larger than one, otherwise a one dimensional array of values
1471 
1472    Notes:
1473    The values, v, are column-oriented for the block version.
1474 
1475    All the nonzeros in the row must be provided
1476 
1477    THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1478 
1479    The row must belong to this process
1480 
1481    Level: advanced
1482 
1483    Concepts: matrices^putting entries in
1484 
1485 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1486           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1487 @*/
1488 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1489 {
1490   PetscErrorCode ierr;
1491 
1492   PetscFunctionBeginHot;
1493   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1494   PetscValidType(mat,1);
1495   MatCheckPreallocated(mat,1);
1496   PetscValidScalarPointer(v,2);
1497 #if defined(PETSC_USE_DEBUG)
1498   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1499   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1500 #endif
1501   mat->insertmode = INSERT_VALUES;
1502 
1503   if (mat->assembled) {
1504     mat->was_assembled = PETSC_TRUE;
1505     mat->assembled     = PETSC_FALSE;
1506   }
1507   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1508   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1509   ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr);
1510   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1511 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1512   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1513     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1514   }
1515 #endif
1516   PetscFunctionReturn(0);
1517 }
1518 
1519 /*@
1520    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1521      Using structured grid indexing
1522 
1523    Not Collective
1524 
1525    Input Parameters:
1526 +  mat - the matrix
1527 .  m - number of rows being entered
1528 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1529 .  n - number of columns being entered
1530 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1531 .  v - a logically two-dimensional array of values
1532 -  addv - either ADD_VALUES or INSERT_VALUES, where
1533    ADD_VALUES adds values to any existing entries, and
1534    INSERT_VALUES replaces existing entries with new values
1535 
1536    Notes:
1537    By default the values, v, are row-oriented.  See MatSetOption() for other options.
1538 
1539    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1540    options cannot be mixed without intervening calls to the assembly
1541    routines.
1542 
1543    The grid coordinates are across the entire grid, not just the local portion
1544 
1545    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1546    as well as in C.
1547 
1548    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1549 
1550    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1551    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1552 
1553    The columns and rows in the stencil passed in MUST be contained within the
1554    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1555    if you create a DMDA with an overlap of one grid level and on a particular process its first
1556    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1557    first i index you can use in your column and row indices in MatSetStencil() is 5.
1558 
1559    In Fortran idxm and idxn should be declared as
1560 $     MatStencil idxm(4,m),idxn(4,n)
1561    and the values inserted using
1562 $    idxm(MatStencil_i,1) = i
1563 $    idxm(MatStencil_j,1) = j
1564 $    idxm(MatStencil_k,1) = k
1565 $    idxm(MatStencil_c,1) = c
1566    etc
1567 
1568    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1569    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1570    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1571    DM_BOUNDARY_PERIODIC boundary type.
1572 
1573    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1574    a single value per point) you can skip filling those indices.
1575 
1576    Inspired by the structured grid interface to the HYPRE package
1577    (http://www.llnl.gov/CASC/hypre)
1578 
1579    Efficiency Alert:
1580    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1581    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1582 
1583    Level: beginner
1584 
1585    Concepts: matrices^putting entries in
1586 
1587 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1588           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1589 @*/
1590 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1591 {
1592   PetscErrorCode ierr;
1593   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1594   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1595   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1596 
1597   PetscFunctionBegin;
1598   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1599   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1600   PetscValidType(mat,1);
1601   PetscValidIntPointer(idxm,3);
1602   PetscValidIntPointer(idxn,5);
1603   PetscValidScalarPointer(v,6);
1604 
1605   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1606     jdxm = buf; jdxn = buf+m;
1607   } else {
1608     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1609     jdxm = bufm; jdxn = bufn;
1610   }
1611   for (i=0; i<m; i++) {
1612     for (j=0; j<3-sdim; j++) dxm++;
1613     tmp = *dxm++ - starts[0];
1614     for (j=0; j<dim-1; j++) {
1615       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1616       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1617     }
1618     if (mat->stencil.noc) dxm++;
1619     jdxm[i] = tmp;
1620   }
1621   for (i=0; i<n; i++) {
1622     for (j=0; j<3-sdim; j++) dxn++;
1623     tmp = *dxn++ - starts[0];
1624     for (j=0; j<dim-1; j++) {
1625       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1626       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1627     }
1628     if (mat->stencil.noc) dxn++;
1629     jdxn[i] = tmp;
1630   }
1631   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1632   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1633   PetscFunctionReturn(0);
1634 }
1635 
1636 /*@
1637    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1638      Using structured grid indexing
1639 
1640    Not Collective
1641 
1642    Input Parameters:
1643 +  mat - the matrix
1644 .  m - number of rows being entered
1645 .  idxm - grid coordinates for matrix rows being entered
1646 .  n - number of columns being entered
1647 .  idxn - grid coordinates for matrix columns being entered
1648 .  v - a logically two-dimensional array of values
1649 -  addv - either ADD_VALUES or INSERT_VALUES, where
1650    ADD_VALUES adds values to any existing entries, and
1651    INSERT_VALUES replaces existing entries with new values
1652 
1653    Notes:
1654    By default the values, v, are row-oriented and unsorted.
1655    See MatSetOption() for other options.
1656 
1657    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1658    options cannot be mixed without intervening calls to the assembly
1659    routines.
1660 
1661    The grid coordinates are across the entire grid, not just the local portion
1662 
1663    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1664    as well as in C.
1665 
1666    For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1667 
1668    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1669    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1670 
1671    The columns and rows in the stencil passed in MUST be contained within the
1672    ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1673    if you create a DMDA with an overlap of one grid level and on a particular process its first
1674    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1675    first i index you can use in your column and row indices in MatSetStencil() is 5.
1676 
1677    In Fortran idxm and idxn should be declared as
1678 $     MatStencil idxm(4,m),idxn(4,n)
1679    and the values inserted using
1680 $    idxm(MatStencil_i,1) = i
1681 $    idxm(MatStencil_j,1) = j
1682 $    idxm(MatStencil_k,1) = k
1683    etc
1684 
1685    Negative indices may be passed in idxm and idxn, these rows and columns are
1686    simply ignored. This allows easily inserting element stiffness matrices
1687    with homogeneous Dirchlet boundary conditions that you don't want represented
1688    in the matrix.
1689 
1690    Inspired by the structured grid interface to the HYPRE package
1691    (http://www.llnl.gov/CASC/hypre)
1692 
1693    Level: beginner
1694 
1695    Concepts: matrices^putting entries in
1696 
1697 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1698           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1699           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1700 @*/
1701 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1702 {
1703   PetscErrorCode ierr;
1704   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1705   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1706   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1707 
1708   PetscFunctionBegin;
1709   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1710   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1711   PetscValidType(mat,1);
1712   PetscValidIntPointer(idxm,3);
1713   PetscValidIntPointer(idxn,5);
1714   PetscValidScalarPointer(v,6);
1715 
1716   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1717     jdxm = buf; jdxn = buf+m;
1718   } else {
1719     ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr);
1720     jdxm = bufm; jdxn = bufn;
1721   }
1722   for (i=0; i<m; i++) {
1723     for (j=0; j<3-sdim; j++) dxm++;
1724     tmp = *dxm++ - starts[0];
1725     for (j=0; j<sdim-1; j++) {
1726       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1727       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1728     }
1729     dxm++;
1730     jdxm[i] = tmp;
1731   }
1732   for (i=0; i<n; i++) {
1733     for (j=0; j<3-sdim; j++) dxn++;
1734     tmp = *dxn++ - starts[0];
1735     for (j=0; j<sdim-1; j++) {
1736       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1737       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1738     }
1739     dxn++;
1740     jdxn[i] = tmp;
1741   }
1742   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
1743   ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr);
1744 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1745   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1746     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1747   }
1748 #endif
1749   PetscFunctionReturn(0);
1750 }
1751 
1752 /*@
1753    MatSetStencil - Sets the grid information for setting values into a matrix via
1754         MatSetValuesStencil()
1755 
1756    Not Collective
1757 
1758    Input Parameters:
1759 +  mat - the matrix
1760 .  dim - dimension of the grid 1, 2, or 3
1761 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1762 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
1763 -  dof - number of degrees of freedom per node
1764 
1765 
1766    Inspired by the structured grid interface to the HYPRE package
1767    (www.llnl.gov/CASC/hyper)
1768 
1769    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1770    user.
1771 
1772    Level: beginner
1773 
1774    Concepts: matrices^putting entries in
1775 
1776 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1777           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1778 @*/
1779 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1780 {
1781   PetscInt i;
1782 
1783   PetscFunctionBegin;
1784   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1785   PetscValidIntPointer(dims,3);
1786   PetscValidIntPointer(starts,4);
1787 
1788   mat->stencil.dim = dim + (dof > 1);
1789   for (i=0; i<dim; i++) {
1790     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1791     mat->stencil.starts[i] = starts[dim-i-1];
1792   }
1793   mat->stencil.dims[dim]   = dof;
1794   mat->stencil.starts[dim] = 0;
1795   mat->stencil.noc         = (PetscBool)(dof == 1);
1796   PetscFunctionReturn(0);
1797 }
1798 
1799 /*@C
1800    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1801 
1802    Not Collective
1803 
1804    Input Parameters:
1805 +  mat - the matrix
1806 .  v - a logically two-dimensional array of values
1807 .  m, idxm - the number of block rows and their global block indices
1808 .  n, idxn - the number of block columns and their global block indices
1809 -  addv - either ADD_VALUES or INSERT_VALUES, where
1810    ADD_VALUES adds values to any existing entries, and
1811    INSERT_VALUES replaces existing entries with new values
1812 
1813    Notes:
1814    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1815    MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1816 
1817    The m and n count the NUMBER of blocks in the row direction and column direction,
1818    NOT the total number of rows/columns; for example, if the block size is 2 and
1819    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1820    The values in idxm would be 1 2; that is the first index for each block divided by
1821    the block size.
1822 
1823    Note that you must call MatSetBlockSize() when constructing this matrix (before
1824    preallocating it).
1825 
1826    By default the values, v, are row-oriented, so the layout of
1827    v is the same as for MatSetValues(). See MatSetOption() for other options.
1828 
1829    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1830    options cannot be mixed without intervening calls to the assembly
1831    routines.
1832 
1833    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1834    as well as in C.
1835 
1836    Negative indices may be passed in idxm and idxn, these rows and columns are
1837    simply ignored. This allows easily inserting element stiffness matrices
1838    with homogeneous Dirchlet boundary conditions that you don't want represented
1839    in the matrix.
1840 
1841    Each time an entry is set within a sparse matrix via MatSetValues(),
1842    internal searching must be done to determine where to place the
1843    data in the matrix storage space.  By instead inserting blocks of
1844    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1845    reduced.
1846 
1847    Example:
1848 $   Suppose m=n=2 and block size(bs) = 2 The array is
1849 $
1850 $   1  2  | 3  4
1851 $   5  6  | 7  8
1852 $   - - - | - - -
1853 $   9  10 | 11 12
1854 $   13 14 | 15 16
1855 $
1856 $   v[] should be passed in like
1857 $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1858 $
1859 $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1860 $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1861 
1862    Level: intermediate
1863 
1864    Concepts: matrices^putting entries in blocked
1865 
1866 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1867 @*/
1868 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1869 {
1870   PetscErrorCode ierr;
1871 
1872   PetscFunctionBeginHot;
1873   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1874   PetscValidType(mat,1);
1875   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1876   PetscValidIntPointer(idxm,3);
1877   PetscValidIntPointer(idxn,5);
1878   PetscValidScalarPointer(v,6);
1879   MatCheckPreallocated(mat,1);
1880   if (mat->insertmode == NOT_SET_VALUES) {
1881     mat->insertmode = addv;
1882   }
1883 #if defined(PETSC_USE_DEBUG)
1884   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1885   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1886   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1887 #endif
1888 
1889   if (mat->assembled) {
1890     mat->was_assembled = PETSC_TRUE;
1891     mat->assembled     = PETSC_FALSE;
1892   }
1893   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1894   if (mat->ops->setvaluesblocked) {
1895     ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1896   } else {
1897     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1898     PetscInt i,j,bs,cbs;
1899     ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr);
1900     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1901       iidxm = buf; iidxn = buf + m*bs;
1902     } else {
1903       ierr  = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr);
1904       iidxm = bufr; iidxn = bufc;
1905     }
1906     for (i=0; i<m; i++) {
1907       for (j=0; j<bs; j++) {
1908         iidxm[i*bs+j] = bs*idxm[i] + j;
1909       }
1910     }
1911     for (i=0; i<n; i++) {
1912       for (j=0; j<cbs; j++) {
1913         iidxn[i*cbs+j] = cbs*idxn[i] + j;
1914       }
1915     }
1916     ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr);
1917     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
1918   }
1919   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1920 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1921   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
1922     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
1923   }
1924 #endif
1925   PetscFunctionReturn(0);
1926 }
1927 
1928 /*@
1929    MatGetValues - Gets a block of values from a matrix.
1930 
1931    Not Collective; currently only returns a local block
1932 
1933    Input Parameters:
1934 +  mat - the matrix
1935 .  v - a logically two-dimensional array for storing the values
1936 .  m, idxm - the number of rows and their global indices
1937 -  n, idxn - the number of columns and their global indices
1938 
1939    Notes:
1940    The user must allocate space (m*n PetscScalars) for the values, v.
1941    The values, v, are then returned in a row-oriented format,
1942    analogous to that used by default in MatSetValues().
1943 
1944    MatGetValues() uses 0-based row and column numbers in
1945    Fortran as well as in C.
1946 
1947    MatGetValues() requires that the matrix has been assembled
1948    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1949    MatSetValues() and MatGetValues() CANNOT be made in succession
1950    without intermediate matrix assembly.
1951 
1952    Negative row or column indices will be ignored and those locations in v[] will be
1953    left unchanged.
1954 
1955    Level: advanced
1956 
1957    Concepts: matrices^accessing values
1958 
1959 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1960 @*/
1961 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1962 {
1963   PetscErrorCode ierr;
1964 
1965   PetscFunctionBegin;
1966   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
1967   PetscValidType(mat,1);
1968   if (!m || !n) PetscFunctionReturn(0);
1969   PetscValidIntPointer(idxm,3);
1970   PetscValidIntPointer(idxn,5);
1971   PetscValidScalarPointer(v,6);
1972   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1973   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1974   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1975   MatCheckPreallocated(mat,1);
1976 
1977   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1978   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1979   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1980   PetscFunctionReturn(0);
1981 }
1982 
1983 /*@
1984   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1985   the same size. Currently, this can only be called once and creates the given matrix.
1986 
1987   Not Collective
1988 
1989   Input Parameters:
1990 + mat - the matrix
1991 . nb - the number of blocks
1992 . bs - the number of rows (and columns) in each block
1993 . rows - a concatenation of the rows for each block
1994 - v - a concatenation of logically two-dimensional arrays of values
1995 
1996   Notes:
1997   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1998 
1999   Level: advanced
2000 
2001   Concepts: matrices^putting entries in
2002 
2003 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
2004           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
2005 @*/
2006 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
2007 {
2008   PetscErrorCode ierr;
2009 
2010   PetscFunctionBegin;
2011   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2012   PetscValidType(mat,1);
2013   PetscValidScalarPointer(rows,4);
2014   PetscValidScalarPointer(v,5);
2015 #if defined(PETSC_USE_DEBUG)
2016   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2017 #endif
2018 
2019   ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2020   if (mat->ops->setvaluesbatch) {
2021     ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr);
2022   } else {
2023     PetscInt b;
2024     for (b = 0; b < nb; ++b) {
2025       ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr);
2026     }
2027   }
2028   ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr);
2029   PetscFunctionReturn(0);
2030 }
2031 
2032 /*@
2033    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
2034    the routine MatSetValuesLocal() to allow users to insert matrix entries
2035    using a local (per-processor) numbering.
2036 
2037    Not Collective
2038 
2039    Input Parameters:
2040 +  x - the matrix
2041 .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
2042 - cmapping - column mapping
2043 
2044    Level: intermediate
2045 
2046    Concepts: matrices^local to global mapping
2047    Concepts: local to global mapping^for matrices
2048 
2049 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
2050 @*/
2051 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
2052 {
2053   PetscErrorCode ierr;
2054 
2055   PetscFunctionBegin;
2056   PetscValidHeaderSpecific(x,MAT_CLASSID,1);
2057   PetscValidType(x,1);
2058   PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2);
2059   PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3);
2060 
2061   if (x->ops->setlocaltoglobalmapping) {
2062     ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr);
2063   } else {
2064     ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr);
2065     ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr);
2066   }
2067   PetscFunctionReturn(0);
2068 }
2069 
2070 
2071 /*@
2072    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
2073 
2074    Not Collective
2075 
2076    Input Parameters:
2077 .  A - the matrix
2078 
2079    Output Parameters:
2080 + rmapping - row mapping
2081 - cmapping - column mapping
2082 
2083    Level: advanced
2084 
2085    Concepts: matrices^local to global mapping
2086    Concepts: local to global mapping^for matrices
2087 
2088 .seealso:  MatSetValuesLocal()
2089 @*/
2090 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
2091 {
2092   PetscFunctionBegin;
2093   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2094   PetscValidType(A,1);
2095   if (rmapping) PetscValidPointer(rmapping,2);
2096   if (cmapping) PetscValidPointer(cmapping,3);
2097   if (rmapping) *rmapping = A->rmap->mapping;
2098   if (cmapping) *cmapping = A->cmap->mapping;
2099   PetscFunctionReturn(0);
2100 }
2101 
2102 /*@
2103    MatGetLayouts - Gets the PetscLayout objects for rows and columns
2104 
2105    Not Collective
2106 
2107    Input Parameters:
2108 .  A - the matrix
2109 
2110    Output Parameters:
2111 + rmap - row layout
2112 - cmap - column layout
2113 
2114    Level: advanced
2115 
2116 .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
2117 @*/
2118 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2119 {
2120   PetscFunctionBegin;
2121   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2122   PetscValidType(A,1);
2123   if (rmap) PetscValidPointer(rmap,2);
2124   if (cmap) PetscValidPointer(cmap,3);
2125   if (rmap) *rmap = A->rmap;
2126   if (cmap) *cmap = A->cmap;
2127   PetscFunctionReturn(0);
2128 }
2129 
2130 /*@C
2131    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2132    using a local ordering of the nodes.
2133 
2134    Not Collective
2135 
2136    Input Parameters:
2137 +  mat - the matrix
2138 .  nrow, irow - number of rows and their local indices
2139 .  ncol, icol - number of columns and their local indices
2140 .  y -  a logically two-dimensional array of values
2141 -  addv - either INSERT_VALUES or ADD_VALUES, where
2142    ADD_VALUES adds values to any existing entries, and
2143    INSERT_VALUES replaces existing entries with new values
2144 
2145    Notes:
2146    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2147       MatSetUp() before using this routine
2148 
2149    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2150 
2151    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2152    options cannot be mixed without intervening calls to the assembly
2153    routines.
2154 
2155    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2156    MUST be called after all calls to MatSetValuesLocal() have been completed.
2157 
2158    Level: intermediate
2159 
2160    Concepts: matrices^putting entries in with local numbering
2161 
2162    Developer Notes:
2163     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2164                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2165 
2166 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2167            MatSetValueLocal()
2168 @*/
2169 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2170 {
2171   PetscErrorCode ierr;
2172 
2173   PetscFunctionBeginHot;
2174   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2175   PetscValidType(mat,1);
2176   MatCheckPreallocated(mat,1);
2177   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2178   PetscValidIntPointer(irow,3);
2179   PetscValidIntPointer(icol,5);
2180   PetscValidScalarPointer(y,6);
2181   if (mat->insertmode == NOT_SET_VALUES) {
2182     mat->insertmode = addv;
2183   }
2184 #if defined(PETSC_USE_DEBUG)
2185   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2186   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2187   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2188 #endif
2189 
2190   if (mat->assembled) {
2191     mat->was_assembled = PETSC_TRUE;
2192     mat->assembled     = PETSC_FALSE;
2193   }
2194   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2195   if (mat->ops->setvalueslocal) {
2196     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2197   } else {
2198     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2199     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2200       irowm = buf; icolm = buf+nrow;
2201     } else {
2202       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2203       irowm = bufr; icolm = bufc;
2204     }
2205     ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2206     ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2207     ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2208     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2209   }
2210   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2211 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2212   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2213     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2214   }
2215 #endif
2216   PetscFunctionReturn(0);
2217 }
2218 
2219 /*@C
2220    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2221    using a local ordering of the nodes a block at a time.
2222 
2223    Not Collective
2224 
2225    Input Parameters:
2226 +  x - the matrix
2227 .  nrow, irow - number of rows and their local indices
2228 .  ncol, icol - number of columns and their local indices
2229 .  y -  a logically two-dimensional array of values
2230 -  addv - either INSERT_VALUES or ADD_VALUES, where
2231    ADD_VALUES adds values to any existing entries, and
2232    INSERT_VALUES replaces existing entries with new values
2233 
2234    Notes:
2235    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2236       MatSetUp() before using this routine
2237 
2238    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2239       before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2240 
2241    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2242    options cannot be mixed without intervening calls to the assembly
2243    routines.
2244 
2245    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2246    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2247 
2248    Level: intermediate
2249 
2250    Developer Notes:
2251     This is labeled with C so does not automatically generate Fortran stubs and interfaces
2252                     because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2253 
2254    Concepts: matrices^putting blocked values in with local numbering
2255 
2256 .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2257            MatSetValuesLocal(),  MatSetValuesBlocked()
2258 @*/
2259 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2260 {
2261   PetscErrorCode ierr;
2262 
2263   PetscFunctionBeginHot;
2264   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2265   PetscValidType(mat,1);
2266   MatCheckPreallocated(mat,1);
2267   if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */
2268   PetscValidIntPointer(irow,3);
2269   PetscValidIntPointer(icol,5);
2270   PetscValidScalarPointer(y,6);
2271   if (mat->insertmode == NOT_SET_VALUES) {
2272     mat->insertmode = addv;
2273   }
2274 #if defined(PETSC_USE_DEBUG)
2275   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2276   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2277   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2278 #endif
2279 
2280   if (mat->assembled) {
2281     mat->was_assembled = PETSC_TRUE;
2282     mat->assembled     = PETSC_FALSE;
2283   }
2284 #if defined(PETSC_USE_DEBUG)
2285   /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */
2286   if (mat->rmap->mapping) {
2287     PetscInt irbs, rbs;
2288     ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr);
2289     ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr);
2290     if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs);
2291   }
2292   if (mat->cmap->mapping) {
2293     PetscInt icbs, cbs;
2294     ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr);
2295     ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr);
2296     if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs);
2297   }
2298 #endif
2299   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2300   if (mat->ops->setvaluesblockedlocal) {
2301     ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
2302   } else {
2303     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2304     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2305       irowm = buf; icolm = buf + nrow;
2306     } else {
2307       ierr  = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr);
2308       irowm = bufr; icolm = bufc;
2309     }
2310     ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr);
2311     ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr);
2312     ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
2313     ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr);
2314   }
2315   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
2316 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
2317   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
2318     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
2319   }
2320 #endif
2321   PetscFunctionReturn(0);
2322 }
2323 
2324 /*@
2325    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2326 
2327    Collective on Mat and Vec
2328 
2329    Input Parameters:
2330 +  mat - the matrix
2331 -  x   - the vector to be multiplied
2332 
2333    Output Parameters:
2334 .  y - the result
2335 
2336    Notes:
2337    The vectors x and y cannot be the same.  I.e., one cannot
2338    call MatMult(A,y,y).
2339 
2340    Level: developer
2341 
2342    Concepts: matrix-vector product
2343 
2344 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2345 @*/
2346 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2347 {
2348   PetscErrorCode ierr;
2349 
2350   PetscFunctionBegin;
2351   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2352   PetscValidType(mat,1);
2353   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2354   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2355 
2356   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2357   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2358   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2359   MatCheckPreallocated(mat,1);
2360 
2361   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2362   ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr);
2363   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2364   PetscFunctionReturn(0);
2365 }
2366 
2367 /* --------------------------------------------------------*/
2368 /*@
2369    MatMult - Computes the matrix-vector product, y = Ax.
2370 
2371    Neighbor-wise Collective on Mat and Vec
2372 
2373    Input Parameters:
2374 +  mat - the matrix
2375 -  x   - the vector to be multiplied
2376 
2377    Output Parameters:
2378 .  y - the result
2379 
2380    Notes:
2381    The vectors x and y cannot be the same.  I.e., one cannot
2382    call MatMult(A,y,y).
2383 
2384    Level: beginner
2385 
2386    Concepts: matrix-vector product
2387 
2388 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2389 @*/
2390 PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2391 {
2392   PetscErrorCode ierr;
2393 
2394   PetscFunctionBegin;
2395   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2396   PetscValidType(mat,1);
2397   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2398   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2399   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2400   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2401   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2402 #if !defined(PETSC_HAVE_CONSTRAINTS)
2403   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);
2404   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);
2405   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);
2406 #endif
2407   ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr);
2408   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2409   MatCheckPreallocated(mat,1);
2410 
2411   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2412   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2413   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2414   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
2415   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
2416   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2417   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2418   PetscFunctionReturn(0);
2419 }
2420 
2421 /*@
2422    MatMultTranspose - Computes matrix transpose times a vector y = A^T * x.
2423 
2424    Neighbor-wise Collective on Mat and Vec
2425 
2426    Input Parameters:
2427 +  mat - the matrix
2428 -  x   - the vector to be multiplied
2429 
2430    Output Parameters:
2431 .  y - the result
2432 
2433    Notes:
2434    The vectors x and y cannot be the same.  I.e., one cannot
2435    call MatMultTranspose(A,y,y).
2436 
2437    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2438    use MatMultHermitianTranspose()
2439 
2440    Level: beginner
2441 
2442    Concepts: matrix vector product^transpose
2443 
2444 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2445 @*/
2446 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2447 {
2448   PetscErrorCode ierr;
2449 
2450   PetscFunctionBegin;
2451   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2452   PetscValidType(mat,1);
2453   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2454   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2455 
2456   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2457   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2458   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2459 #if !defined(PETSC_HAVE_CONSTRAINTS)
2460   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);
2461   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);
2462 #endif
2463   if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);}
2464   MatCheckPreallocated(mat,1);
2465 
2466   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined");
2467   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2468   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2469   ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
2470   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2471   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
2472   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2473   if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);}
2474   PetscFunctionReturn(0);
2475 }
2476 
2477 /*@
2478    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2479 
2480    Neighbor-wise Collective on Mat and Vec
2481 
2482    Input Parameters:
2483 +  mat - the matrix
2484 -  x   - the vector to be multilplied
2485 
2486    Output Parameters:
2487 .  y - the result
2488 
2489    Notes:
2490    The vectors x and y cannot be the same.  I.e., one cannot
2491    call MatMultHermitianTranspose(A,y,y).
2492 
2493    Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2494 
2495    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2496 
2497    Level: beginner
2498 
2499    Concepts: matrix vector product^transpose
2500 
2501 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2502 @*/
2503 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2504 {
2505   PetscErrorCode ierr;
2506   Vec            w;
2507 
2508   PetscFunctionBegin;
2509   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2510   PetscValidType(mat,1);
2511   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2512   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2513 
2514   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2515   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2516   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2517 #if !defined(PETSC_HAVE_CONSTRAINTS)
2518   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);
2519   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);
2520 #endif
2521   MatCheckPreallocated(mat,1);
2522 
2523   ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2524   if (mat->ops->multhermitiantranspose) {
2525     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2526     ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr);
2527     ierr = VecLockReadPop(x);CHKERRQ(ierr);
2528   } else {
2529     ierr = VecDuplicate(x,&w);CHKERRQ(ierr);
2530     ierr = VecCopy(x,w);CHKERRQ(ierr);
2531     ierr = VecConjugate(w);CHKERRQ(ierr);
2532     ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr);
2533     ierr = VecDestroy(&w);CHKERRQ(ierr);
2534     ierr = VecConjugate(y);CHKERRQ(ierr);
2535   }
2536   ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr);
2537   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2538   PetscFunctionReturn(0);
2539 }
2540 
2541 /*@
2542     MatMultAdd -  Computes v3 = v2 + A * v1.
2543 
2544     Neighbor-wise Collective on Mat and Vec
2545 
2546     Input Parameters:
2547 +   mat - the matrix
2548 -   v1, v2 - the vectors
2549 
2550     Output Parameters:
2551 .   v3 - the result
2552 
2553     Notes:
2554     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2555     call MatMultAdd(A,v1,v2,v1).
2556 
2557     Level: beginner
2558 
2559     Concepts: matrix vector product^addition
2560 
2561 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2562 @*/
2563 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2564 {
2565   PetscErrorCode ierr;
2566 
2567   PetscFunctionBegin;
2568   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2569   PetscValidType(mat,1);
2570   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2571   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2572   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2573 
2574   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2575   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2576   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);
2577   /* 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);
2578      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); */
2579   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);
2580   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);
2581   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2582   MatCheckPreallocated(mat,1);
2583 
2584   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2585   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2586   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2587   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2588   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2589   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2590   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2591   PetscFunctionReturn(0);
2592 }
2593 
2594 /*@
2595    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2596 
2597    Neighbor-wise Collective on Mat and Vec
2598 
2599    Input Parameters:
2600 +  mat - the matrix
2601 -  v1, v2 - the vectors
2602 
2603    Output Parameters:
2604 .  v3 - the result
2605 
2606    Notes:
2607    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2608    call MatMultTransposeAdd(A,v1,v2,v1).
2609 
2610    Level: beginner
2611 
2612    Concepts: matrix vector product^transpose and addition
2613 
2614 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2615 @*/
2616 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2617 {
2618   PetscErrorCode ierr;
2619 
2620   PetscFunctionBegin;
2621   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2622   PetscValidType(mat,1);
2623   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2624   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2625   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2626 
2627   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2628   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2629   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2630   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2631   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);
2632   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);
2633   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);
2634   MatCheckPreallocated(mat,1);
2635 
2636   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2637   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2638   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2639   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2640   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2641   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2642   PetscFunctionReturn(0);
2643 }
2644 
2645 /*@
2646    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2647 
2648    Neighbor-wise Collective on Mat and Vec
2649 
2650    Input Parameters:
2651 +  mat - the matrix
2652 -  v1, v2 - the vectors
2653 
2654    Output Parameters:
2655 .  v3 - the result
2656 
2657    Notes:
2658    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2659    call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2660 
2661    Level: beginner
2662 
2663    Concepts: matrix vector product^transpose and addition
2664 
2665 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2666 @*/
2667 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2668 {
2669   PetscErrorCode ierr;
2670 
2671   PetscFunctionBegin;
2672   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2673   PetscValidType(mat,1);
2674   PetscValidHeaderSpecific(v1,VEC_CLASSID,2);
2675   PetscValidHeaderSpecific(v2,VEC_CLASSID,3);
2676   PetscValidHeaderSpecific(v3,VEC_CLASSID,4);
2677 
2678   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2679   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2680   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2681   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);
2682   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);
2683   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);
2684   MatCheckPreallocated(mat,1);
2685 
2686   ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2687   ierr = VecLockReadPush(v1);CHKERRQ(ierr);
2688   if (mat->ops->multhermitiantransposeadd) {
2689     ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
2690   } else {
2691     Vec w,z;
2692     ierr = VecDuplicate(v1,&w);CHKERRQ(ierr);
2693     ierr = VecCopy(v1,w);CHKERRQ(ierr);
2694     ierr = VecConjugate(w);CHKERRQ(ierr);
2695     ierr = VecDuplicate(v3,&z);CHKERRQ(ierr);
2696     ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr);
2697     ierr = VecDestroy(&w);CHKERRQ(ierr);
2698     ierr = VecConjugate(z);CHKERRQ(ierr);
2699     if (v2 != v3) {
2700       ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr);
2701     } else {
2702       ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr);
2703     }
2704     ierr = VecDestroy(&z);CHKERRQ(ierr);
2705   }
2706   ierr = VecLockReadPop(v1);CHKERRQ(ierr);
2707   ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
2708   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
2709   PetscFunctionReturn(0);
2710 }
2711 
2712 /*@
2713    MatMultConstrained - The inner multiplication routine for a
2714    constrained matrix P^T A P.
2715 
2716    Neighbor-wise Collective on Mat and Vec
2717 
2718    Input Parameters:
2719 +  mat - the matrix
2720 -  x   - the vector to be multilplied
2721 
2722    Output Parameters:
2723 .  y - the result
2724 
2725    Notes:
2726    The vectors x and y cannot be the same.  I.e., one cannot
2727    call MatMult(A,y,y).
2728 
2729    Level: beginner
2730 
2731 .keywords: matrix, multiply, matrix-vector product, constraint
2732 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2733 @*/
2734 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2735 {
2736   PetscErrorCode ierr;
2737 
2738   PetscFunctionBegin;
2739   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2740   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2741   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2742   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2743   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2744   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2745   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);
2746   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);
2747   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);
2748 
2749   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2750   ierr = VecLockReadPush(x);CHKERRQ(ierr);
2751   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
2752   ierr = VecLockReadPop(x);CHKERRQ(ierr);
2753   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2754   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2755   PetscFunctionReturn(0);
2756 }
2757 
2758 /*@
2759    MatMultTransposeConstrained - The inner multiplication routine for a
2760    constrained matrix P^T A^T P.
2761 
2762    Neighbor-wise Collective on Mat and Vec
2763 
2764    Input Parameters:
2765 +  mat - the matrix
2766 -  x   - the vector to be multilplied
2767 
2768    Output Parameters:
2769 .  y - the result
2770 
2771    Notes:
2772    The vectors x and y cannot be the same.  I.e., one cannot
2773    call MatMult(A,y,y).
2774 
2775    Level: beginner
2776 
2777 .keywords: matrix, multiply, matrix-vector product, constraint
2778 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2779 @*/
2780 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2781 {
2782   PetscErrorCode ierr;
2783 
2784   PetscFunctionBegin;
2785   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2786   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2787   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2788   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2789   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2790   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2791   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);
2792   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);
2793 
2794   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2795   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
2796   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
2797   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
2798   PetscFunctionReturn(0);
2799 }
2800 
2801 /*@C
2802    MatGetFactorType - gets the type of factorization it is
2803 
2804    Not Collective
2805 
2806    Input Parameters:
2807 .  mat - the matrix
2808 
2809    Output Parameters:
2810 .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2811 
2812    Level: intermediate
2813 
2814 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType()
2815 @*/
2816 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2817 {
2818   PetscFunctionBegin;
2819   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2820   PetscValidType(mat,1);
2821   PetscValidPointer(t,2);
2822   *t = mat->factortype;
2823   PetscFunctionReturn(0);
2824 }
2825 
2826 /*@C
2827    MatSetFactorType - sets the type of factorization it is
2828 
2829    Logically Collective on Mat
2830 
2831    Input Parameters:
2832 +  mat - the matrix
2833 -  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2834 
2835    Level: intermediate
2836 
2837 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType()
2838 @*/
2839 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t)
2840 {
2841   PetscFunctionBegin;
2842   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2843   PetscValidType(mat,1);
2844   mat->factortype = t;
2845   PetscFunctionReturn(0);
2846 }
2847 
2848 /* ------------------------------------------------------------*/
2849 /*@C
2850    MatGetInfo - Returns information about matrix storage (number of
2851    nonzeros, memory, etc.).
2852 
2853    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2854 
2855    Input Parameters:
2856 .  mat - the matrix
2857 
2858    Output Parameters:
2859 +  flag - flag indicating the type of parameters to be returned
2860    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2861    MAT_GLOBAL_SUM - sum over all processors)
2862 -  info - matrix information context
2863 
2864    Notes:
2865    The MatInfo context contains a variety of matrix data, including
2866    number of nonzeros allocated and used, number of mallocs during
2867    matrix assembly, etc.  Additional information for factored matrices
2868    is provided (such as the fill ratio, number of mallocs during
2869    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2870    when using the runtime options
2871 $       -info -mat_view ::ascii_info
2872 
2873    Example for C/C++ Users:
2874    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2875    data within the MatInfo context.  For example,
2876 .vb
2877       MatInfo info;
2878       Mat     A;
2879       double  mal, nz_a, nz_u;
2880 
2881       MatGetInfo(A,MAT_LOCAL,&info);
2882       mal  = info.mallocs;
2883       nz_a = info.nz_allocated;
2884 .ve
2885 
2886    Example for Fortran Users:
2887    Fortran users should declare info as a double precision
2888    array of dimension MAT_INFO_SIZE, and then extract the parameters
2889    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2890    a complete list of parameter names.
2891 .vb
2892       double  precision info(MAT_INFO_SIZE)
2893       double  precision mal, nz_a
2894       Mat     A
2895       integer ierr
2896 
2897       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2898       mal = info(MAT_INFO_MALLOCS)
2899       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2900 .ve
2901 
2902     Level: intermediate
2903 
2904     Concepts: matrices^getting information on
2905 
2906     Developer Note: fortran interface is not autogenerated as the f90
2907     interface defintion cannot be generated correctly [due to MatInfo]
2908 
2909 .seealso: MatStashGetInfo()
2910 
2911 @*/
2912 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2913 {
2914   PetscErrorCode ierr;
2915 
2916   PetscFunctionBegin;
2917   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2918   PetscValidType(mat,1);
2919   PetscValidPointer(info,3);
2920   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2921   MatCheckPreallocated(mat,1);
2922   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
2923   PetscFunctionReturn(0);
2924 }
2925 
2926 /*
2927    This is used by external packages where it is not easy to get the info from the actual
2928    matrix factorization.
2929 */
2930 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2931 {
2932   PetscErrorCode ierr;
2933 
2934   PetscFunctionBegin;
2935   ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr);
2936   PetscFunctionReturn(0);
2937 }
2938 
2939 /* ----------------------------------------------------------*/
2940 
2941 /*@C
2942    MatLUFactor - Performs in-place LU factorization of matrix.
2943 
2944    Collective on Mat
2945 
2946    Input Parameters:
2947 +  mat - the matrix
2948 .  row - row permutation
2949 .  col - column permutation
2950 -  info - options for factorization, includes
2951 $          fill - expected fill as ratio of original fill.
2952 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2953 $                   Run with the option -info to determine an optimal value to use
2954 
2955    Notes:
2956    Most users should employ the simplified KSP interface for linear solvers
2957    instead of working directly with matrix algebra routines such as this.
2958    See, e.g., KSPCreate().
2959 
2960    This changes the state of the matrix to a factored matrix; it cannot be used
2961    for example with MatSetValues() unless one first calls MatSetUnfactored().
2962 
2963    Level: developer
2964 
2965    Concepts: matrices^LU factorization
2966 
2967 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2968           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2969 
2970     Developer Note: fortran interface is not autogenerated as the f90
2971     interface defintion cannot be generated correctly [due to MatFactorInfo]
2972 
2973 @*/
2974 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2975 {
2976   PetscErrorCode ierr;
2977   MatFactorInfo  tinfo;
2978 
2979   PetscFunctionBegin;
2980   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
2981   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
2982   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
2983   if (info) PetscValidPointer(info,4);
2984   PetscValidType(mat,1);
2985   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2986   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2987   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2988   MatCheckPreallocated(mat,1);
2989   if (!info) {
2990     ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr);
2991     info = &tinfo;
2992   }
2993 
2994   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2995   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
2996   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
2997   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
2998   PetscFunctionReturn(0);
2999 }
3000 
3001 /*@C
3002    MatILUFactor - Performs in-place ILU factorization of matrix.
3003 
3004    Collective on Mat
3005 
3006    Input Parameters:
3007 +  mat - the matrix
3008 .  row - row permutation
3009 .  col - column permutation
3010 -  info - structure containing
3011 $      levels - number of levels of fill.
3012 $      expected fill - as ratio of original fill.
3013 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3014                 missing diagonal entries)
3015 
3016    Notes:
3017    Probably really in-place only when level of fill is zero, otherwise allocates
3018    new space to store factored matrix and deletes previous memory.
3019 
3020    Most users should employ the simplified KSP interface for linear solvers
3021    instead of working directly with matrix algebra routines such as this.
3022    See, e.g., KSPCreate().
3023 
3024    Level: developer
3025 
3026    Concepts: matrices^ILU factorization
3027 
3028 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3029 
3030     Developer Note: fortran interface is not autogenerated as the f90
3031     interface defintion cannot be generated correctly [due to MatFactorInfo]
3032 
3033 @*/
3034 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
3035 {
3036   PetscErrorCode ierr;
3037 
3038   PetscFunctionBegin;
3039   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3040   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3041   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3042   PetscValidPointer(info,4);
3043   PetscValidType(mat,1);
3044   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
3045   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3047   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3048   MatCheckPreallocated(mat,1);
3049 
3050   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3051   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
3052   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
3053   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3054   PetscFunctionReturn(0);
3055 }
3056 
3057 /*@C
3058    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
3059    Call this routine before calling MatLUFactorNumeric().
3060 
3061    Collective on Mat
3062 
3063    Input Parameters:
3064 +  fact - the factor matrix obtained with MatGetFactor()
3065 .  mat - the matrix
3066 .  row, col - row and column permutations
3067 -  info - options for factorization, includes
3068 $          fill - expected fill as ratio of original fill.
3069 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3070 $                   Run with the option -info to determine an optimal value to use
3071 
3072 
3073    Notes:
3074     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
3075 
3076    Most users should employ the simplified KSP interface for linear solvers
3077    instead of working directly with matrix algebra routines such as this.
3078    See, e.g., KSPCreate().
3079 
3080    Level: developer
3081 
3082    Concepts: matrices^LU symbolic factorization
3083 
3084 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
3085 
3086     Developer Note: fortran interface is not autogenerated as the f90
3087     interface defintion cannot be generated correctly [due to MatFactorInfo]
3088 
3089 @*/
3090 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
3091 {
3092   PetscErrorCode ierr;
3093 
3094   PetscFunctionBegin;
3095   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3096   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
3097   if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3);
3098   if (info) PetscValidPointer(info,4);
3099   PetscValidType(mat,1);
3100   PetscValidPointer(fact,5);
3101   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3102   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3103   if (!(fact)->ops->lufactorsymbolic) {
3104     MatSolverType spackage;
3105     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3106     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
3107   }
3108   MatCheckPreallocated(mat,2);
3109 
3110   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3111   ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
3112   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3113   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3114   PetscFunctionReturn(0);
3115 }
3116 
3117 /*@C
3118    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
3119    Call this routine after first calling MatLUFactorSymbolic().
3120 
3121    Collective on Mat
3122 
3123    Input Parameters:
3124 +  fact - the factor matrix obtained with MatGetFactor()
3125 .  mat - the matrix
3126 -  info - options for factorization
3127 
3128    Notes:
3129    See MatLUFactor() for in-place factorization.  See
3130    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3131 
3132    Most users should employ the simplified KSP interface for linear solvers
3133    instead of working directly with matrix algebra routines such as this.
3134    See, e.g., KSPCreate().
3135 
3136    Level: developer
3137 
3138    Concepts: matrices^LU numeric factorization
3139 
3140 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3141 
3142     Developer Note: fortran interface is not autogenerated as the f90
3143     interface defintion cannot be generated correctly [due to MatFactorInfo]
3144 
3145 @*/
3146 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3147 {
3148   PetscErrorCode ierr;
3149 
3150   PetscFunctionBegin;
3151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3152   PetscValidType(mat,1);
3153   PetscValidPointer(fact,2);
3154   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3155   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3156   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);
3157 
3158   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3159   MatCheckPreallocated(mat,2);
3160   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3161   ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr);
3162   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3163   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3164   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3165   PetscFunctionReturn(0);
3166 }
3167 
3168 /*@C
3169    MatCholeskyFactor - Performs in-place Cholesky factorization of a
3170    symmetric matrix.
3171 
3172    Collective on Mat
3173 
3174    Input Parameters:
3175 +  mat - the matrix
3176 .  perm - row and column permutations
3177 -  f - expected fill as ratio of original fill
3178 
3179    Notes:
3180    See MatLUFactor() for the nonsymmetric case.  See also
3181    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3182 
3183    Most users should employ the simplified KSP interface for linear solvers
3184    instead of working directly with matrix algebra routines such as this.
3185    See, e.g., KSPCreate().
3186 
3187    Level: developer
3188 
3189    Concepts: matrices^Cholesky factorization
3190 
3191 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3192           MatGetOrdering()
3193 
3194     Developer Note: fortran interface is not autogenerated as the f90
3195     interface defintion cannot be generated correctly [due to MatFactorInfo]
3196 
3197 @*/
3198 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3199 {
3200   PetscErrorCode ierr;
3201 
3202   PetscFunctionBegin;
3203   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3204   PetscValidType(mat,1);
3205   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3206   if (info) PetscValidPointer(info,3);
3207   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3208   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3209   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3210   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);
3211   MatCheckPreallocated(mat,1);
3212 
3213   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3214   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
3215   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
3216   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
3217   PetscFunctionReturn(0);
3218 }
3219 
3220 /*@C
3221    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3222    of a symmetric matrix.
3223 
3224    Collective on Mat
3225 
3226    Input Parameters:
3227 +  fact - the factor matrix obtained with MatGetFactor()
3228 .  mat - the matrix
3229 .  perm - row and column permutations
3230 -  info - options for factorization, includes
3231 $          fill - expected fill as ratio of original fill.
3232 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3233 $                   Run with the option -info to determine an optimal value to use
3234 
3235    Notes:
3236    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
3237    MatCholeskyFactor() and MatCholeskyFactorNumeric().
3238 
3239    Most users should employ the simplified KSP interface for linear solvers
3240    instead of working directly with matrix algebra routines such as this.
3241    See, e.g., KSPCreate().
3242 
3243    Level: developer
3244 
3245    Concepts: matrices^Cholesky symbolic factorization
3246 
3247 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3248           MatGetOrdering()
3249 
3250     Developer Note: fortran interface is not autogenerated as the f90
3251     interface defintion cannot be generated correctly [due to MatFactorInfo]
3252 
3253 @*/
3254 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3255 {
3256   PetscErrorCode ierr;
3257 
3258   PetscFunctionBegin;
3259   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3260   PetscValidType(mat,1);
3261   if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2);
3262   if (info) PetscValidPointer(info,3);
3263   PetscValidPointer(fact,4);
3264   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3265   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3266   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3267   if (!(fact)->ops->choleskyfactorsymbolic) {
3268     MatSolverType spackage;
3269     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
3270     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3271   }
3272   MatCheckPreallocated(mat,2);
3273 
3274   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3275   ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
3276   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3277   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3278   PetscFunctionReturn(0);
3279 }
3280 
3281 /*@C
3282    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3283    of a symmetric matrix. Call this routine after first calling
3284    MatCholeskyFactorSymbolic().
3285 
3286    Collective on Mat
3287 
3288    Input Parameters:
3289 +  fact - the factor matrix obtained with MatGetFactor()
3290 .  mat - the initial matrix
3291 .  info - options for factorization
3292 -  fact - the symbolic factor of mat
3293 
3294 
3295    Notes:
3296    Most users should employ the simplified KSP interface for linear solvers
3297    instead of working directly with matrix algebra routines such as this.
3298    See, e.g., KSPCreate().
3299 
3300    Level: developer
3301 
3302    Concepts: matrices^Cholesky numeric factorization
3303 
3304 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3305 
3306     Developer Note: fortran interface is not autogenerated as the f90
3307     interface defintion cannot be generated correctly [due to MatFactorInfo]
3308 
3309 @*/
3310 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3311 {
3312   PetscErrorCode ierr;
3313 
3314   PetscFunctionBegin;
3315   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3316   PetscValidType(mat,1);
3317   PetscValidPointer(fact,2);
3318   PetscValidHeaderSpecific(fact,MAT_CLASSID,2);
3319   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3320   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3321   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);
3322   MatCheckPreallocated(mat,2);
3323 
3324   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3325   ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr);
3326   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);
3327   ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr);
3328   ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr);
3329   PetscFunctionReturn(0);
3330 }
3331 
3332 /* ----------------------------------------------------------------*/
3333 /*@
3334    MatSolve - Solves A x = b, given a factored matrix.
3335 
3336    Neighbor-wise Collective on Mat and Vec
3337 
3338    Input Parameters:
3339 +  mat - the factored matrix
3340 -  b - the right-hand-side vector
3341 
3342    Output Parameter:
3343 .  x - the result vector
3344 
3345    Notes:
3346    The vectors b and x cannot be the same.  I.e., one cannot
3347    call MatSolve(A,x,x).
3348 
3349    Notes:
3350    Most users should employ the simplified KSP interface for linear solvers
3351    instead of working directly with matrix algebra routines such as this.
3352    See, e.g., KSPCreate().
3353 
3354    Level: developer
3355 
3356    Concepts: matrices^triangular solves
3357 
3358 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3359 @*/
3360 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3361 {
3362   PetscErrorCode ierr;
3363 
3364   PetscFunctionBegin;
3365   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3366   PetscValidType(mat,1);
3367   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3368   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3369   PetscCheckSameComm(mat,1,b,2);
3370   PetscCheckSameComm(mat,1,x,3);
3371   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3372   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);
3373   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);
3374   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);
3375   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3376   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3377   MatCheckPreallocated(mat,1);
3378 
3379   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3380   if (mat->factorerrortype) {
3381     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3382     ierr = VecSetInf(x);CHKERRQ(ierr);
3383   } else {
3384     if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3385     ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
3386   }
3387   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
3388   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3389   PetscFunctionReturn(0);
3390 }
3391 
3392 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3393 {
3394   PetscErrorCode ierr;
3395   Vec            b,x;
3396   PetscInt       m,N,i;
3397   PetscScalar    *bb,*xx;
3398   PetscBool      flg;
3399 
3400   PetscFunctionBegin;
3401   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3402   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3403   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
3404   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3405 
3406   ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr);
3407   ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr);
3408   ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr);  /* number local rows */
3409   ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr);       /* total columns in dense matrix */
3410   ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr);
3411   for (i=0; i<N; i++) {
3412     ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr);
3413     ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr);
3414     if (trans) {
3415       ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr);
3416     } else {
3417       ierr = MatSolve(A,b,x);CHKERRQ(ierr);
3418     }
3419     ierr = VecResetArray(x);CHKERRQ(ierr);
3420     ierr = VecResetArray(b);CHKERRQ(ierr);
3421   }
3422   ierr = VecDestroy(&b);CHKERRQ(ierr);
3423   ierr = VecDestroy(&x);CHKERRQ(ierr);
3424   ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr);
3425   ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr);
3426   PetscFunctionReturn(0);
3427 }
3428 
3429 /*@
3430    MatMatSolve - Solves A X = B, given a factored matrix.
3431 
3432    Neighbor-wise Collective on Mat
3433 
3434    Input Parameters:
3435 +  A - the factored matrix
3436 -  B - the right-hand-side matrix  (dense matrix)
3437 
3438    Output Parameter:
3439 .  X - the result matrix (dense matrix)
3440 
3441    Notes:
3442    The matrices b and x cannot be the same.  I.e., one cannot
3443    call MatMatSolve(A,x,x).
3444 
3445    Notes:
3446    Most users should usually employ the simplified KSP interface for linear solvers
3447    instead of working directly with matrix algebra routines such as this.
3448    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3449    at a time.
3450 
3451    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3452    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3453 
3454    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3455 
3456    Level: developer
3457 
3458    Concepts: matrices^triangular solves
3459 
3460 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3461 @*/
3462 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3463 {
3464   PetscErrorCode ierr;
3465 
3466   PetscFunctionBegin;
3467   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3468   PetscValidType(A,1);
3469   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3470   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3471   PetscCheckSameComm(A,1,B,2);
3472   PetscCheckSameComm(A,1,X,3);
3473   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3474   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);
3475   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);
3476   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");
3477   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3478   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3479   MatCheckPreallocated(A,1);
3480 
3481   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3482   if (!A->ops->matsolve) {
3483     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3484     ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr);
3485   } else {
3486     ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr);
3487   }
3488   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3489   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3490   PetscFunctionReturn(0);
3491 }
3492 
3493 /*@
3494    MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3495 
3496    Neighbor-wise Collective on Mat
3497 
3498    Input Parameters:
3499 +  A - the factored matrix
3500 -  B - the right-hand-side matrix  (dense matrix)
3501 
3502    Output Parameter:
3503 .  X - the result matrix (dense matrix)
3504 
3505    Notes:
3506    The matrices B and X cannot be the same.  I.e., one cannot
3507    call MatMatSolveTranspose(A,X,X).
3508 
3509    Notes:
3510    Most users should usually employ the simplified KSP interface for linear solvers
3511    instead of working directly with matrix algebra routines such as this.
3512    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3513    at a time.
3514 
3515    When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously.
3516 
3517    Level: developer
3518 
3519    Concepts: matrices^triangular solves
3520 
3521 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor()
3522 @*/
3523 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3524 {
3525   PetscErrorCode ierr;
3526 
3527   PetscFunctionBegin;
3528   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3529   PetscValidType(A,1);
3530   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
3531   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3532   PetscCheckSameComm(A,1,B,2);
3533   PetscCheckSameComm(A,1,X,3);
3534   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3535   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);
3536   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);
3537   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);
3538   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");
3539   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3540   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3541   MatCheckPreallocated(A,1);
3542 
3543   ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3544   if (!A->ops->matsolvetranspose) {
3545     ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr);
3546     ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr);
3547   } else {
3548     ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr);
3549   }
3550   ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr);
3551   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3552   PetscFunctionReturn(0);
3553 }
3554 
3555 /*@
3556    MatMatTransposeSolve - Solves A X = B^T, given a factored matrix.
3557 
3558    Neighbor-wise Collective on Mat
3559 
3560    Input Parameters:
3561 +  A - the factored matrix
3562 -  Bt - the transpose of right-hand-side matrix
3563 
3564    Output Parameter:
3565 .  X - the result matrix (dense matrix)
3566 
3567    Notes:
3568    Most users should usually employ the simplified KSP interface for linear solvers
3569    instead of working directly with matrix algebra routines such as this.
3570    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3571    at a time.
3572 
3573    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().
3574 
3575    Level: developer
3576 
3577    Concepts: matrices^triangular solves
3578 
3579 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3580 @*/
3581 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X)
3582 {
3583   PetscErrorCode ierr;
3584 
3585   PetscFunctionBegin;
3586   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3587   PetscValidType(A,1);
3588   PetscValidHeaderSpecific(Bt,MAT_CLASSID,2);
3589   PetscValidHeaderSpecific(X,MAT_CLASSID,3);
3590   PetscCheckSameComm(A,1,Bt,2);
3591   PetscCheckSameComm(A,1,X,3);
3592 
3593   if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3594   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);
3595   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);
3596   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");
3597   if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0);
3598   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3599   MatCheckPreallocated(A,1);
3600 
3601   if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
3602   ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3603   ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr);
3604   ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr);
3605   ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr);
3606   PetscFunctionReturn(0);
3607 }
3608 
3609 /*@
3610    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3611                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3612 
3613    Neighbor-wise Collective on Mat and Vec
3614 
3615    Input Parameters:
3616 +  mat - the factored matrix
3617 -  b - the right-hand-side vector
3618 
3619    Output Parameter:
3620 .  x - the result vector
3621 
3622    Notes:
3623    MatSolve() should be used for most applications, as it performs
3624    a forward solve followed by a backward solve.
3625 
3626    The vectors b and x cannot be the same,  i.e., one cannot
3627    call MatForwardSolve(A,x,x).
3628 
3629    For matrix in seqsbaij format with block size larger than 1,
3630    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3631    MatForwardSolve() solves U^T*D y = b, and
3632    MatBackwardSolve() solves U x = y.
3633    Thus they do not provide a symmetric preconditioner.
3634 
3635    Most users should employ the simplified KSP interface for linear solvers
3636    instead of working directly with matrix algebra routines such as this.
3637    See, e.g., KSPCreate().
3638 
3639    Level: developer
3640 
3641    Concepts: matrices^forward solves
3642 
3643 .seealso: MatSolve(), MatBackwardSolve()
3644 @*/
3645 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3646 {
3647   PetscErrorCode ierr;
3648 
3649   PetscFunctionBegin;
3650   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3651   PetscValidType(mat,1);
3652   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3653   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3654   PetscCheckSameComm(mat,1,b,2);
3655   PetscCheckSameComm(mat,1,x,3);
3656   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3657   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);
3658   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);
3659   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);
3660   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3661   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3662   MatCheckPreallocated(mat,1);
3663 
3664   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3665   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3666   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
3667   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
3668   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3669   PetscFunctionReturn(0);
3670 }
3671 
3672 /*@
3673    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3674                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3675 
3676    Neighbor-wise Collective on Mat and Vec
3677 
3678    Input Parameters:
3679 +  mat - the factored matrix
3680 -  b - the right-hand-side vector
3681 
3682    Output Parameter:
3683 .  x - the result vector
3684 
3685    Notes:
3686    MatSolve() should be used for most applications, as it performs
3687    a forward solve followed by a backward solve.
3688 
3689    The vectors b and x cannot be the same.  I.e., one cannot
3690    call MatBackwardSolve(A,x,x).
3691 
3692    For matrix in seqsbaij format with block size larger than 1,
3693    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3694    MatForwardSolve() solves U^T*D y = b, and
3695    MatBackwardSolve() solves U x = y.
3696    Thus they do not provide a symmetric preconditioner.
3697 
3698    Most users should employ the simplified KSP interface for linear solvers
3699    instead of working directly with matrix algebra routines such as this.
3700    See, e.g., KSPCreate().
3701 
3702    Level: developer
3703 
3704    Concepts: matrices^backward solves
3705 
3706 .seealso: MatSolve(), MatForwardSolve()
3707 @*/
3708 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3709 {
3710   PetscErrorCode ierr;
3711 
3712   PetscFunctionBegin;
3713   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3714   PetscValidType(mat,1);
3715   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3716   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3717   PetscCheckSameComm(mat,1,b,2);
3718   PetscCheckSameComm(mat,1,x,3);
3719   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3720   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);
3721   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);
3722   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);
3723   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3724   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3725   MatCheckPreallocated(mat,1);
3726 
3727   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3728   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3729   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
3730   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
3731   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3732   PetscFunctionReturn(0);
3733 }
3734 
3735 /*@
3736    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3737 
3738    Neighbor-wise Collective on Mat and Vec
3739 
3740    Input Parameters:
3741 +  mat - the factored matrix
3742 .  b - the right-hand-side vector
3743 -  y - the vector to be added to
3744 
3745    Output Parameter:
3746 .  x - the result vector
3747 
3748    Notes:
3749    The vectors b and x cannot be the same.  I.e., one cannot
3750    call MatSolveAdd(A,x,y,x).
3751 
3752    Most users should employ the simplified KSP interface for linear solvers
3753    instead of working directly with matrix algebra routines such as this.
3754    See, e.g., KSPCreate().
3755 
3756    Level: developer
3757 
3758    Concepts: matrices^triangular solves
3759 
3760 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3761 @*/
3762 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3763 {
3764   PetscScalar    one = 1.0;
3765   Vec            tmp;
3766   PetscErrorCode ierr;
3767 
3768   PetscFunctionBegin;
3769   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3770   PetscValidType(mat,1);
3771   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3772   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3773   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3774   PetscCheckSameComm(mat,1,b,2);
3775   PetscCheckSameComm(mat,1,y,2);
3776   PetscCheckSameComm(mat,1,x,3);
3777   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3778   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);
3779   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);
3780   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);
3781   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);
3782   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);
3783   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3784   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3785   MatCheckPreallocated(mat,1);
3786 
3787   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3788   if (mat->ops->solveadd) {
3789     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
3790   } else {
3791     /* do the solve then the add manually */
3792     if (x != y) {
3793       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3794       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3795     } else {
3796       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3797       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3798       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3799       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
3800       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3801       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3802     }
3803   }
3804   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
3805   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3806   PetscFunctionReturn(0);
3807 }
3808 
3809 /*@
3810    MatSolveTranspose - Solves A' x = b, given a factored matrix.
3811 
3812    Neighbor-wise Collective on Mat and Vec
3813 
3814    Input Parameters:
3815 +  mat - the factored matrix
3816 -  b - the right-hand-side vector
3817 
3818    Output Parameter:
3819 .  x - the result vector
3820 
3821    Notes:
3822    The vectors b and x cannot be the same.  I.e., one cannot
3823    call MatSolveTranspose(A,x,x).
3824 
3825    Most users should employ the simplified KSP interface for linear solvers
3826    instead of working directly with matrix algebra routines such as this.
3827    See, e.g., KSPCreate().
3828 
3829    Level: developer
3830 
3831    Concepts: matrices^triangular solves
3832 
3833 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3834 @*/
3835 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3836 {
3837   PetscErrorCode ierr;
3838 
3839   PetscFunctionBegin;
3840   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3841   PetscValidType(mat,1);
3842   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
3843   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3844   PetscCheckSameComm(mat,1,b,2);
3845   PetscCheckSameComm(mat,1,x,3);
3846   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3847   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);
3848   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);
3849   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3850   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3851   MatCheckPreallocated(mat,1);
3852   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3853   if (mat->factorerrortype) {
3854     ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3855     ierr = VecSetInf(x);CHKERRQ(ierr);
3856   } else {
3857     if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3858     ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
3859   }
3860   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
3861   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3862   PetscFunctionReturn(0);
3863 }
3864 
3865 /*@
3866    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3867                       factored matrix.
3868 
3869    Neighbor-wise Collective on Mat and Vec
3870 
3871    Input Parameters:
3872 +  mat - the factored matrix
3873 .  b - the right-hand-side vector
3874 -  y - the vector to be added to
3875 
3876    Output Parameter:
3877 .  x - the result vector
3878 
3879    Notes:
3880    The vectors b and x cannot be the same.  I.e., one cannot
3881    call MatSolveTransposeAdd(A,x,y,x).
3882 
3883    Most users should employ the simplified KSP interface for linear solvers
3884    instead of working directly with matrix algebra routines such as this.
3885    See, e.g., KSPCreate().
3886 
3887    Level: developer
3888 
3889    Concepts: matrices^triangular solves
3890 
3891 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3892 @*/
3893 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3894 {
3895   PetscScalar    one = 1.0;
3896   PetscErrorCode ierr;
3897   Vec            tmp;
3898 
3899   PetscFunctionBegin;
3900   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3901   PetscValidType(mat,1);
3902   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3903   PetscValidHeaderSpecific(b,VEC_CLASSID,3);
3904   PetscValidHeaderSpecific(x,VEC_CLASSID,4);
3905   PetscCheckSameComm(mat,1,b,2);
3906   PetscCheckSameComm(mat,1,y,3);
3907   PetscCheckSameComm(mat,1,x,4);
3908   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3909   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);
3910   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);
3911   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);
3912   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);
3913   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
3914   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3915   MatCheckPreallocated(mat,1);
3916 
3917   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3918   if (mat->ops->solvetransposeadd) {
3919     if (mat->factorerrortype) {
3920       ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr);
3921       ierr = VecSetInf(x);CHKERRQ(ierr);
3922     } else {
3923       ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
3924     }
3925   } else {
3926     /* do the solve then the add manually */
3927     if (x != y) {
3928       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3929       ierr = VecAXPY(x,one,y);CHKERRQ(ierr);
3930     } else {
3931       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
3932       ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr);
3933       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
3934       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
3935       ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr);
3936       ierr = VecDestroy(&tmp);CHKERRQ(ierr);
3937     }
3938   }
3939   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
3940   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
3941   PetscFunctionReturn(0);
3942 }
3943 /* ----------------------------------------------------------------*/
3944 
3945 /*@
3946    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3947 
3948    Neighbor-wise Collective on Mat and Vec
3949 
3950    Input Parameters:
3951 +  mat - the matrix
3952 .  b - the right hand side
3953 .  omega - the relaxation factor
3954 .  flag - flag indicating the type of SOR (see below)
3955 .  shift -  diagonal shift
3956 .  its - the number of iterations
3957 -  lits - the number of local iterations
3958 
3959    Output Parameters:
3960 .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3961 
3962    SOR Flags:
3963 .     SOR_FORWARD_SWEEP - forward SOR
3964 .     SOR_BACKWARD_SWEEP - backward SOR
3965 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3966 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3967 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3968 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3969 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3970          upper/lower triangular part of matrix to
3971          vector (with omega)
3972 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
3973 
3974    Notes:
3975    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3976    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3977    on each processor.
3978 
3979    Application programmers will not generally use MatSOR() directly,
3980    but instead will employ the KSP/PC interface.
3981 
3982    Notes:
3983     for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3984 
3985    Notes for Advanced Users:
3986    The flags are implemented as bitwise inclusive or operations.
3987    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3988    to specify a zero initial guess for SSOR.
3989 
3990    Most users should employ the simplified KSP interface for linear solvers
3991    instead of working directly with matrix algebra routines such as this.
3992    See, e.g., KSPCreate().
3993 
3994    Vectors x and b CANNOT be the same
3995 
3996    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3997 
3998    Level: developer
3999 
4000    Concepts: matrices^relaxation
4001    Concepts: matrices^SOR
4002    Concepts: matrices^Gauss-Seidel
4003 
4004 @*/
4005 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
4006 {
4007   PetscErrorCode ierr;
4008 
4009   PetscFunctionBegin;
4010   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4011   PetscValidType(mat,1);
4012   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
4013   PetscValidHeaderSpecific(x,VEC_CLASSID,8);
4014   PetscCheckSameComm(mat,1,b,2);
4015   PetscCheckSameComm(mat,1,x,8);
4016   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4017   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4018   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4019   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);
4020   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);
4021   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);
4022   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
4023   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
4024   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
4025 
4026   MatCheckPreallocated(mat,1);
4027   ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4028   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
4029   ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr);
4030   ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr);
4031   PetscFunctionReturn(0);
4032 }
4033 
4034 /*
4035       Default matrix copy routine.
4036 */
4037 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
4038 {
4039   PetscErrorCode    ierr;
4040   PetscInt          i,rstart = 0,rend = 0,nz;
4041   const PetscInt    *cwork;
4042   const PetscScalar *vwork;
4043 
4044   PetscFunctionBegin;
4045   if (B->assembled) {
4046     ierr = MatZeroEntries(B);CHKERRQ(ierr);
4047   }
4048   if (str == SAME_NONZERO_PATTERN) {
4049     ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
4050     for (i=rstart; i<rend; i++) {
4051       ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4052       ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
4053       ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
4054     }
4055   } else {
4056     ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr);
4057   }
4058   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4059   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
4060   PetscFunctionReturn(0);
4061 }
4062 
4063 /*@
4064    MatCopy - Copies a matrix to another matrix.
4065 
4066    Collective on Mat
4067 
4068    Input Parameters:
4069 +  A - the matrix
4070 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
4071 
4072    Output Parameter:
4073 .  B - where the copy is put
4074 
4075    Notes:
4076    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
4077    same nonzero pattern or the routine will crash.
4078 
4079    MatCopy() copies the matrix entries of a matrix to another existing
4080    matrix (after first zeroing the second matrix).  A related routine is
4081    MatConvert(), which first creates a new matrix and then copies the data.
4082 
4083    Level: intermediate
4084 
4085    Concepts: matrices^copying
4086 
4087 .seealso: MatConvert(), MatDuplicate()
4088 
4089 @*/
4090 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
4091 {
4092   PetscErrorCode ierr;
4093   PetscInt       i;
4094 
4095   PetscFunctionBegin;
4096   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4097   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4098   PetscValidType(A,1);
4099   PetscValidType(B,2);
4100   PetscCheckSameComm(A,1,B,2);
4101   MatCheckPreallocated(B,2);
4102   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4103   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4104   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);
4105   MatCheckPreallocated(A,1);
4106   if (A == B) PetscFunctionReturn(0);
4107 
4108   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4109   if (A->ops->copy) {
4110     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
4111   } else { /* generic conversion */
4112     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
4113   }
4114 
4115   B->stencil.dim = A->stencil.dim;
4116   B->stencil.noc = A->stencil.noc;
4117   for (i=0; i<=A->stencil.dim; i++) {
4118     B->stencil.dims[i]   = A->stencil.dims[i];
4119     B->stencil.starts[i] = A->stencil.starts[i];
4120   }
4121 
4122   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
4123   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4124   PetscFunctionReturn(0);
4125 }
4126 
4127 /*@C
4128    MatConvert - Converts a matrix to another matrix, either of the same
4129    or different type.
4130 
4131    Collective on Mat
4132 
4133    Input Parameters:
4134 +  mat - the matrix
4135 .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
4136    same type as the original matrix.
4137 -  reuse - denotes if the destination matrix is to be created or reused.
4138    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
4139    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).
4140 
4141    Output Parameter:
4142 .  M - pointer to place new matrix
4143 
4144    Notes:
4145    MatConvert() first creates a new matrix and then copies the data from
4146    the first matrix.  A related routine is MatCopy(), which copies the matrix
4147    entries of one matrix to another already existing matrix context.
4148 
4149    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
4150    the MPI communicator of the generated matrix is always the same as the communicator
4151    of the input matrix.
4152 
4153    Level: intermediate
4154 
4155    Concepts: matrices^converting between storage formats
4156 
4157 .seealso: MatCopy(), MatDuplicate()
4158 @*/
4159 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
4160 {
4161   PetscErrorCode ierr;
4162   PetscBool      sametype,issame,flg;
4163   char           convname[256],mtype[256];
4164   Mat            B;
4165 
4166   PetscFunctionBegin;
4167   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4168   PetscValidType(mat,1);
4169   PetscValidPointer(M,3);
4170   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4171   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4172   MatCheckPreallocated(mat,1);
4173 
4174   ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
4175   if (flg) {
4176     newtype = mtype;
4177   }
4178   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
4179   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
4180   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
4181   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");
4182 
4183   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
4184 
4185   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4186     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4187   } else {
4188     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4189     const char     *prefix[3] = {"seq","mpi",""};
4190     PetscInt       i;
4191     /*
4192        Order of precedence:
4193        0) See if newtype is a superclass of the current matrix.
4194        1) See if a specialized converter is known to the current matrix.
4195        2) See if a specialized converter is known to the desired matrix class.
4196        3) See if a good general converter is registered for the desired class
4197           (as of 6/27/03 only MATMPIADJ falls into this category).
4198        4) See if a good general converter is known for the current matrix.
4199        5) Use a really basic converter.
4200     */
4201 
4202     /* 0) See if newtype is a superclass of the current matrix.
4203           i.e mat is mpiaij and newtype is aij */
4204     for (i=0; i<2; i++) {
4205       ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4206       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4207       ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr);
4208       if (flg) {
4209         if (reuse == MAT_INPLACE_MATRIX) {
4210           PetscFunctionReturn(0);
4211         } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) {
4212           ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
4213           PetscFunctionReturn(0);
4214         } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) {
4215           ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
4216           PetscFunctionReturn(0);
4217         }
4218       }
4219     }
4220     /* 1) See if a specialized converter is known to the current matrix and the desired class */
4221     for (i=0; i<3; i++) {
4222       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4223       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4224       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4225       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4226       ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr);
4227       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4228       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr);
4229       if (conv) goto foundconv;
4230     }
4231 
4232     /* 2)  See if a specialized converter is known to the desired matrix class. */
4233     ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr);
4234     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
4235     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
4236     for (i=0; i<3; i++) {
4237       ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr);
4238       ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr);
4239       ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr);
4240       ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr);
4241       ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr);
4242       ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr);
4243       ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr);
4244       if (conv) {
4245         ierr = MatDestroy(&B);CHKERRQ(ierr);
4246         goto foundconv;
4247       }
4248     }
4249 
4250     /* 3) See if a good general converter is registered for the desired class */
4251     conv = B->ops->convertfrom;
4252     ierr = MatDestroy(&B);CHKERRQ(ierr);
4253     if (conv) goto foundconv;
4254 
4255     /* 4) See if a good general converter is known for the current matrix */
4256     if (mat->ops->convert) {
4257       conv = mat->ops->convert;
4258     }
4259     if (conv) goto foundconv;
4260 
4261     /* 5) Use a really basic converter. */
4262     conv = MatConvert_Basic;
4263 
4264 foundconv:
4265     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4266     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
4267     if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) {
4268       /* the block sizes must be same if the mappings are copied over */
4269       (*M)->rmap->bs = mat->rmap->bs;
4270       (*M)->cmap->bs = mat->cmap->bs;
4271       ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr);
4272       ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr);
4273       (*M)->rmap->mapping = mat->rmap->mapping;
4274       (*M)->cmap->mapping = mat->cmap->mapping;
4275     }
4276     (*M)->stencil.dim = mat->stencil.dim;
4277     (*M)->stencil.noc = mat->stencil.noc;
4278     for (i=0; i<=mat->stencil.dim; i++) {
4279       (*M)->stencil.dims[i]   = mat->stencil.dims[i];
4280       (*M)->stencil.starts[i] = mat->stencil.starts[i];
4281     }
4282     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4283   }
4284   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
4285 
4286   /* Copy Mat options */
4287   if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
4288   if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
4289   PetscFunctionReturn(0);
4290 }
4291 
4292 /*@C
4293    MatFactorGetSolverType - Returns name of the package providing the factorization routines
4294 
4295    Not Collective
4296 
4297    Input Parameter:
4298 .  mat - the matrix, must be a factored matrix
4299 
4300    Output Parameter:
4301 .   type - the string name of the package (do not free this string)
4302 
4303    Notes:
4304       In Fortran you pass in a empty string and the package name will be copied into it.
4305     (Make sure the string is long enough)
4306 
4307    Level: intermediate
4308 
4309 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4310 @*/
4311 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type)
4312 {
4313   PetscErrorCode ierr, (*conv)(Mat,MatSolverType*);
4314 
4315   PetscFunctionBegin;
4316   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4317   PetscValidType(mat,1);
4318   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4319   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr);
4320   if (!conv) {
4321     *type = MATSOLVERPETSC;
4322   } else {
4323     ierr = (*conv)(mat,type);CHKERRQ(ierr);
4324   }
4325   PetscFunctionReturn(0);
4326 }
4327 
4328 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType;
4329 struct _MatSolverTypeForSpecifcType {
4330   MatType                        mtype;
4331   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
4332   MatSolverTypeForSpecifcType next;
4333 };
4334 
4335 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder;
4336 struct _MatSolverTypeHolder {
4337   char                           *name;
4338   MatSolverTypeForSpecifcType handlers;
4339   MatSolverTypeHolder         next;
4340 };
4341 
4342 static MatSolverTypeHolder MatSolverTypeHolders = NULL;
4343 
4344 /*@C
4345    MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type
4346 
4347    Input Parameters:
4348 +    package - name of the package, for example petsc or superlu
4349 .    mtype - the matrix type that works with this package
4350 .    ftype - the type of factorization supported by the package
4351 -    getfactor - routine that will create the factored matrix ready to be used
4352 
4353     Level: intermediate
4354 
4355 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4356 @*/
4357 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4358 {
4359   PetscErrorCode              ierr;
4360   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4361   PetscBool                   flg;
4362   MatSolverTypeForSpecifcType inext,iprev = NULL;
4363 
4364   PetscFunctionBegin;
4365   ierr = MatInitializePackage();CHKERRQ(ierr);
4366   if (!next) {
4367     ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr);
4368     ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr);
4369     ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr);
4370     ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr);
4371     MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4372     PetscFunctionReturn(0);
4373   }
4374   while (next) {
4375     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4376     if (flg) {
4377       if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers");
4378       inext = next->handlers;
4379       while (inext) {
4380         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4381         if (flg) {
4382           inext->getfactor[(int)ftype-1] = getfactor;
4383           PetscFunctionReturn(0);
4384         }
4385         iprev = inext;
4386         inext = inext->next;
4387       }
4388       ierr = PetscNew(&iprev->next);CHKERRQ(ierr);
4389       ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr);
4390       iprev->next->getfactor[(int)ftype-1] = getfactor;
4391       PetscFunctionReturn(0);
4392     }
4393     prev = next;
4394     next = next->next;
4395   }
4396   ierr = PetscNew(&prev->next);CHKERRQ(ierr);
4397   ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr);
4398   ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr);
4399   ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr);
4400   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4401   PetscFunctionReturn(0);
4402 }
4403 
4404 /*@C
4405    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4406 
4407    Input Parameters:
4408 +    package - name of the package, for example petsc or superlu
4409 .    ftype - the type of factorization supported by the package
4410 -    mtype - the matrix type that works with this package
4411 
4412    Output Parameters:
4413 +   foundpackage - PETSC_TRUE if the package was registered
4414 .   foundmtype - PETSC_TRUE if the package supports the requested mtype
4415 -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4416 
4417     Level: intermediate
4418 
4419 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4420 @*/
4421 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4422 {
4423   PetscErrorCode                 ierr;
4424   MatSolverTypeHolder         next = MatSolverTypeHolders;
4425   PetscBool                      flg;
4426   MatSolverTypeForSpecifcType inext;
4427 
4428   PetscFunctionBegin;
4429   if (foundpackage) *foundpackage = PETSC_FALSE;
4430   if (foundmtype)   *foundmtype   = PETSC_FALSE;
4431   if (getfactor)    *getfactor    = NULL;
4432 
4433   if (package) {
4434     while (next) {
4435       ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4436       if (flg) {
4437         if (foundpackage) *foundpackage = PETSC_TRUE;
4438         inext = next->handlers;
4439         while (inext) {
4440           ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4441           if (flg) {
4442             if (foundmtype) *foundmtype = PETSC_TRUE;
4443             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4444             PetscFunctionReturn(0);
4445           }
4446           inext = inext->next;
4447         }
4448       }
4449       next = next->next;
4450     }
4451   } else {
4452     while (next) {
4453       inext = next->handlers;
4454       while (inext) {
4455         ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4456         if (flg && inext->getfactor[(int)ftype-1]) {
4457           if (foundpackage) *foundpackage = PETSC_TRUE;
4458           if (foundmtype)   *foundmtype   = PETSC_TRUE;
4459           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
4460           PetscFunctionReturn(0);
4461         }
4462         inext = inext->next;
4463       }
4464       next = next->next;
4465     }
4466   }
4467   PetscFunctionReturn(0);
4468 }
4469 
4470 PetscErrorCode MatSolverTypeDestroy(void)
4471 {
4472   PetscErrorCode              ierr;
4473   MatSolverTypeHolder         next = MatSolverTypeHolders,prev;
4474   MatSolverTypeForSpecifcType inext,iprev;
4475 
4476   PetscFunctionBegin;
4477   while (next) {
4478     ierr = PetscFree(next->name);CHKERRQ(ierr);
4479     inext = next->handlers;
4480     while (inext) {
4481       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4482       iprev = inext;
4483       inext = inext->next;
4484       ierr = PetscFree(iprev);CHKERRQ(ierr);
4485     }
4486     prev = next;
4487     next = next->next;
4488     ierr = PetscFree(prev);CHKERRQ(ierr);
4489   }
4490   MatSolverTypeHolders = NULL;
4491   PetscFunctionReturn(0);
4492 }
4493 
4494 /*@C
4495    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4496 
4497    Collective on Mat
4498 
4499    Input Parameters:
4500 +  mat - the matrix
4501 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4502 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4503 
4504    Output Parameters:
4505 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4506 
4507    Notes:
4508       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4509      such as pastix, superlu, mumps etc.
4510 
4511       PETSc must have been ./configure to use the external solver, using the option --download-package
4512 
4513    Level: intermediate
4514 
4515 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4516 @*/
4517 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f)
4518 {
4519   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4520   PetscBool      foundpackage,foundmtype;
4521 
4522   PetscFunctionBegin;
4523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4524   PetscValidType(mat,1);
4525 
4526   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4527   MatCheckPreallocated(mat,1);
4528 
4529   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4530   if (!foundpackage) {
4531     if (type) {
4532       SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4533     } else {
4534       SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4535     }
4536   }
4537 
4538   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4539   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);
4540 
4541 #if defined(PETSC_USE_COMPLEX)
4542   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");
4543 #endif
4544 
4545   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4546   PetscFunctionReturn(0);
4547 }
4548 
4549 /*@C
4550    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4551 
4552    Not Collective
4553 
4554    Input Parameters:
4555 +  mat - the matrix
4556 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4557 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4558 
4559    Output Parameter:
4560 .    flg - PETSC_TRUE if the factorization is available
4561 
4562    Notes:
4563       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4564      such as pastix, superlu, mumps etc.
4565 
4566       PETSc must have been ./configure to use the external solver, using the option --download-package
4567 
4568    Level: intermediate
4569 
4570 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4571 @*/
4572 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool  *flg)
4573 {
4574   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4575 
4576   PetscFunctionBegin;
4577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4578   PetscValidType(mat,1);
4579 
4580   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4581   MatCheckPreallocated(mat,1);
4582 
4583   *flg = PETSC_FALSE;
4584   ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4585   if (gconv) {
4586     *flg = PETSC_TRUE;
4587   }
4588   PetscFunctionReturn(0);
4589 }
4590 
4591 #include <petscdmtypes.h>
4592 
4593 /*@
4594    MatDuplicate - Duplicates a matrix including the non-zero structure.
4595 
4596    Collective on Mat
4597 
4598    Input Parameters:
4599 +  mat - the matrix
4600 -  op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4601         See the manual page for MatDuplicateOption for an explanation of these options.
4602 
4603    Output Parameter:
4604 .  M - pointer to place new matrix
4605 
4606    Level: intermediate
4607 
4608    Concepts: matrices^duplicating
4609 
4610    Notes:
4611     You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4612     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.
4613 
4614 .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4615 @*/
4616 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4617 {
4618   PetscErrorCode ierr;
4619   Mat            B;
4620   PetscInt       i;
4621   DM             dm;
4622   void           (*viewf)(void);
4623 
4624   PetscFunctionBegin;
4625   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4626   PetscValidType(mat,1);
4627   PetscValidPointer(M,3);
4628   if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4629   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4630   MatCheckPreallocated(mat,1);
4631 
4632   *M = 0;
4633   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4634   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4635   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4636   B    = *M;
4637 
4638   ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr);
4639   if (viewf) {
4640     ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr);
4641   }
4642 
4643   B->stencil.dim = mat->stencil.dim;
4644   B->stencil.noc = mat->stencil.noc;
4645   for (i=0; i<=mat->stencil.dim; i++) {
4646     B->stencil.dims[i]   = mat->stencil.dims[i];
4647     B->stencil.starts[i] = mat->stencil.starts[i];
4648   }
4649 
4650   B->nooffproczerorows = mat->nooffproczerorows;
4651   B->nooffprocentries  = mat->nooffprocentries;
4652 
4653   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4654   if (dm) {
4655     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4656   }
4657   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4658   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4659   PetscFunctionReturn(0);
4660 }
4661 
4662 /*@
4663    MatGetDiagonal - Gets the diagonal of a matrix.
4664 
4665    Logically Collective on Mat and Vec
4666 
4667    Input Parameters:
4668 +  mat - the matrix
4669 -  v - the vector for storing the diagonal
4670 
4671    Output Parameter:
4672 .  v - the diagonal of the matrix
4673 
4674    Level: intermediate
4675 
4676    Note:
4677    Currently only correct in parallel for square matrices.
4678 
4679    Concepts: matrices^accessing diagonals
4680 
4681 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs()
4682 @*/
4683 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4684 {
4685   PetscErrorCode ierr;
4686 
4687   PetscFunctionBegin;
4688   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4689   PetscValidType(mat,1);
4690   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4691   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4692   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4693   MatCheckPreallocated(mat,1);
4694 
4695   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4696   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4697   PetscFunctionReturn(0);
4698 }
4699 
4700 /*@C
4701    MatGetRowMin - Gets the minimum value (of the real part) of each
4702         row of the matrix
4703 
4704    Logically Collective on Mat and Vec
4705 
4706    Input Parameters:
4707 .  mat - the matrix
4708 
4709    Output Parameter:
4710 +  v - the vector for storing the maximums
4711 -  idx - the indices of the column found for each row (optional)
4712 
4713    Level: intermediate
4714 
4715    Notes:
4716     The result of this call are the same as if one converted the matrix to dense format
4717       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4718 
4719     This code is only implemented for a couple of matrix formats.
4720 
4721    Concepts: matrices^getting row maximums
4722 
4723 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(),
4724           MatGetRowMax()
4725 @*/
4726 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4727 {
4728   PetscErrorCode ierr;
4729 
4730   PetscFunctionBegin;
4731   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4732   PetscValidType(mat,1);
4733   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4734   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4735   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4736   MatCheckPreallocated(mat,1);
4737 
4738   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4739   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4740   PetscFunctionReturn(0);
4741 }
4742 
4743 /*@C
4744    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4745         row of the matrix
4746 
4747    Logically Collective on Mat and Vec
4748 
4749    Input Parameters:
4750 .  mat - the matrix
4751 
4752    Output Parameter:
4753 +  v - the vector for storing the minimums
4754 -  idx - the indices of the column found for each row (or NULL if not needed)
4755 
4756    Level: intermediate
4757 
4758    Notes:
4759     if a row is completely empty or has only 0.0 values then the idx[] value for that
4760     row is 0 (the first column).
4761 
4762     This code is only implemented for a couple of matrix formats.
4763 
4764    Concepts: matrices^getting row maximums
4765 
4766 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4767 @*/
4768 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4769 {
4770   PetscErrorCode ierr;
4771 
4772   PetscFunctionBegin;
4773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4774   PetscValidType(mat,1);
4775   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4776   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4777   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4778   MatCheckPreallocated(mat,1);
4779   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4780 
4781   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4782   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4783   PetscFunctionReturn(0);
4784 }
4785 
4786 /*@C
4787    MatGetRowMax - Gets the maximum value (of the real part) of each
4788         row of the matrix
4789 
4790    Logically Collective on Mat and Vec
4791 
4792    Input Parameters:
4793 .  mat - the matrix
4794 
4795    Output Parameter:
4796 +  v - the vector for storing the maximums
4797 -  idx - the indices of the column found for each row (optional)
4798 
4799    Level: intermediate
4800 
4801    Notes:
4802     The result of this call are the same as if one converted the matrix to dense format
4803       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4804 
4805     This code is only implemented for a couple of matrix formats.
4806 
4807    Concepts: matrices^getting row maximums
4808 
4809 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4810 @*/
4811 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4812 {
4813   PetscErrorCode ierr;
4814 
4815   PetscFunctionBegin;
4816   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4817   PetscValidType(mat,1);
4818   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4819   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4820   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4821   MatCheckPreallocated(mat,1);
4822 
4823   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4824   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4825   PetscFunctionReturn(0);
4826 }
4827 
4828 /*@C
4829    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4830         row of the matrix
4831 
4832    Logically Collective on Mat and Vec
4833 
4834    Input Parameters:
4835 .  mat - the matrix
4836 
4837    Output Parameter:
4838 +  v - the vector for storing the maximums
4839 -  idx - the indices of the column found for each row (or NULL if not needed)
4840 
4841    Level: intermediate
4842 
4843    Notes:
4844     if a row is completely empty or has only 0.0 values then the idx[] value for that
4845     row is 0 (the first column).
4846 
4847     This code is only implemented for a couple of matrix formats.
4848 
4849    Concepts: matrices^getting row maximums
4850 
4851 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4852 @*/
4853 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4854 {
4855   PetscErrorCode ierr;
4856 
4857   PetscFunctionBegin;
4858   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4859   PetscValidType(mat,1);
4860   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4861   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4862   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4863   MatCheckPreallocated(mat,1);
4864   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4865 
4866   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4867   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4868   PetscFunctionReturn(0);
4869 }
4870 
4871 /*@
4872    MatGetRowSum - Gets the sum of each row of the matrix
4873 
4874    Logically or Neighborhood Collective on Mat and Vec
4875 
4876    Input Parameters:
4877 .  mat - the matrix
4878 
4879    Output Parameter:
4880 .  v - the vector for storing the sum of rows
4881 
4882    Level: intermediate
4883 
4884    Notes:
4885     This code is slow since it is not currently specialized for different formats
4886 
4887    Concepts: matrices^getting row sums
4888 
4889 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin()
4890 @*/
4891 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4892 {
4893   Vec            ones;
4894   PetscErrorCode ierr;
4895 
4896   PetscFunctionBegin;
4897   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4898   PetscValidType(mat,1);
4899   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4900   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4901   MatCheckPreallocated(mat,1);
4902   ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr);
4903   ierr = VecSet(ones,1.);CHKERRQ(ierr);
4904   ierr = MatMult(mat,ones,v);CHKERRQ(ierr);
4905   ierr = VecDestroy(&ones);CHKERRQ(ierr);
4906   PetscFunctionReturn(0);
4907 }
4908 
4909 /*@
4910    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4911 
4912    Collective on Mat
4913 
4914    Input Parameter:
4915 +  mat - the matrix to transpose
4916 -  reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4917 
4918    Output Parameters:
4919 .  B - the transpose
4920 
4921    Notes:
4922      If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4923 
4924      MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4925 
4926      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4927 
4928    Level: intermediate
4929 
4930    Concepts: matrices^transposing
4931 
4932 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4933 @*/
4934 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4935 {
4936   PetscErrorCode ierr;
4937 
4938   PetscFunctionBegin;
4939   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4940   PetscValidType(mat,1);
4941   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4942   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4943   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4944   if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4945   if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4946   MatCheckPreallocated(mat,1);
4947 
4948   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4949   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4950   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4951   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4952   PetscFunctionReturn(0);
4953 }
4954 
4955 /*@
4956    MatIsTranspose - Test whether a matrix is another one's transpose,
4957         or its own, in which case it tests symmetry.
4958 
4959    Collective on Mat
4960 
4961    Input Parameter:
4962 +  A - the matrix to test
4963 -  B - the matrix to test against, this can equal the first parameter
4964 
4965    Output Parameters:
4966 .  flg - the result
4967 
4968    Notes:
4969    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4970    has a running time of the order of the number of nonzeros; the parallel
4971    test involves parallel copies of the block-offdiagonal parts of the matrix.
4972 
4973    Level: intermediate
4974 
4975    Concepts: matrices^transposing, matrix^symmetry
4976 
4977 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4978 @*/
4979 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4980 {
4981   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4982 
4983   PetscFunctionBegin;
4984   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4985   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4986   PetscValidPointer(flg,3);
4987   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4988   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4989   *flg = PETSC_FALSE;
4990   if (f && g) {
4991     if (f == g) {
4992       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4993     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4994   } else {
4995     MatType mattype;
4996     if (!f) {
4997       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4998     } else {
4999       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
5000     }
5001     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
5002   }
5003   PetscFunctionReturn(0);
5004 }
5005 
5006 /*@
5007    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
5008 
5009    Collective on Mat
5010 
5011    Input Parameter:
5012 +  mat - the matrix to transpose and complex conjugate
5013 -  reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
5014 
5015    Output Parameters:
5016 .  B - the Hermitian
5017 
5018    Level: intermediate
5019 
5020    Concepts: matrices^transposing, complex conjugatex
5021 
5022 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
5023 @*/
5024 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
5025 {
5026   PetscErrorCode ierr;
5027 
5028   PetscFunctionBegin;
5029   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
5030 #if defined(PETSC_USE_COMPLEX)
5031   ierr = MatConjugate(*B);CHKERRQ(ierr);
5032 #endif
5033   PetscFunctionReturn(0);
5034 }
5035 
5036 /*@
5037    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
5038 
5039    Collective on Mat
5040 
5041    Input Parameter:
5042 +  A - the matrix to test
5043 -  B - the matrix to test against, this can equal the first parameter
5044 
5045    Output Parameters:
5046 .  flg - the result
5047 
5048    Notes:
5049    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
5050    has a running time of the order of the number of nonzeros; the parallel
5051    test involves parallel copies of the block-offdiagonal parts of the matrix.
5052 
5053    Level: intermediate
5054 
5055    Concepts: matrices^transposing, matrix^symmetry
5056 
5057 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
5058 @*/
5059 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
5060 {
5061   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
5062 
5063   PetscFunctionBegin;
5064   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5065   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5066   PetscValidPointer(flg,3);
5067   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
5068   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
5069   if (f && g) {
5070     if (f==g) {
5071       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
5072     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
5073   }
5074   PetscFunctionReturn(0);
5075 }
5076 
5077 /*@
5078    MatPermute - Creates a new matrix with rows and columns permuted from the
5079    original.
5080 
5081    Collective on Mat
5082 
5083    Input Parameters:
5084 +  mat - the matrix to permute
5085 .  row - row permutation, each processor supplies only the permutation for its rows
5086 -  col - column permutation, each processor supplies only the permutation for its columns
5087 
5088    Output Parameters:
5089 .  B - the permuted matrix
5090 
5091    Level: advanced
5092 
5093    Note:
5094    The index sets map from row/col of permuted matrix to row/col of original matrix.
5095    The index sets should be on the same communicator as Mat and have the same local sizes.
5096 
5097    Concepts: matrices^permuting
5098 
5099 .seealso: MatGetOrdering(), ISAllGather()
5100 
5101 @*/
5102 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
5103 {
5104   PetscErrorCode ierr;
5105 
5106   PetscFunctionBegin;
5107   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5108   PetscValidType(mat,1);
5109   PetscValidHeaderSpecific(row,IS_CLASSID,2);
5110   PetscValidHeaderSpecific(col,IS_CLASSID,3);
5111   PetscValidPointer(B,4);
5112   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5113   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5114   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
5115   MatCheckPreallocated(mat,1);
5116 
5117   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
5118   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
5119   PetscFunctionReturn(0);
5120 }
5121 
5122 /*@
5123    MatEqual - Compares two matrices.
5124 
5125    Collective on Mat
5126 
5127    Input Parameters:
5128 +  A - the first matrix
5129 -  B - the second matrix
5130 
5131    Output Parameter:
5132 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
5133 
5134    Level: intermediate
5135 
5136    Concepts: matrices^equality between
5137 @*/
5138 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
5139 {
5140   PetscErrorCode ierr;
5141 
5142   PetscFunctionBegin;
5143   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
5144   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
5145   PetscValidType(A,1);
5146   PetscValidType(B,2);
5147   PetscValidIntPointer(flg,3);
5148   PetscCheckSameComm(A,1,B,2);
5149   MatCheckPreallocated(B,2);
5150   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5151   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5152   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);
5153   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
5154   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
5155   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);
5156   MatCheckPreallocated(A,1);
5157 
5158   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
5159   PetscFunctionReturn(0);
5160 }
5161 
5162 /*@
5163    MatDiagonalScale - Scales a matrix on the left and right by diagonal
5164    matrices that are stored as vectors.  Either of the two scaling
5165    matrices can be NULL.
5166 
5167    Collective on Mat
5168 
5169    Input Parameters:
5170 +  mat - the matrix to be scaled
5171 .  l - the left scaling vector (or NULL)
5172 -  r - the right scaling vector (or NULL)
5173 
5174    Notes:
5175    MatDiagonalScale() computes A = LAR, where
5176    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
5177    The L scales the rows of the matrix, the R scales the columns of the matrix.
5178 
5179    Level: intermediate
5180 
5181    Concepts: matrices^diagonal scaling
5182    Concepts: diagonal scaling of matrices
5183 
5184 .seealso: MatScale(), MatShift(), MatDiagonalSet()
5185 @*/
5186 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
5187 {
5188   PetscErrorCode ierr;
5189 
5190   PetscFunctionBegin;
5191   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5192   PetscValidType(mat,1);
5193   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5194   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
5195   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
5196   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5197   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5198   MatCheckPreallocated(mat,1);
5199 
5200   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5201   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
5202   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5203   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5204 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5205   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5206     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5207   }
5208 #endif
5209   PetscFunctionReturn(0);
5210 }
5211 
5212 /*@
5213     MatScale - Scales all elements of a matrix by a given number.
5214 
5215     Logically Collective on Mat
5216 
5217     Input Parameters:
5218 +   mat - the matrix to be scaled
5219 -   a  - the scaling value
5220 
5221     Output Parameter:
5222 .   mat - the scaled matrix
5223 
5224     Level: intermediate
5225 
5226     Concepts: matrices^scaling all entries
5227 
5228 .seealso: MatDiagonalScale()
5229 @*/
5230 PetscErrorCode MatScale(Mat mat,PetscScalar a)
5231 {
5232   PetscErrorCode ierr;
5233 
5234   PetscFunctionBegin;
5235   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5236   PetscValidType(mat,1);
5237   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5238   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5239   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5240   PetscValidLogicalCollectiveScalar(mat,a,2);
5241   MatCheckPreallocated(mat,1);
5242 
5243   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5244   if (a != (PetscScalar)1.0) {
5245     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
5246     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5247 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5248     if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5249       mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5250     }
5251 #endif
5252   }
5253   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5254   PetscFunctionReturn(0);
5255 }
5256 
5257 /*@
5258    MatNorm - Calculates various norms of a matrix.
5259 
5260    Collective on Mat
5261 
5262    Input Parameters:
5263 +  mat - the matrix
5264 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5265 
5266    Output Parameters:
5267 .  nrm - the resulting norm
5268 
5269    Level: intermediate
5270 
5271    Concepts: matrices^norm
5272    Concepts: norm^of matrix
5273 @*/
5274 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5275 {
5276   PetscErrorCode ierr;
5277 
5278   PetscFunctionBegin;
5279   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5280   PetscValidType(mat,1);
5281   PetscValidScalarPointer(nrm,3);
5282 
5283   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5284   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5285   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5286   MatCheckPreallocated(mat,1);
5287 
5288   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
5289   PetscFunctionReturn(0);
5290 }
5291 
5292 /*
5293      This variable is used to prevent counting of MatAssemblyBegin() that
5294    are called from within a MatAssemblyEnd().
5295 */
5296 static PetscInt MatAssemblyEnd_InUse = 0;
5297 /*@
5298    MatAssemblyBegin - Begins assembling the matrix.  This routine should
5299    be called after completing all calls to MatSetValues().
5300 
5301    Collective on Mat
5302 
5303    Input Parameters:
5304 +  mat - the matrix
5305 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5306 
5307    Notes:
5308    MatSetValues() generally caches the values.  The matrix is ready to
5309    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5310    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5311    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5312    using the matrix.
5313 
5314    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5315    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
5316    a global collective operation requring all processes that share the matrix.
5317 
5318    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5319    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5320    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5321 
5322    Level: beginner
5323 
5324    Concepts: matrices^assembling
5325 
5326 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5327 @*/
5328 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5329 {
5330   PetscErrorCode ierr;
5331 
5332   PetscFunctionBegin;
5333   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5334   PetscValidType(mat,1);
5335   MatCheckPreallocated(mat,1);
5336   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5337   if (mat->assembled) {
5338     mat->was_assembled = PETSC_TRUE;
5339     mat->assembled     = PETSC_FALSE;
5340   }
5341   if (!MatAssemblyEnd_InUse) {
5342     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5343     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5344     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5345   } else if (mat->ops->assemblybegin) {
5346     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5347   }
5348   PetscFunctionReturn(0);
5349 }
5350 
5351 /*@
5352    MatAssembled - Indicates if a matrix has been assembled and is ready for
5353      use; for example, in matrix-vector product.
5354 
5355    Not Collective
5356 
5357    Input Parameter:
5358 .  mat - the matrix
5359 
5360    Output Parameter:
5361 .  assembled - PETSC_TRUE or PETSC_FALSE
5362 
5363    Level: advanced
5364 
5365    Concepts: matrices^assembled?
5366 
5367 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5368 @*/
5369 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5370 {
5371   PetscFunctionBegin;
5372   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5373   PetscValidPointer(assembled,2);
5374   *assembled = mat->assembled;
5375   PetscFunctionReturn(0);
5376 }
5377 
5378 /*@
5379    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5380    be called after MatAssemblyBegin().
5381 
5382    Collective on Mat
5383 
5384    Input Parameters:
5385 +  mat - the matrix
5386 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5387 
5388    Options Database Keys:
5389 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5390 .  -mat_view ::ascii_info_detail - Prints more detailed info
5391 .  -mat_view - Prints matrix in ASCII format
5392 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5393 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5394 .  -display <name> - Sets display name (default is host)
5395 .  -draw_pause <sec> - Sets number of seconds to pause after display
5396 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5397 .  -viewer_socket_machine <machine> - Machine to use for socket
5398 .  -viewer_socket_port <port> - Port number to use for socket
5399 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5400 
5401    Notes:
5402    MatSetValues() generally caches the values.  The matrix is ready to
5403    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5404    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5405    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5406    using the matrix.
5407 
5408    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5409    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5410    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5411 
5412    Level: beginner
5413 
5414 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5415 @*/
5416 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5417 {
5418   PetscErrorCode  ierr;
5419   static PetscInt inassm = 0;
5420   PetscBool       flg    = PETSC_FALSE;
5421 
5422   PetscFunctionBegin;
5423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5424   PetscValidType(mat,1);
5425 
5426   inassm++;
5427   MatAssemblyEnd_InUse++;
5428   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5429     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5430     if (mat->ops->assemblyend) {
5431       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5432     }
5433     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5434   } else if (mat->ops->assemblyend) {
5435     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5436   }
5437 
5438   /* Flush assembly is not a true assembly */
5439   if (type != MAT_FLUSH_ASSEMBLY) {
5440     mat->assembled = PETSC_TRUE; mat->num_ass++;
5441   }
5442   mat->insertmode = NOT_SET_VALUES;
5443   MatAssemblyEnd_InUse--;
5444   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5445   if (!mat->symmetric_eternal) {
5446     mat->symmetric_set              = PETSC_FALSE;
5447     mat->hermitian_set              = PETSC_FALSE;
5448     mat->structurally_symmetric_set = PETSC_FALSE;
5449   }
5450 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5451   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5452     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5453   }
5454 #endif
5455   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5456     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5457 
5458     if (mat->checksymmetryonassembly) {
5459       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5460       if (flg) {
5461         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5462       } else {
5463         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5464       }
5465     }
5466     if (mat->nullsp && mat->checknullspaceonassembly) {
5467       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5468     }
5469   }
5470   inassm--;
5471   PetscFunctionReturn(0);
5472 }
5473 
5474 /*@
5475    MatSetOption - Sets a parameter option for a matrix. Some options
5476    may be specific to certain storage formats.  Some options
5477    determine how values will be inserted (or added). Sorted,
5478    row-oriented input will generally assemble the fastest. The default
5479    is row-oriented.
5480 
5481    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5482 
5483    Input Parameters:
5484 +  mat - the matrix
5485 .  option - the option, one of those listed below (and possibly others),
5486 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5487 
5488   Options Describing Matrix Structure:
5489 +    MAT_SPD - symmetric positive definite
5490 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5491 .    MAT_HERMITIAN - transpose is the complex conjugation
5492 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5493 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5494                             you set to be kept with all future use of the matrix
5495                             including after MatAssemblyBegin/End() which could
5496                             potentially change the symmetry structure, i.e. you
5497                             KNOW the matrix will ALWAYS have the property you set.
5498 
5499 
5500    Options For Use with MatSetValues():
5501    Insert a logically dense subblock, which can be
5502 .    MAT_ROW_ORIENTED - row-oriented (default)
5503 
5504    Note these options reflect the data you pass in with MatSetValues(); it has
5505    nothing to do with how the data is stored internally in the matrix
5506    data structure.
5507 
5508    When (re)assembling a matrix, we can restrict the input for
5509    efficiency/debugging purposes.  These options include:
5510 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5511 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5512 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5513 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5514 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5515 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5516         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5517         performance for very large process counts.
5518 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5519         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5520         functions, instead sending only neighbor messages.
5521 
5522    Notes:
5523    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5524 
5525    Some options are relevant only for particular matrix types and
5526    are thus ignored by others.  Other options are not supported by
5527    certain matrix types and will generate an error message if set.
5528 
5529    If using a Fortran 77 module to compute a matrix, one may need to
5530    use the column-oriented option (or convert to the row-oriented
5531    format).
5532 
5533    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5534    that would generate a new entry in the nonzero structure is instead
5535    ignored.  Thus, if memory has not alredy been allocated for this particular
5536    data, then the insertion is ignored. For dense matrices, in which
5537    the entire array is allocated, no entries are ever ignored.
5538    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5539 
5540    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5541    that would generate a new entry in the nonzero structure instead produces
5542    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
5543 
5544    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5545    that would generate a new entry that has not been preallocated will
5546    instead produce an error. (Currently supported for AIJ and BAIJ formats
5547    only.) This is a useful flag when debugging matrix memory preallocation.
5548    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5549 
5550    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5551    other processors should be dropped, rather than stashed.
5552    This is useful if you know that the "owning" processor is also
5553    always generating the correct matrix entries, so that PETSc need
5554    not transfer duplicate entries generated on another processor.
5555 
5556    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5557    searches during matrix assembly. When this flag is set, the hash table
5558    is created during the first Matrix Assembly. This hash table is
5559    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5560    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5561    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5562    supported by MATMPIBAIJ format only.
5563 
5564    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5565    are kept in the nonzero structure
5566 
5567    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5568    a zero location in the matrix
5569 
5570    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5571 
5572    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5573         zero row routines and thus improves performance for very large process counts.
5574 
5575    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5576         part of the matrix (since they should match the upper triangular part).
5577 
5578    Notes:
5579     Can only be called after MatSetSizes() and MatSetType() have been set.
5580 
5581    Level: intermediate
5582 
5583    Concepts: matrices^setting options
5584 
5585 .seealso:  MatOption, Mat
5586 
5587 @*/
5588 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5589 {
5590   PetscErrorCode ierr;
5591 
5592   PetscFunctionBegin;
5593   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5594   PetscValidType(mat,1);
5595   if (op > 0) {
5596     PetscValidLogicalCollectiveEnum(mat,op,2);
5597     PetscValidLogicalCollectiveBool(mat,flg,3);
5598   }
5599 
5600   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);
5601   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()");
5602 
5603   switch (op) {
5604   case MAT_NO_OFF_PROC_ENTRIES:
5605     mat->nooffprocentries = flg;
5606     PetscFunctionReturn(0);
5607     break;
5608   case MAT_SUBSET_OFF_PROC_ENTRIES:
5609     mat->subsetoffprocentries = flg;
5610     PetscFunctionReturn(0);
5611   case MAT_NO_OFF_PROC_ZERO_ROWS:
5612     mat->nooffproczerorows = flg;
5613     PetscFunctionReturn(0);
5614     break;
5615   case MAT_SPD:
5616     mat->spd_set = PETSC_TRUE;
5617     mat->spd     = flg;
5618     if (flg) {
5619       mat->symmetric                  = PETSC_TRUE;
5620       mat->structurally_symmetric     = PETSC_TRUE;
5621       mat->symmetric_set              = PETSC_TRUE;
5622       mat->structurally_symmetric_set = PETSC_TRUE;
5623     }
5624     break;
5625   case MAT_SYMMETRIC:
5626     mat->symmetric = flg;
5627     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5628     mat->symmetric_set              = PETSC_TRUE;
5629     mat->structurally_symmetric_set = flg;
5630 #if !defined(PETSC_USE_COMPLEX)
5631     mat->hermitian     = flg;
5632     mat->hermitian_set = PETSC_TRUE;
5633 #endif
5634     break;
5635   case MAT_HERMITIAN:
5636     mat->hermitian = flg;
5637     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5638     mat->hermitian_set              = PETSC_TRUE;
5639     mat->structurally_symmetric_set = flg;
5640 #if !defined(PETSC_USE_COMPLEX)
5641     mat->symmetric     = flg;
5642     mat->symmetric_set = PETSC_TRUE;
5643 #endif
5644     break;
5645   case MAT_STRUCTURALLY_SYMMETRIC:
5646     mat->structurally_symmetric     = flg;
5647     mat->structurally_symmetric_set = PETSC_TRUE;
5648     break;
5649   case MAT_SYMMETRY_ETERNAL:
5650     mat->symmetric_eternal = flg;
5651     break;
5652   case MAT_STRUCTURE_ONLY:
5653     mat->structure_only = flg;
5654     break;
5655   default:
5656     break;
5657   }
5658   if (mat->ops->setoption) {
5659     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5660   }
5661   PetscFunctionReturn(0);
5662 }
5663 
5664 /*@
5665    MatGetOption - Gets a parameter option that has been set for a matrix.
5666 
5667    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5668 
5669    Input Parameters:
5670 +  mat - the matrix
5671 -  option - the option, this only responds to certain options, check the code for which ones
5672 
5673    Output Parameter:
5674 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5675 
5676     Notes:
5677     Can only be called after MatSetSizes() and MatSetType() have been set.
5678 
5679    Level: intermediate
5680 
5681    Concepts: matrices^setting options
5682 
5683 .seealso:  MatOption, MatSetOption()
5684 
5685 @*/
5686 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5687 {
5688   PetscFunctionBegin;
5689   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5690   PetscValidType(mat,1);
5691 
5692   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);
5693   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()");
5694 
5695   switch (op) {
5696   case MAT_NO_OFF_PROC_ENTRIES:
5697     *flg = mat->nooffprocentries;
5698     break;
5699   case MAT_NO_OFF_PROC_ZERO_ROWS:
5700     *flg = mat->nooffproczerorows;
5701     break;
5702   case MAT_SYMMETRIC:
5703     *flg = mat->symmetric;
5704     break;
5705   case MAT_HERMITIAN:
5706     *flg = mat->hermitian;
5707     break;
5708   case MAT_STRUCTURALLY_SYMMETRIC:
5709     *flg = mat->structurally_symmetric;
5710     break;
5711   case MAT_SYMMETRY_ETERNAL:
5712     *flg = mat->symmetric_eternal;
5713     break;
5714   case MAT_SPD:
5715     *flg = mat->spd;
5716     break;
5717   default:
5718     break;
5719   }
5720   PetscFunctionReturn(0);
5721 }
5722 
5723 /*@
5724    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5725    this routine retains the old nonzero structure.
5726 
5727    Logically Collective on Mat
5728 
5729    Input Parameters:
5730 .  mat - the matrix
5731 
5732    Level: intermediate
5733 
5734    Notes:
5735     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.
5736    See the Performance chapter of the users manual for information on preallocating matrices.
5737 
5738    Concepts: matrices^zeroing
5739 
5740 .seealso: MatZeroRows()
5741 @*/
5742 PetscErrorCode MatZeroEntries(Mat mat)
5743 {
5744   PetscErrorCode ierr;
5745 
5746   PetscFunctionBegin;
5747   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5748   PetscValidType(mat,1);
5749   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5750   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");
5751   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5752   MatCheckPreallocated(mat,1);
5753 
5754   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5755   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5756   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5757   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5758 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5759   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5760     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5761   }
5762 #endif
5763   PetscFunctionReturn(0);
5764 }
5765 
5766 /*@
5767    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5768    of a set of rows and columns of a matrix.
5769 
5770    Collective on Mat
5771 
5772    Input Parameters:
5773 +  mat - the matrix
5774 .  numRows - the number of rows to remove
5775 .  rows - the global row indices
5776 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5777 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5778 -  b - optional vector of right hand side, that will be adjusted by provided solution
5779 
5780    Notes:
5781    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5782 
5783    The user can set a value in the diagonal entry (or for the AIJ and
5784    row formats can optionally remove the main diagonal entry from the
5785    nonzero structure as well, by passing 0.0 as the final argument).
5786 
5787    For the parallel case, all processes that share the matrix (i.e.,
5788    those in the communicator used for matrix creation) MUST call this
5789    routine, regardless of whether any rows being zeroed are owned by
5790    them.
5791 
5792    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5793    list only rows local to itself).
5794 
5795    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5796 
5797    Level: intermediate
5798 
5799    Concepts: matrices^zeroing rows
5800 
5801 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5802           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5803 @*/
5804 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5805 {
5806   PetscErrorCode ierr;
5807 
5808   PetscFunctionBegin;
5809   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5810   PetscValidType(mat,1);
5811   if (numRows) PetscValidIntPointer(rows,3);
5812   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5813   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5814   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5815   MatCheckPreallocated(mat,1);
5816 
5817   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5818   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5819   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5820 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5821   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5822     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5823   }
5824 #endif
5825   PetscFunctionReturn(0);
5826 }
5827 
5828 /*@
5829    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5830    of a set of rows and columns of a matrix.
5831 
5832    Collective on Mat
5833 
5834    Input Parameters:
5835 +  mat - the matrix
5836 .  is - the rows to zero
5837 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5838 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5839 -  b - optional vector of right hand side, that will be adjusted by provided solution
5840 
5841    Notes:
5842    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5843 
5844    The user can set a value in the diagonal entry (or for the AIJ and
5845    row formats can optionally remove the main diagonal entry from the
5846    nonzero structure as well, by passing 0.0 as the final argument).
5847 
5848    For the parallel case, all processes that share the matrix (i.e.,
5849    those in the communicator used for matrix creation) MUST call this
5850    routine, regardless of whether any rows being zeroed are owned by
5851    them.
5852 
5853    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5854    list only rows local to itself).
5855 
5856    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5857 
5858    Level: intermediate
5859 
5860    Concepts: matrices^zeroing rows
5861 
5862 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5863           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5864 @*/
5865 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5866 {
5867   PetscErrorCode ierr;
5868   PetscInt       numRows;
5869   const PetscInt *rows;
5870 
5871   PetscFunctionBegin;
5872   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5873   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5874   PetscValidType(mat,1);
5875   PetscValidType(is,2);
5876   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5877   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5878   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5879   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5880   PetscFunctionReturn(0);
5881 }
5882 
5883 /*@
5884    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5885    of a set of rows of a matrix.
5886 
5887    Collective on Mat
5888 
5889    Input Parameters:
5890 +  mat - the matrix
5891 .  numRows - the number of rows to remove
5892 .  rows - the global row indices
5893 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5894 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5895 -  b - optional vector of right hand side, that will be adjusted by provided solution
5896 
5897    Notes:
5898    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5899    but does not release memory.  For the dense and block diagonal
5900    formats this does not alter the nonzero structure.
5901 
5902    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5903    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5904    merely zeroed.
5905 
5906    The user can set a value in the diagonal entry (or for the AIJ and
5907    row formats can optionally remove the main diagonal entry from the
5908    nonzero structure as well, by passing 0.0 as the final argument).
5909 
5910    For the parallel case, all processes that share the matrix (i.e.,
5911    those in the communicator used for matrix creation) MUST call this
5912    routine, regardless of whether any rows being zeroed are owned by
5913    them.
5914 
5915    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5916    list only rows local to itself).
5917 
5918    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5919    owns that are to be zeroed. This saves a global synchronization in the implementation.
5920 
5921    Level: intermediate
5922 
5923    Concepts: matrices^zeroing rows
5924 
5925 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5926           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5927 @*/
5928 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5929 {
5930   PetscErrorCode ierr;
5931 
5932   PetscFunctionBegin;
5933   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5934   PetscValidType(mat,1);
5935   if (numRows) PetscValidIntPointer(rows,3);
5936   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5937   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5938   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5939   MatCheckPreallocated(mat,1);
5940 
5941   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5942   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5943   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5944 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
5945   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
5946     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
5947   }
5948 #endif
5949   PetscFunctionReturn(0);
5950 }
5951 
5952 /*@
5953    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5954    of a set of rows of a matrix.
5955 
5956    Collective on Mat
5957 
5958    Input Parameters:
5959 +  mat - the matrix
5960 .  is - index set of rows to remove
5961 .  diag - value put in all diagonals of eliminated rows
5962 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5963 -  b - optional vector of right hand side, that will be adjusted by provided solution
5964 
5965    Notes:
5966    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5967    but does not release memory.  For the dense and block diagonal
5968    formats this does not alter the nonzero structure.
5969 
5970    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5971    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5972    merely zeroed.
5973 
5974    The user can set a value in the diagonal entry (or for the AIJ and
5975    row formats can optionally remove the main diagonal entry from the
5976    nonzero structure as well, by passing 0.0 as the final argument).
5977 
5978    For the parallel case, all processes that share the matrix (i.e.,
5979    those in the communicator used for matrix creation) MUST call this
5980    routine, regardless of whether any rows being zeroed are owned by
5981    them.
5982 
5983    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5984    list only rows local to itself).
5985 
5986    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5987    owns that are to be zeroed. This saves a global synchronization in the implementation.
5988 
5989    Level: intermediate
5990 
5991    Concepts: matrices^zeroing rows
5992 
5993 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5994           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5995 @*/
5996 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5997 {
5998   PetscInt       numRows;
5999   const PetscInt *rows;
6000   PetscErrorCode ierr;
6001 
6002   PetscFunctionBegin;
6003   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6004   PetscValidType(mat,1);
6005   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6006   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6007   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6008   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6009   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6010   PetscFunctionReturn(0);
6011 }
6012 
6013 /*@
6014    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
6015    of a set of rows of a matrix. These rows must be local to the process.
6016 
6017    Collective on Mat
6018 
6019    Input Parameters:
6020 +  mat - the matrix
6021 .  numRows - the number of rows to remove
6022 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6023 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6024 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6025 -  b - optional vector of right hand side, that will be adjusted by provided solution
6026 
6027    Notes:
6028    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6029    but does not release memory.  For the dense and block diagonal
6030    formats this does not alter the nonzero structure.
6031 
6032    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6033    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6034    merely zeroed.
6035 
6036    The user can set a value in the diagonal entry (or for the AIJ and
6037    row formats can optionally remove the main diagonal entry from the
6038    nonzero structure as well, by passing 0.0 as the final argument).
6039 
6040    For the parallel case, all processes that share the matrix (i.e.,
6041    those in the communicator used for matrix creation) MUST call this
6042    routine, regardless of whether any rows being zeroed are owned by
6043    them.
6044 
6045    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6046    list only rows local to itself).
6047 
6048    The grid coordinates are across the entire grid, not just the local portion
6049 
6050    In Fortran idxm and idxn should be declared as
6051 $     MatStencil idxm(4,m)
6052    and the values inserted using
6053 $    idxm(MatStencil_i,1) = i
6054 $    idxm(MatStencil_j,1) = j
6055 $    idxm(MatStencil_k,1) = k
6056 $    idxm(MatStencil_c,1) = c
6057    etc
6058 
6059    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6060    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6061    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6062    DM_BOUNDARY_PERIODIC boundary type.
6063 
6064    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
6065    a single value per point) you can skip filling those indices.
6066 
6067    Level: intermediate
6068 
6069    Concepts: matrices^zeroing rows
6070 
6071 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6072           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6073 @*/
6074 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6075 {
6076   PetscInt       dim     = mat->stencil.dim;
6077   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6078   PetscInt       *dims   = mat->stencil.dims+1;
6079   PetscInt       *starts = mat->stencil.starts;
6080   PetscInt       *dxm    = (PetscInt*) rows;
6081   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6082   PetscErrorCode ierr;
6083 
6084   PetscFunctionBegin;
6085   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6086   PetscValidType(mat,1);
6087   if (numRows) PetscValidIntPointer(rows,3);
6088 
6089   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6090   for (i = 0; i < numRows; ++i) {
6091     /* Skip unused dimensions (they are ordered k, j, i, c) */
6092     for (j = 0; j < 3-sdim; ++j) dxm++;
6093     /* Local index in X dir */
6094     tmp = *dxm++ - starts[0];
6095     /* Loop over remaining dimensions */
6096     for (j = 0; j < dim-1; ++j) {
6097       /* If nonlocal, set index to be negative */
6098       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6099       /* Update local index */
6100       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6101     }
6102     /* Skip component slot if necessary */
6103     if (mat->stencil.noc) dxm++;
6104     /* Local row number */
6105     if (tmp >= 0) {
6106       jdxm[numNewRows++] = tmp;
6107     }
6108   }
6109   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6110   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6111   PetscFunctionReturn(0);
6112 }
6113 
6114 /*@
6115    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
6116    of a set of rows and columns of a matrix.
6117 
6118    Collective on Mat
6119 
6120    Input Parameters:
6121 +  mat - the matrix
6122 .  numRows - the number of rows/columns to remove
6123 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
6124 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
6125 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6126 -  b - optional vector of right hand side, that will be adjusted by provided solution
6127 
6128    Notes:
6129    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
6130    but does not release memory.  For the dense and block diagonal
6131    formats this does not alter the nonzero structure.
6132 
6133    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6134    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6135    merely zeroed.
6136 
6137    The user can set a value in the diagonal entry (or for the AIJ and
6138    row formats can optionally remove the main diagonal entry from the
6139    nonzero structure as well, by passing 0.0 as the final argument).
6140 
6141    For the parallel case, all processes that share the matrix (i.e.,
6142    those in the communicator used for matrix creation) MUST call this
6143    routine, regardless of whether any rows being zeroed are owned by
6144    them.
6145 
6146    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
6147    list only rows local to itself, but the row/column numbers are given in local numbering).
6148 
6149    The grid coordinates are across the entire grid, not just the local portion
6150 
6151    In Fortran idxm and idxn should be declared as
6152 $     MatStencil idxm(4,m)
6153    and the values inserted using
6154 $    idxm(MatStencil_i,1) = i
6155 $    idxm(MatStencil_j,1) = j
6156 $    idxm(MatStencil_k,1) = k
6157 $    idxm(MatStencil_c,1) = c
6158    etc
6159 
6160    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
6161    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
6162    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
6163    DM_BOUNDARY_PERIODIC boundary type.
6164 
6165    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
6166    a single value per point) you can skip filling those indices.
6167 
6168    Level: intermediate
6169 
6170    Concepts: matrices^zeroing rows
6171 
6172 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6173           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
6174 @*/
6175 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
6176 {
6177   PetscInt       dim     = mat->stencil.dim;
6178   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
6179   PetscInt       *dims   = mat->stencil.dims+1;
6180   PetscInt       *starts = mat->stencil.starts;
6181   PetscInt       *dxm    = (PetscInt*) rows;
6182   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
6183   PetscErrorCode ierr;
6184 
6185   PetscFunctionBegin;
6186   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6187   PetscValidType(mat,1);
6188   if (numRows) PetscValidIntPointer(rows,3);
6189 
6190   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
6191   for (i = 0; i < numRows; ++i) {
6192     /* Skip unused dimensions (they are ordered k, j, i, c) */
6193     for (j = 0; j < 3-sdim; ++j) dxm++;
6194     /* Local index in X dir */
6195     tmp = *dxm++ - starts[0];
6196     /* Loop over remaining dimensions */
6197     for (j = 0; j < dim-1; ++j) {
6198       /* If nonlocal, set index to be negative */
6199       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6200       /* Update local index */
6201       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6202     }
6203     /* Skip component slot if necessary */
6204     if (mat->stencil.noc) dxm++;
6205     /* Local row number */
6206     if (tmp >= 0) {
6207       jdxm[numNewRows++] = tmp;
6208     }
6209   }
6210   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
6211   ierr = PetscFree(jdxm);CHKERRQ(ierr);
6212   PetscFunctionReturn(0);
6213 }
6214 
6215 /*@C
6216    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6217    of a set of rows of a matrix; using local numbering of rows.
6218 
6219    Collective on Mat
6220 
6221    Input Parameters:
6222 +  mat - the matrix
6223 .  numRows - the number of rows to remove
6224 .  rows - the global row indices
6225 .  diag - value put in all diagonals of eliminated rows
6226 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6227 -  b - optional vector of right hand side, that will be adjusted by provided solution
6228 
6229    Notes:
6230    Before calling MatZeroRowsLocal(), the user must first set the
6231    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6232 
6233    For the AIJ matrix formats this removes the old nonzero structure,
6234    but does not release memory.  For the dense and block diagonal
6235    formats this does not alter the nonzero structure.
6236 
6237    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6238    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6239    merely zeroed.
6240 
6241    The user can set a value in the diagonal entry (or for the AIJ and
6242    row formats can optionally remove the main diagonal entry from the
6243    nonzero structure as well, by passing 0.0 as the final argument).
6244 
6245    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6246    owns that are to be zeroed. This saves a global synchronization in the implementation.
6247 
6248    Level: intermediate
6249 
6250    Concepts: matrices^zeroing
6251 
6252 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6253           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6254 @*/
6255 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6256 {
6257   PetscErrorCode ierr;
6258 
6259   PetscFunctionBegin;
6260   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6261   PetscValidType(mat,1);
6262   if (numRows) PetscValidIntPointer(rows,3);
6263   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6264   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6265   MatCheckPreallocated(mat,1);
6266 
6267   if (mat->ops->zerorowslocal) {
6268     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6269   } else {
6270     IS             is, newis;
6271     const PetscInt *newRows;
6272 
6273     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6274     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6275     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
6276     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6277     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6278     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6279     ierr = ISDestroy(&newis);CHKERRQ(ierr);
6280     ierr = ISDestroy(&is);CHKERRQ(ierr);
6281   }
6282   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6283 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6284   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6285     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6286   }
6287 #endif
6288   PetscFunctionReturn(0);
6289 }
6290 
6291 /*@
6292    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6293    of a set of rows of a matrix; using local numbering of rows.
6294 
6295    Collective on Mat
6296 
6297    Input Parameters:
6298 +  mat - the matrix
6299 .  is - index set of rows to remove
6300 .  diag - value put in all diagonals of eliminated rows
6301 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6302 -  b - optional vector of right hand side, that will be adjusted by provided solution
6303 
6304    Notes:
6305    Before calling MatZeroRowsLocalIS(), the user must first set the
6306    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6307 
6308    For the AIJ matrix formats this removes the old nonzero structure,
6309    but does not release memory.  For the dense and block diagonal
6310    formats this does not alter the nonzero structure.
6311 
6312    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6313    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6314    merely zeroed.
6315 
6316    The user can set a value in the diagonal entry (or for the AIJ and
6317    row formats can optionally remove the main diagonal entry from the
6318    nonzero structure as well, by passing 0.0 as the final argument).
6319 
6320    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6321    owns that are to be zeroed. This saves a global synchronization in the implementation.
6322 
6323    Level: intermediate
6324 
6325    Concepts: matrices^zeroing
6326 
6327 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6328           MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6329 @*/
6330 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6331 {
6332   PetscErrorCode ierr;
6333   PetscInt       numRows;
6334   const PetscInt *rows;
6335 
6336   PetscFunctionBegin;
6337   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6338   PetscValidType(mat,1);
6339   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6340   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6341   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6342   MatCheckPreallocated(mat,1);
6343 
6344   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6345   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6346   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6347   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6348   PetscFunctionReturn(0);
6349 }
6350 
6351 /*@
6352    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6353    of a set of rows and columns of a matrix; using local numbering of rows.
6354 
6355    Collective on Mat
6356 
6357    Input Parameters:
6358 +  mat - the matrix
6359 .  numRows - the number of rows to remove
6360 .  rows - the global row indices
6361 .  diag - value put in all diagonals of eliminated rows
6362 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6363 -  b - optional vector of right hand side, that will be adjusted by provided solution
6364 
6365    Notes:
6366    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6367    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6368 
6369    The user can set a value in the diagonal entry (or for the AIJ and
6370    row formats can optionally remove the main diagonal entry from the
6371    nonzero structure as well, by passing 0.0 as the final argument).
6372 
6373    Level: intermediate
6374 
6375    Concepts: matrices^zeroing
6376 
6377 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6378           MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6379 @*/
6380 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6381 {
6382   PetscErrorCode ierr;
6383   IS             is, newis;
6384   const PetscInt *newRows;
6385 
6386   PetscFunctionBegin;
6387   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6388   PetscValidType(mat,1);
6389   if (numRows) PetscValidIntPointer(rows,3);
6390   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6391   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6392   MatCheckPreallocated(mat,1);
6393 
6394   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6395   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6396   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6397   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6398   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6399   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6400   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6401   ierr = ISDestroy(&is);CHKERRQ(ierr);
6402   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6403 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
6404   if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) {
6405     mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU;
6406   }
6407 #endif
6408   PetscFunctionReturn(0);
6409 }
6410 
6411 /*@
6412    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6413    of a set of rows and columns of a matrix; using local numbering of rows.
6414 
6415    Collective on Mat
6416 
6417    Input Parameters:
6418 +  mat - the matrix
6419 .  is - index set of rows to remove
6420 .  diag - value put in all diagonals of eliminated rows
6421 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6422 -  b - optional vector of right hand side, that will be adjusted by provided solution
6423 
6424    Notes:
6425    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6426    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6427 
6428    The user can set a value in the diagonal entry (or for the AIJ and
6429    row formats can optionally remove the main diagonal entry from the
6430    nonzero structure as well, by passing 0.0 as the final argument).
6431 
6432    Level: intermediate
6433 
6434    Concepts: matrices^zeroing
6435 
6436 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6437           MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6438 @*/
6439 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6440 {
6441   PetscErrorCode ierr;
6442   PetscInt       numRows;
6443   const PetscInt *rows;
6444 
6445   PetscFunctionBegin;
6446   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6447   PetscValidType(mat,1);
6448   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6449   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6450   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6451   MatCheckPreallocated(mat,1);
6452 
6453   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6454   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6455   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6456   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6457   PetscFunctionReturn(0);
6458 }
6459 
6460 /*@C
6461    MatGetSize - Returns the numbers of rows and columns in a matrix.
6462 
6463    Not Collective
6464 
6465    Input Parameter:
6466 .  mat - the matrix
6467 
6468    Output Parameters:
6469 +  m - the number of global rows
6470 -  n - the number of global columns
6471 
6472    Note: both output parameters can be NULL on input.
6473 
6474    Level: beginner
6475 
6476    Concepts: matrices^size
6477 
6478 .seealso: MatGetLocalSize()
6479 @*/
6480 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6481 {
6482   PetscFunctionBegin;
6483   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6484   if (m) *m = mat->rmap->N;
6485   if (n) *n = mat->cmap->N;
6486   PetscFunctionReturn(0);
6487 }
6488 
6489 /*@C
6490    MatGetLocalSize - Returns the number of rows and columns in a matrix
6491    stored locally.  This information may be implementation dependent, so
6492    use with care.
6493 
6494    Not Collective
6495 
6496    Input Parameters:
6497 .  mat - the matrix
6498 
6499    Output Parameters:
6500 +  m - the number of local rows
6501 -  n - the number of local columns
6502 
6503    Note: both output parameters can be NULL on input.
6504 
6505    Level: beginner
6506 
6507    Concepts: matrices^local size
6508 
6509 .seealso: MatGetSize()
6510 @*/
6511 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6512 {
6513   PetscFunctionBegin;
6514   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6515   if (m) PetscValidIntPointer(m,2);
6516   if (n) PetscValidIntPointer(n,3);
6517   if (m) *m = mat->rmap->n;
6518   if (n) *n = mat->cmap->n;
6519   PetscFunctionReturn(0);
6520 }
6521 
6522 /*@C
6523    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6524    this processor. (The columns of the "diagonal block")
6525 
6526    Not Collective, unless matrix has not been allocated, then collective on Mat
6527 
6528    Input Parameters:
6529 .  mat - the matrix
6530 
6531    Output Parameters:
6532 +  m - the global index of the first local column
6533 -  n - one more than the global index of the last local column
6534 
6535    Notes:
6536     both output parameters can be NULL on input.
6537 
6538    Level: developer
6539 
6540    Concepts: matrices^column ownership
6541 
6542 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6543 
6544 @*/
6545 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6546 {
6547   PetscFunctionBegin;
6548   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6549   PetscValidType(mat,1);
6550   if (m) PetscValidIntPointer(m,2);
6551   if (n) PetscValidIntPointer(n,3);
6552   MatCheckPreallocated(mat,1);
6553   if (m) *m = mat->cmap->rstart;
6554   if (n) *n = mat->cmap->rend;
6555   PetscFunctionReturn(0);
6556 }
6557 
6558 /*@C
6559    MatGetOwnershipRange - Returns the range of matrix rows owned by
6560    this processor, assuming that the matrix is laid out with the first
6561    n1 rows on the first processor, the next n2 rows on the second, etc.
6562    For certain parallel layouts this range may not be well defined.
6563 
6564    Not Collective
6565 
6566    Input Parameters:
6567 .  mat - the matrix
6568 
6569    Output Parameters:
6570 +  m - the global index of the first local row
6571 -  n - one more than the global index of the last local row
6572 
6573    Note: Both output parameters can be NULL on input.
6574 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6575 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6576 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6577 
6578    Level: beginner
6579 
6580    Concepts: matrices^row ownership
6581 
6582 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6583 
6584 @*/
6585 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6586 {
6587   PetscFunctionBegin;
6588   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6589   PetscValidType(mat,1);
6590   if (m) PetscValidIntPointer(m,2);
6591   if (n) PetscValidIntPointer(n,3);
6592   MatCheckPreallocated(mat,1);
6593   if (m) *m = mat->rmap->rstart;
6594   if (n) *n = mat->rmap->rend;
6595   PetscFunctionReturn(0);
6596 }
6597 
6598 /*@C
6599    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6600    each process
6601 
6602    Not Collective, unless matrix has not been allocated, then collective on Mat
6603 
6604    Input Parameters:
6605 .  mat - the matrix
6606 
6607    Output Parameters:
6608 .  ranges - start of each processors portion plus one more than the total length at the end
6609 
6610    Level: beginner
6611 
6612    Concepts: matrices^row ownership
6613 
6614 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6615 
6616 @*/
6617 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6618 {
6619   PetscErrorCode ierr;
6620 
6621   PetscFunctionBegin;
6622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6623   PetscValidType(mat,1);
6624   MatCheckPreallocated(mat,1);
6625   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6626   PetscFunctionReturn(0);
6627 }
6628 
6629 /*@C
6630    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6631    this processor. (The columns of the "diagonal blocks" for each process)
6632 
6633    Not Collective, unless matrix has not been allocated, then collective on Mat
6634 
6635    Input Parameters:
6636 .  mat - the matrix
6637 
6638    Output Parameters:
6639 .  ranges - start of each processors portion plus one more then the total length at the end
6640 
6641    Level: beginner
6642 
6643    Concepts: matrices^column ownership
6644 
6645 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6646 
6647 @*/
6648 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6649 {
6650   PetscErrorCode ierr;
6651 
6652   PetscFunctionBegin;
6653   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6654   PetscValidType(mat,1);
6655   MatCheckPreallocated(mat,1);
6656   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6657   PetscFunctionReturn(0);
6658 }
6659 
6660 /*@C
6661    MatGetOwnershipIS - Get row and column ownership as index sets
6662 
6663    Not Collective
6664 
6665    Input Arguments:
6666 .  A - matrix of type Elemental
6667 
6668    Output Arguments:
6669 +  rows - rows in which this process owns elements
6670 .  cols - columns in which this process owns elements
6671 
6672    Level: intermediate
6673 
6674 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL
6675 @*/
6676 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6677 {
6678   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6679 
6680   PetscFunctionBegin;
6681   MatCheckPreallocated(A,1);
6682   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6683   if (f) {
6684     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6685   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6686     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6687     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6688   }
6689   PetscFunctionReturn(0);
6690 }
6691 
6692 /*@C
6693    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6694    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6695    to complete the factorization.
6696 
6697    Collective on Mat
6698 
6699    Input Parameters:
6700 +  mat - the matrix
6701 .  row - row permutation
6702 .  column - column permutation
6703 -  info - structure containing
6704 $      levels - number of levels of fill.
6705 $      expected fill - as ratio of original fill.
6706 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6707                 missing diagonal entries)
6708 
6709    Output Parameters:
6710 .  fact - new matrix that has been symbolically factored
6711 
6712    Notes:
6713     See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6714 
6715    Most users should employ the simplified KSP interface for linear solvers
6716    instead of working directly with matrix algebra routines such as this.
6717    See, e.g., KSPCreate().
6718 
6719    Level: developer
6720 
6721   Concepts: matrices^symbolic LU factorization
6722   Concepts: matrices^factorization
6723   Concepts: LU^symbolic factorization
6724 
6725 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6726           MatGetOrdering(), MatFactorInfo
6727 
6728     Note: this uses the definition of level of fill as in Y. Saad, 2003
6729 
6730     Developer Note: fortran interface is not autogenerated as the f90
6731     interface defintion cannot be generated correctly [due to MatFactorInfo]
6732 
6733    References:
6734      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6735 @*/
6736 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6737 {
6738   PetscErrorCode ierr;
6739 
6740   PetscFunctionBegin;
6741   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6742   PetscValidType(mat,1);
6743   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6744   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6745   PetscValidPointer(info,4);
6746   PetscValidPointer(fact,5);
6747   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6748   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6749   if (!(fact)->ops->ilufactorsymbolic) {
6750     MatSolverType spackage;
6751     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6752     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6753   }
6754   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6755   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6756   MatCheckPreallocated(mat,2);
6757 
6758   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6759   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6760   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6761   PetscFunctionReturn(0);
6762 }
6763 
6764 /*@C
6765    MatICCFactorSymbolic - Performs symbolic incomplete
6766    Cholesky factorization for a symmetric matrix.  Use
6767    MatCholeskyFactorNumeric() to complete the factorization.
6768 
6769    Collective on Mat
6770 
6771    Input Parameters:
6772 +  mat - the matrix
6773 .  perm - row and column permutation
6774 -  info - structure containing
6775 $      levels - number of levels of fill.
6776 $      expected fill - as ratio of original fill.
6777 
6778    Output Parameter:
6779 .  fact - the factored matrix
6780 
6781    Notes:
6782    Most users should employ the KSP interface for linear solvers
6783    instead of working directly with matrix algebra routines such as this.
6784    See, e.g., KSPCreate().
6785 
6786    Level: developer
6787 
6788   Concepts: matrices^symbolic incomplete Cholesky factorization
6789   Concepts: matrices^factorization
6790   Concepts: Cholsky^symbolic factorization
6791 
6792 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6793 
6794     Note: this uses the definition of level of fill as in Y. Saad, 2003
6795 
6796     Developer Note: fortran interface is not autogenerated as the f90
6797     interface defintion cannot be generated correctly [due to MatFactorInfo]
6798 
6799    References:
6800      Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003
6801 @*/
6802 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6803 {
6804   PetscErrorCode ierr;
6805 
6806   PetscFunctionBegin;
6807   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6808   PetscValidType(mat,1);
6809   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6810   PetscValidPointer(info,3);
6811   PetscValidPointer(fact,4);
6812   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6813   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6814   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6815   if (!(fact)->ops->iccfactorsymbolic) {
6816     MatSolverType spackage;
6817     ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr);
6818     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6819   }
6820   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6821   MatCheckPreallocated(mat,2);
6822 
6823   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6824   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6825   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6826   PetscFunctionReturn(0);
6827 }
6828 
6829 /*@C
6830    MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6831    points to an array of valid matrices, they may be reused to store the new
6832    submatrices.
6833 
6834    Collective on Mat
6835 
6836    Input Parameters:
6837 +  mat - the matrix
6838 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6839 .  irow, icol - index sets of rows and columns to extract
6840 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6841 
6842    Output Parameter:
6843 .  submat - the array of submatrices
6844 
6845    Notes:
6846    MatCreateSubMatrices() can extract ONLY sequential submatrices
6847    (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6848    to extract a parallel submatrix.
6849 
6850    Some matrix types place restrictions on the row and column
6851    indices, such as that they be sorted or that they be equal to each other.
6852 
6853    The index sets may not have duplicate entries.
6854 
6855    When extracting submatrices from a parallel matrix, each processor can
6856    form a different submatrix by setting the rows and columns of its
6857    individual index sets according to the local submatrix desired.
6858 
6859    When finished using the submatrices, the user should destroy
6860    them with MatDestroySubMatrices().
6861 
6862    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6863    original matrix has not changed from that last call to MatCreateSubMatrices().
6864 
6865    This routine creates the matrices in submat; you should NOT create them before
6866    calling it. It also allocates the array of matrix pointers submat.
6867 
6868    For BAIJ matrices the index sets must respect the block structure, that is if they
6869    request one row/column in a block, they must request all rows/columns that are in
6870    that block. For example, if the block size is 2 you cannot request just row 0 and
6871    column 0.
6872 
6873    Fortran Note:
6874    The Fortran interface is slightly different from that given below; it
6875    requires one to pass in  as submat a Mat (integer) array of size at least n+1.
6876 
6877    Level: advanced
6878 
6879    Concepts: matrices^accessing submatrices
6880    Concepts: submatrices
6881 
6882 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6883 @*/
6884 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6885 {
6886   PetscErrorCode ierr;
6887   PetscInt       i;
6888   PetscBool      eq;
6889 
6890   PetscFunctionBegin;
6891   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6892   PetscValidType(mat,1);
6893   if (n) {
6894     PetscValidPointer(irow,3);
6895     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6896     PetscValidPointer(icol,4);
6897     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6898   }
6899   PetscValidPointer(submat,6);
6900   if (n && scall == MAT_REUSE_MATRIX) {
6901     PetscValidPointer(*submat,6);
6902     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6903   }
6904   if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6905   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6906   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6907   MatCheckPreallocated(mat,1);
6908 
6909   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6910   ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6911   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6912   for (i=0; i<n; i++) {
6913     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6914     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6915       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6916       if (eq) {
6917         if (mat->symmetric) {
6918           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6919         } else if (mat->hermitian) {
6920           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6921         } else if (mat->structurally_symmetric) {
6922           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6923         }
6924       }
6925     }
6926   }
6927   PetscFunctionReturn(0);
6928 }
6929 
6930 /*@C
6931    MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6932 
6933    Collective on Mat
6934 
6935    Input Parameters:
6936 +  mat - the matrix
6937 .  n   - the number of submatrixes to be extracted
6938 .  irow, icol - index sets of rows and columns to extract
6939 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6940 
6941    Output Parameter:
6942 .  submat - the array of submatrices
6943 
6944    Level: advanced
6945 
6946    Concepts: matrices^accessing submatrices
6947    Concepts: submatrices
6948 
6949 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6950 @*/
6951 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6952 {
6953   PetscErrorCode ierr;
6954   PetscInt       i;
6955   PetscBool      eq;
6956 
6957   PetscFunctionBegin;
6958   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6959   PetscValidType(mat,1);
6960   if (n) {
6961     PetscValidPointer(irow,3);
6962     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6963     PetscValidPointer(icol,4);
6964     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6965   }
6966   PetscValidPointer(submat,6);
6967   if (n && scall == MAT_REUSE_MATRIX) {
6968     PetscValidPointer(*submat,6);
6969     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6970   }
6971   if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6972   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6973   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6974   MatCheckPreallocated(mat,1);
6975 
6976   ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6977   ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6978   ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr);
6979   for (i=0; i<n; i++) {
6980     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6981       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6982       if (eq) {
6983         if (mat->symmetric) {
6984           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6985         } else if (mat->hermitian) {
6986           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6987         } else if (mat->structurally_symmetric) {
6988           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6989         }
6990       }
6991     }
6992   }
6993   PetscFunctionReturn(0);
6994 }
6995 
6996 /*@C
6997    MatDestroyMatrices - Destroys an array of matrices.
6998 
6999    Collective on Mat
7000 
7001    Input Parameters:
7002 +  n - the number of local matrices
7003 -  mat - the matrices (note that this is a pointer to the array of matrices)
7004 
7005    Level: advanced
7006 
7007     Notes:
7008     Frees not only the matrices, but also the array that contains the matrices
7009            In Fortran will not free the array.
7010 
7011 .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
7012 @*/
7013 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
7014 {
7015   PetscErrorCode ierr;
7016   PetscInt       i;
7017 
7018   PetscFunctionBegin;
7019   if (!*mat) PetscFunctionReturn(0);
7020   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7021   PetscValidPointer(mat,2);
7022 
7023   for (i=0; i<n; i++) {
7024     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
7025   }
7026 
7027   /* memory is allocated even if n = 0 */
7028   ierr = PetscFree(*mat);CHKERRQ(ierr);
7029   PetscFunctionReturn(0);
7030 }
7031 
7032 /*@C
7033    MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
7034 
7035    Collective on Mat
7036 
7037    Input Parameters:
7038 +  n - the number of local matrices
7039 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
7040                        sequence of MatCreateSubMatrices())
7041 
7042    Level: advanced
7043 
7044     Notes:
7045     Frees not only the matrices, but also the array that contains the matrices
7046            In Fortran will not free the array.
7047 
7048 .seealso: MatCreateSubMatrices()
7049 @*/
7050 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
7051 {
7052   PetscErrorCode ierr;
7053   Mat            mat0;
7054 
7055   PetscFunctionBegin;
7056   if (!*mat) PetscFunctionReturn(0);
7057   /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
7058   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
7059   PetscValidPointer(mat,2);
7060 
7061   mat0 = (*mat)[0];
7062   if (mat0 && mat0->ops->destroysubmatrices) {
7063     ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr);
7064   } else {
7065     ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr);
7066   }
7067   PetscFunctionReturn(0);
7068 }
7069 
7070 /*@C
7071    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
7072 
7073    Collective on Mat
7074 
7075    Input Parameters:
7076 .  mat - the matrix
7077 
7078    Output Parameter:
7079 .  matstruct - the sequential matrix with the nonzero structure of mat
7080 
7081   Level: intermediate
7082 
7083 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
7084 @*/
7085 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
7086 {
7087   PetscErrorCode ierr;
7088 
7089   PetscFunctionBegin;
7090   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7091   PetscValidPointer(matstruct,2);
7092 
7093   PetscValidType(mat,1);
7094   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7095   MatCheckPreallocated(mat,1);
7096 
7097   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
7098   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7099   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
7100   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
7101   PetscFunctionReturn(0);
7102 }
7103 
7104 /*@C
7105    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
7106 
7107    Collective on Mat
7108 
7109    Input Parameters:
7110 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
7111                        sequence of MatGetSequentialNonzeroStructure())
7112 
7113    Level: advanced
7114 
7115     Notes:
7116     Frees not only the matrices, but also the array that contains the matrices
7117 
7118 .seealso: MatGetSeqNonzeroStructure()
7119 @*/
7120 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
7121 {
7122   PetscErrorCode ierr;
7123 
7124   PetscFunctionBegin;
7125   PetscValidPointer(mat,1);
7126   ierr = MatDestroy(mat);CHKERRQ(ierr);
7127   PetscFunctionReturn(0);
7128 }
7129 
7130 /*@
7131    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
7132    replaces the index sets by larger ones that represent submatrices with
7133    additional overlap.
7134 
7135    Collective on Mat
7136 
7137    Input Parameters:
7138 +  mat - the matrix
7139 .  n   - the number of index sets
7140 .  is  - the array of index sets (these index sets will changed during the call)
7141 -  ov  - the additional overlap requested
7142 
7143    Options Database:
7144 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7145 
7146    Level: developer
7147 
7148    Concepts: overlap
7149    Concepts: ASM^computing overlap
7150 
7151 .seealso: MatCreateSubMatrices()
7152 @*/
7153 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
7154 {
7155   PetscErrorCode ierr;
7156 
7157   PetscFunctionBegin;
7158   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7159   PetscValidType(mat,1);
7160   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7161   if (n) {
7162     PetscValidPointer(is,3);
7163     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7164   }
7165   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7166   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7167   MatCheckPreallocated(mat,1);
7168 
7169   if (!ov) PetscFunctionReturn(0);
7170   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7171   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7172   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
7173   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7174   PetscFunctionReturn(0);
7175 }
7176 
7177 
7178 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
7179 
7180 /*@
7181    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
7182    a sub communicator, replaces the index sets by larger ones that represent submatrices with
7183    additional overlap.
7184 
7185    Collective on Mat
7186 
7187    Input Parameters:
7188 +  mat - the matrix
7189 .  n   - the number of index sets
7190 .  is  - the array of index sets (these index sets will changed during the call)
7191 -  ov  - the additional overlap requested
7192 
7193    Options Database:
7194 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7195 
7196    Level: developer
7197 
7198    Concepts: overlap
7199    Concepts: ASM^computing overlap
7200 
7201 .seealso: MatCreateSubMatrices()
7202 @*/
7203 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7204 {
7205   PetscInt       i;
7206   PetscErrorCode ierr;
7207 
7208   PetscFunctionBegin;
7209   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7210   PetscValidType(mat,1);
7211   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7212   if (n) {
7213     PetscValidPointer(is,3);
7214     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
7215   }
7216   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7217   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7218   MatCheckPreallocated(mat,1);
7219   if (!ov) PetscFunctionReturn(0);
7220   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7221   for(i=0; i<n; i++){
7222 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
7223   }
7224   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
7225   PetscFunctionReturn(0);
7226 }
7227 
7228 
7229 
7230 
7231 /*@
7232    MatGetBlockSize - Returns the matrix block size.
7233 
7234    Not Collective
7235 
7236    Input Parameter:
7237 .  mat - the matrix
7238 
7239    Output Parameter:
7240 .  bs - block size
7241 
7242    Notes:
7243     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7244 
7245    If the block size has not been set yet this routine returns 1.
7246 
7247    Level: intermediate
7248 
7249    Concepts: matrices^block size
7250 
7251 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7252 @*/
7253 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7254 {
7255   PetscFunctionBegin;
7256   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7257   PetscValidIntPointer(bs,2);
7258   *bs = PetscAbs(mat->rmap->bs);
7259   PetscFunctionReturn(0);
7260 }
7261 
7262 /*@
7263    MatGetBlockSizes - Returns the matrix block row and column sizes.
7264 
7265    Not Collective
7266 
7267    Input Parameter:
7268 .  mat - the matrix
7269 
7270    Output Parameter:
7271 .  rbs - row block size
7272 .  cbs - column block size
7273 
7274    Notes:
7275     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7276     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7277 
7278    If a block size has not been set yet this routine returns 1.
7279 
7280    Level: intermediate
7281 
7282    Concepts: matrices^block size
7283 
7284 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7285 @*/
7286 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7287 {
7288   PetscFunctionBegin;
7289   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7290   if (rbs) PetscValidIntPointer(rbs,2);
7291   if (cbs) PetscValidIntPointer(cbs,3);
7292   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7293   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7294   PetscFunctionReturn(0);
7295 }
7296 
7297 /*@
7298    MatSetBlockSize - Sets the matrix block size.
7299 
7300    Logically Collective on Mat
7301 
7302    Input Parameters:
7303 +  mat - the matrix
7304 -  bs - block size
7305 
7306    Notes:
7307     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7308     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7309 
7310     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7311     is compatible with the matrix local sizes.
7312 
7313    Level: intermediate
7314 
7315    Concepts: matrices^block size
7316 
7317 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7318 @*/
7319 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7320 {
7321   PetscErrorCode ierr;
7322 
7323   PetscFunctionBegin;
7324   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7325   PetscValidLogicalCollectiveInt(mat,bs,2);
7326   ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr);
7327   PetscFunctionReturn(0);
7328 }
7329 
7330 /*@
7331    MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size
7332 
7333    Logically Collective on Mat
7334 
7335    Input Parameters:
7336 +  mat - the matrix
7337 .  nblocks - the number of blocks on this process
7338 -  bsizes - the block sizes
7339 
7340    Notes:
7341     Currently used by PCVPBJACOBI for SeqAIJ matrices
7342 
7343    Level: intermediate
7344 
7345    Concepts: matrices^block size
7346 
7347 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes()
7348 @*/
7349 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes)
7350 {
7351   PetscErrorCode ierr;
7352   PetscInt       i,ncnt = 0, nlocal;
7353 
7354   PetscFunctionBegin;
7355   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7356   if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero");
7357   ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr);
7358   for (i=0; i<nblocks; i++) ncnt += bsizes[i];
7359   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);
7360   ierr = PetscFree(mat->bsizes);CHKERRQ(ierr);
7361   mat->nblocks = nblocks;
7362   ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr);
7363   ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr);
7364   PetscFunctionReturn(0);
7365 }
7366 
7367 /*@C
7368    MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size
7369 
7370    Logically Collective on Mat
7371 
7372    Input Parameters:
7373 .  mat - the matrix
7374 
7375    Output Parameters:
7376 +  nblocks - the number of blocks on this process
7377 -  bsizes - the block sizes
7378 
7379    Notes: Currently not supported from Fortran
7380 
7381    Level: intermediate
7382 
7383    Concepts: matrices^block size
7384 
7385 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes()
7386 @*/
7387 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes)
7388 {
7389   PetscFunctionBegin;
7390   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7391   *nblocks = mat->nblocks;
7392   *bsizes  = mat->bsizes;
7393   PetscFunctionReturn(0);
7394 }
7395 
7396 /*@
7397    MatSetBlockSizes - Sets the matrix block row and column sizes.
7398 
7399    Logically Collective on Mat
7400 
7401    Input Parameters:
7402 +  mat - the matrix
7403 -  rbs - row block size
7404 -  cbs - column block size
7405 
7406    Notes:
7407     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7408     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7409     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7410 
7411     For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7412     are compatible with the matrix local sizes.
7413 
7414     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7415 
7416    Level: intermediate
7417 
7418    Concepts: matrices^block size
7419 
7420 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7421 @*/
7422 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7423 {
7424   PetscErrorCode ierr;
7425 
7426   PetscFunctionBegin;
7427   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7428   PetscValidLogicalCollectiveInt(mat,rbs,2);
7429   PetscValidLogicalCollectiveInt(mat,cbs,3);
7430   if (mat->ops->setblocksizes) {
7431     ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr);
7432   }
7433   if (mat->rmap->refcnt) {
7434     ISLocalToGlobalMapping l2g = NULL;
7435     PetscLayout            nmap = NULL;
7436 
7437     ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr);
7438     if (mat->rmap->mapping) {
7439       ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr);
7440     }
7441     ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr);
7442     mat->rmap = nmap;
7443     mat->rmap->mapping = l2g;
7444   }
7445   if (mat->cmap->refcnt) {
7446     ISLocalToGlobalMapping l2g = NULL;
7447     PetscLayout            nmap = NULL;
7448 
7449     ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr);
7450     if (mat->cmap->mapping) {
7451       ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr);
7452     }
7453     ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr);
7454     mat->cmap = nmap;
7455     mat->cmap->mapping = l2g;
7456   }
7457   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7458   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7459   PetscFunctionReturn(0);
7460 }
7461 
7462 /*@
7463    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7464 
7465    Logically Collective on Mat
7466 
7467    Input Parameters:
7468 +  mat - the matrix
7469 .  fromRow - matrix from which to copy row block size
7470 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7471 
7472    Level: developer
7473 
7474    Concepts: matrices^block size
7475 
7476 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7477 @*/
7478 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7479 {
7480   PetscErrorCode ierr;
7481 
7482   PetscFunctionBegin;
7483   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7484   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7485   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7486   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7487   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7488   PetscFunctionReturn(0);
7489 }
7490 
7491 /*@
7492    MatResidual - Default routine to calculate the residual.
7493 
7494    Collective on Mat and Vec
7495 
7496    Input Parameters:
7497 +  mat - the matrix
7498 .  b   - the right-hand-side
7499 -  x   - the approximate solution
7500 
7501    Output Parameter:
7502 .  r - location to store the residual
7503 
7504    Level: developer
7505 
7506 .keywords: MG, default, multigrid, residual
7507 
7508 .seealso: PCMGSetResidual()
7509 @*/
7510 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7511 {
7512   PetscErrorCode ierr;
7513 
7514   PetscFunctionBegin;
7515   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7516   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7517   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7518   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7519   PetscValidType(mat,1);
7520   MatCheckPreallocated(mat,1);
7521   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7522   if (!mat->ops->residual) {
7523     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7524     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7525   } else {
7526     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7527   }
7528   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7529   PetscFunctionReturn(0);
7530 }
7531 
7532 /*@C
7533     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7534 
7535    Collective on Mat
7536 
7537     Input Parameters:
7538 +   mat - the matrix
7539 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7540 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7541 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7542                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7543                  always used.
7544 
7545     Output Parameters:
7546 +   n - number of rows in the (possibly compressed) matrix
7547 .   ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix
7548 .   ja - the column indices
7549 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7550            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7551 
7552     Level: developer
7553 
7554     Notes:
7555     You CANNOT change any of the ia[] or ja[] values.
7556 
7557     Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values.
7558 
7559     Fortran Notes:
7560     In Fortran use
7561 $
7562 $      PetscInt ia(1), ja(1)
7563 $      PetscOffset iia, jja
7564 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7565 $      ! Access the ith and jth entries via ia(iia + i) and ja(jja + j)
7566 
7567      or
7568 $
7569 $    PetscInt, pointer :: ia(:),ja(:)
7570 $    call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7571 $    ! Access the ith and jth entries via ia(i) and ja(j)
7572 
7573 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7574 @*/
7575 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7576 {
7577   PetscErrorCode ierr;
7578 
7579   PetscFunctionBegin;
7580   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7581   PetscValidType(mat,1);
7582   PetscValidIntPointer(n,5);
7583   if (ia) PetscValidIntPointer(ia,6);
7584   if (ja) PetscValidIntPointer(ja,7);
7585   PetscValidIntPointer(done,8);
7586   MatCheckPreallocated(mat,1);
7587   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7588   else {
7589     *done = PETSC_TRUE;
7590     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7591     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7592     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7593   }
7594   PetscFunctionReturn(0);
7595 }
7596 
7597 /*@C
7598     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7599 
7600     Collective on Mat
7601 
7602     Input Parameters:
7603 +   mat - the matrix
7604 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7605 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7606                 symmetrized
7607 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7608                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7609                  always used.
7610 .   n - number of columns in the (possibly compressed) matrix
7611 .   ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix
7612 -   ja - the row indices
7613 
7614     Output Parameters:
7615 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7616 
7617     Level: developer
7618 
7619 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7620 @*/
7621 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7622 {
7623   PetscErrorCode ierr;
7624 
7625   PetscFunctionBegin;
7626   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7627   PetscValidType(mat,1);
7628   PetscValidIntPointer(n,4);
7629   if (ia) PetscValidIntPointer(ia,5);
7630   if (ja) PetscValidIntPointer(ja,6);
7631   PetscValidIntPointer(done,7);
7632   MatCheckPreallocated(mat,1);
7633   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7634   else {
7635     *done = PETSC_TRUE;
7636     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7637   }
7638   PetscFunctionReturn(0);
7639 }
7640 
7641 /*@C
7642     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7643     MatGetRowIJ().
7644 
7645     Collective on Mat
7646 
7647     Input Parameters:
7648 +   mat - the matrix
7649 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7650 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7651                 symmetrized
7652 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7653                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7654                  always used.
7655 .   n - size of (possibly compressed) matrix
7656 .   ia - the row pointers
7657 -   ja - the column indices
7658 
7659     Output Parameters:
7660 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7661 
7662     Note:
7663     This routine zeros out n, ia, and ja. This is to prevent accidental
7664     us of the array after it has been restored. If you pass NULL, it will
7665     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7666 
7667     Level: developer
7668 
7669 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7670 @*/
7671 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7672 {
7673   PetscErrorCode ierr;
7674 
7675   PetscFunctionBegin;
7676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7677   PetscValidType(mat,1);
7678   if (ia) PetscValidIntPointer(ia,6);
7679   if (ja) PetscValidIntPointer(ja,7);
7680   PetscValidIntPointer(done,8);
7681   MatCheckPreallocated(mat,1);
7682 
7683   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7684   else {
7685     *done = PETSC_TRUE;
7686     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7687     if (n)  *n = 0;
7688     if (ia) *ia = NULL;
7689     if (ja) *ja = NULL;
7690   }
7691   PetscFunctionReturn(0);
7692 }
7693 
7694 /*@C
7695     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7696     MatGetColumnIJ().
7697 
7698     Collective on Mat
7699 
7700     Input Parameters:
7701 +   mat - the matrix
7702 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7703 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7704                 symmetrized
7705 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7706                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7707                  always used.
7708 
7709     Output Parameters:
7710 +   n - size of (possibly compressed) matrix
7711 .   ia - the column pointers
7712 .   ja - the row indices
7713 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7714 
7715     Level: developer
7716 
7717 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7718 @*/
7719 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7720 {
7721   PetscErrorCode ierr;
7722 
7723   PetscFunctionBegin;
7724   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7725   PetscValidType(mat,1);
7726   if (ia) PetscValidIntPointer(ia,5);
7727   if (ja) PetscValidIntPointer(ja,6);
7728   PetscValidIntPointer(done,7);
7729   MatCheckPreallocated(mat,1);
7730 
7731   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7732   else {
7733     *done = PETSC_TRUE;
7734     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7735     if (n)  *n = 0;
7736     if (ia) *ia = NULL;
7737     if (ja) *ja = NULL;
7738   }
7739   PetscFunctionReturn(0);
7740 }
7741 
7742 /*@C
7743     MatColoringPatch -Used inside matrix coloring routines that
7744     use MatGetRowIJ() and/or MatGetColumnIJ().
7745 
7746     Collective on Mat
7747 
7748     Input Parameters:
7749 +   mat - the matrix
7750 .   ncolors - max color value
7751 .   n   - number of entries in colorarray
7752 -   colorarray - array indicating color for each column
7753 
7754     Output Parameters:
7755 .   iscoloring - coloring generated using colorarray information
7756 
7757     Level: developer
7758 
7759 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7760 
7761 @*/
7762 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7763 {
7764   PetscErrorCode ierr;
7765 
7766   PetscFunctionBegin;
7767   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7768   PetscValidType(mat,1);
7769   PetscValidIntPointer(colorarray,4);
7770   PetscValidPointer(iscoloring,5);
7771   MatCheckPreallocated(mat,1);
7772 
7773   if (!mat->ops->coloringpatch) {
7774     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7775   } else {
7776     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7777   }
7778   PetscFunctionReturn(0);
7779 }
7780 
7781 
7782 /*@
7783    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7784 
7785    Logically Collective on Mat
7786 
7787    Input Parameter:
7788 .  mat - the factored matrix to be reset
7789 
7790    Notes:
7791    This routine should be used only with factored matrices formed by in-place
7792    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7793    format).  This option can save memory, for example, when solving nonlinear
7794    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7795    ILU(0) preconditioner.
7796 
7797    Note that one can specify in-place ILU(0) factorization by calling
7798 .vb
7799      PCType(pc,PCILU);
7800      PCFactorSeUseInPlace(pc);
7801 .ve
7802    or by using the options -pc_type ilu -pc_factor_in_place
7803 
7804    In-place factorization ILU(0) can also be used as a local
7805    solver for the blocks within the block Jacobi or additive Schwarz
7806    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7807    for details on setting local solver options.
7808 
7809    Most users should employ the simplified KSP interface for linear solvers
7810    instead of working directly with matrix algebra routines such as this.
7811    See, e.g., KSPCreate().
7812 
7813    Level: developer
7814 
7815 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7816 
7817    Concepts: matrices^unfactored
7818 
7819 @*/
7820 PetscErrorCode MatSetUnfactored(Mat mat)
7821 {
7822   PetscErrorCode ierr;
7823 
7824   PetscFunctionBegin;
7825   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7826   PetscValidType(mat,1);
7827   MatCheckPreallocated(mat,1);
7828   mat->factortype = MAT_FACTOR_NONE;
7829   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7830   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7831   PetscFunctionReturn(0);
7832 }
7833 
7834 /*MC
7835     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7836 
7837     Synopsis:
7838     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7839 
7840     Not collective
7841 
7842     Input Parameter:
7843 .   x - matrix
7844 
7845     Output Parameters:
7846 +   xx_v - the Fortran90 pointer to the array
7847 -   ierr - error code
7848 
7849     Example of Usage:
7850 .vb
7851       PetscScalar, pointer xx_v(:,:)
7852       ....
7853       call MatDenseGetArrayF90(x,xx_v,ierr)
7854       a = xx_v(3)
7855       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7856 .ve
7857 
7858     Level: advanced
7859 
7860 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7861 
7862     Concepts: matrices^accessing array
7863 
7864 M*/
7865 
7866 /*MC
7867     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7868     accessed with MatDenseGetArrayF90().
7869 
7870     Synopsis:
7871     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7872 
7873     Not collective
7874 
7875     Input Parameters:
7876 +   x - matrix
7877 -   xx_v - the Fortran90 pointer to the array
7878 
7879     Output Parameter:
7880 .   ierr - error code
7881 
7882     Example of Usage:
7883 .vb
7884        PetscScalar, pointer xx_v(:,:)
7885        ....
7886        call MatDenseGetArrayF90(x,xx_v,ierr)
7887        a = xx_v(3)
7888        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7889 .ve
7890 
7891     Level: advanced
7892 
7893 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7894 
7895 M*/
7896 
7897 
7898 /*MC
7899     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7900 
7901     Synopsis:
7902     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7903 
7904     Not collective
7905 
7906     Input Parameter:
7907 .   x - matrix
7908 
7909     Output Parameters:
7910 +   xx_v - the Fortran90 pointer to the array
7911 -   ierr - error code
7912 
7913     Example of Usage:
7914 .vb
7915       PetscScalar, pointer xx_v(:)
7916       ....
7917       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7918       a = xx_v(3)
7919       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7920 .ve
7921 
7922     Level: advanced
7923 
7924 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7925 
7926     Concepts: matrices^accessing array
7927 
7928 M*/
7929 
7930 /*MC
7931     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7932     accessed with MatSeqAIJGetArrayF90().
7933 
7934     Synopsis:
7935     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7936 
7937     Not collective
7938 
7939     Input Parameters:
7940 +   x - matrix
7941 -   xx_v - the Fortran90 pointer to the array
7942 
7943     Output Parameter:
7944 .   ierr - error code
7945 
7946     Example of Usage:
7947 .vb
7948        PetscScalar, pointer xx_v(:)
7949        ....
7950        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7951        a = xx_v(3)
7952        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7953 .ve
7954 
7955     Level: advanced
7956 
7957 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7958 
7959 M*/
7960 
7961 
7962 /*@
7963     MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7964                       as the original matrix.
7965 
7966     Collective on Mat
7967 
7968     Input Parameters:
7969 +   mat - the original matrix
7970 .   isrow - parallel IS containing the rows this processor should obtain
7971 .   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.
7972 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7973 
7974     Output Parameter:
7975 .   newmat - the new submatrix, of the same type as the old
7976 
7977     Level: advanced
7978 
7979     Notes:
7980     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7981 
7982     Some matrix types place restrictions on the row and column indices, such
7983     as that they be sorted or that they be equal to each other.
7984 
7985     The index sets may not have duplicate entries.
7986 
7987       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7988    the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7989    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7990    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7991    you are finished using it.
7992 
7993     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7994     the input matrix.
7995 
7996     If iscol is NULL then all columns are obtained (not supported in Fortran).
7997 
7998    Example usage:
7999    Consider the following 8x8 matrix with 34 non-zero values, that is
8000    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
8001    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
8002    as follows:
8003 
8004 .vb
8005             1  2  0  |  0  3  0  |  0  4
8006     Proc0   0  5  6  |  7  0  0  |  8  0
8007             9  0 10  | 11  0  0  | 12  0
8008     -------------------------------------
8009            13  0 14  | 15 16 17  |  0  0
8010     Proc1   0 18  0  | 19 20 21  |  0  0
8011             0  0  0  | 22 23  0  | 24  0
8012     -------------------------------------
8013     Proc2  25 26 27  |  0  0 28  | 29  0
8014            30  0  0  | 31 32 33  |  0 34
8015 .ve
8016 
8017     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
8018 
8019 .vb
8020             2  0  |  0  3  0  |  0
8021     Proc0   5  6  |  7  0  0  |  8
8022     -------------------------------
8023     Proc1  18  0  | 19 20 21  |  0
8024     -------------------------------
8025     Proc2  26 27  |  0  0 28  | 29
8026             0  0  | 31 32 33  |  0
8027 .ve
8028 
8029 
8030     Concepts: matrices^submatrices
8031 
8032 .seealso: MatCreateSubMatrices()
8033 @*/
8034 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
8035 {
8036   PetscErrorCode ierr;
8037   PetscMPIInt    size;
8038   Mat            *local;
8039   IS             iscoltmp;
8040 
8041   PetscFunctionBegin;
8042   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8043   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8044   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8045   PetscValidPointer(newmat,5);
8046   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
8047   PetscValidType(mat,1);
8048   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8049   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
8050 
8051   MatCheckPreallocated(mat,1);
8052   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8053 
8054   if (!iscol || isrow == iscol) {
8055     PetscBool   stride;
8056     PetscMPIInt grabentirematrix = 0,grab;
8057     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
8058     if (stride) {
8059       PetscInt first,step,n,rstart,rend;
8060       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
8061       if (step == 1) {
8062         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
8063         if (rstart == first) {
8064           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
8065           if (n == rend-rstart) {
8066             grabentirematrix = 1;
8067           }
8068         }
8069       }
8070     }
8071     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
8072     if (grab) {
8073       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
8074       if (cll == MAT_INITIAL_MATRIX) {
8075         *newmat = mat;
8076         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
8077       }
8078       PetscFunctionReturn(0);
8079     }
8080   }
8081 
8082   if (!iscol) {
8083     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
8084   } else {
8085     iscoltmp = iscol;
8086   }
8087 
8088   /* if original matrix is on just one processor then use submatrix generated */
8089   if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
8090     ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
8091     goto setproperties;
8092   } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
8093     ierr    = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
8094     *newmat = *local;
8095     ierr    = PetscFree(local);CHKERRQ(ierr);
8096     goto setproperties;
8097   } else if (!mat->ops->createsubmatrix) {
8098     /* Create a new matrix type that implements the operation using the full matrix */
8099     ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8100     switch (cll) {
8101     case MAT_INITIAL_MATRIX:
8102       ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
8103       break;
8104     case MAT_REUSE_MATRIX:
8105       ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
8106       break;
8107     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
8108     }
8109     ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8110     goto setproperties;
8111   }
8112 
8113   if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8114   ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8115   ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
8116   ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr);
8117 
8118   /* Propagate symmetry information for diagonal blocks */
8119 setproperties:
8120   if (isrow == iscoltmp) {
8121     if (mat->symmetric_set && mat->symmetric) {
8122       ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8123     }
8124     if (mat->structurally_symmetric_set && mat->structurally_symmetric) {
8125       ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
8126     }
8127     if (mat->hermitian_set && mat->hermitian) {
8128       ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
8129     }
8130     if (mat->spd_set && mat->spd) {
8131       ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
8132     }
8133   }
8134 
8135   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
8136   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
8137   PetscFunctionReturn(0);
8138 }
8139 
8140 /*@
8141    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
8142    used during the assembly process to store values that belong to
8143    other processors.
8144 
8145    Not Collective
8146 
8147    Input Parameters:
8148 +  mat   - the matrix
8149 .  size  - the initial size of the stash.
8150 -  bsize - the initial size of the block-stash(if used).
8151 
8152    Options Database Keys:
8153 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
8154 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
8155 
8156    Level: intermediate
8157 
8158    Notes:
8159      The block-stash is used for values set with MatSetValuesBlocked() while
8160      the stash is used for values set with MatSetValues()
8161 
8162      Run with the option -info and look for output of the form
8163      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
8164      to determine the appropriate value, MM, to use for size and
8165      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
8166      to determine the value, BMM to use for bsize
8167 
8168    Concepts: stash^setting matrix size
8169    Concepts: matrices^stash
8170 
8171 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
8172 
8173 @*/
8174 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
8175 {
8176   PetscErrorCode ierr;
8177 
8178   PetscFunctionBegin;
8179   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8180   PetscValidType(mat,1);
8181   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
8182   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
8183   PetscFunctionReturn(0);
8184 }
8185 
8186 /*@
8187    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
8188      the matrix
8189 
8190    Neighbor-wise Collective on Mat
8191 
8192    Input Parameters:
8193 +  mat   - the matrix
8194 .  x,y - the vectors
8195 -  w - where the result is stored
8196 
8197    Level: intermediate
8198 
8199    Notes:
8200     w may be the same vector as y.
8201 
8202     This allows one to use either the restriction or interpolation (its transpose)
8203     matrix to do the interpolation
8204 
8205     Concepts: interpolation
8206 
8207 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8208 
8209 @*/
8210 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
8211 {
8212   PetscErrorCode ierr;
8213   PetscInt       M,N,Ny;
8214 
8215   PetscFunctionBegin;
8216   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8217   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8218   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8219   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
8220   PetscValidType(A,1);
8221   MatCheckPreallocated(A,1);
8222   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8223   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8224   if (M == Ny) {
8225     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
8226   } else {
8227     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
8228   }
8229   PetscFunctionReturn(0);
8230 }
8231 
8232 /*@
8233    MatInterpolate - y = A*x or A'*x depending on the shape of
8234      the matrix
8235 
8236    Neighbor-wise Collective on Mat
8237 
8238    Input Parameters:
8239 +  mat   - the matrix
8240 -  x,y - the vectors
8241 
8242    Level: intermediate
8243 
8244    Notes:
8245     This allows one to use either the restriction or interpolation (its transpose)
8246     matrix to do the interpolation
8247 
8248    Concepts: matrices^interpolation
8249 
8250 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
8251 
8252 @*/
8253 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
8254 {
8255   PetscErrorCode ierr;
8256   PetscInt       M,N,Ny;
8257 
8258   PetscFunctionBegin;
8259   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8260   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8261   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8262   PetscValidType(A,1);
8263   MatCheckPreallocated(A,1);
8264   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8265   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8266   if (M == Ny) {
8267     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8268   } else {
8269     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8270   }
8271   PetscFunctionReturn(0);
8272 }
8273 
8274 /*@
8275    MatRestrict - y = A*x or A'*x
8276 
8277    Neighbor-wise Collective on Mat
8278 
8279    Input Parameters:
8280 +  mat   - the matrix
8281 -  x,y - the vectors
8282 
8283    Level: intermediate
8284 
8285    Notes:
8286     This allows one to use either the restriction or interpolation (its transpose)
8287     matrix to do the restriction
8288 
8289    Concepts: matrices^restriction
8290 
8291 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8292 
8293 @*/
8294 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8295 {
8296   PetscErrorCode ierr;
8297   PetscInt       M,N,Ny;
8298 
8299   PetscFunctionBegin;
8300   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8301   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
8302   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
8303   PetscValidType(A,1);
8304   MatCheckPreallocated(A,1);
8305 
8306   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
8307   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
8308   if (M == Ny) {
8309     ierr = MatMult(A,x,y);CHKERRQ(ierr);
8310   } else {
8311     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
8312   }
8313   PetscFunctionReturn(0);
8314 }
8315 
8316 /*@
8317    MatGetNullSpace - retrieves the null space of a matrix.
8318 
8319    Logically Collective on Mat and MatNullSpace
8320 
8321    Input Parameters:
8322 +  mat - the matrix
8323 -  nullsp - the null space object
8324 
8325    Level: developer
8326 
8327    Concepts: null space^attaching to matrix
8328 
8329 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8330 @*/
8331 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8332 {
8333   PetscFunctionBegin;
8334   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8335   PetscValidPointer(nullsp,2);
8336   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp;
8337   PetscFunctionReturn(0);
8338 }
8339 
8340 /*@
8341    MatSetNullSpace - attaches a null space to a matrix.
8342 
8343    Logically Collective on Mat and MatNullSpace
8344 
8345    Input Parameters:
8346 +  mat - the matrix
8347 -  nullsp - the null space object
8348 
8349    Level: advanced
8350 
8351    Notes:
8352       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8353 
8354       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8355       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8356 
8357       You can remove the null space by calling this routine with an nullsp of NULL
8358 
8359 
8360       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8361    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).
8362    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
8363    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
8364    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).
8365 
8366       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8367 
8368     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
8369     routine also automatically calls MatSetTransposeNullSpace().
8370 
8371    Concepts: null space^attaching to matrix
8372 
8373 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8374 @*/
8375 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8376 {
8377   PetscErrorCode ierr;
8378 
8379   PetscFunctionBegin;
8380   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8381   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8382   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8383   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
8384   mat->nullsp = nullsp;
8385   if (mat->symmetric_set && mat->symmetric) {
8386     ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr);
8387   }
8388   PetscFunctionReturn(0);
8389 }
8390 
8391 /*@
8392    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8393 
8394    Logically Collective on Mat and MatNullSpace
8395 
8396    Input Parameters:
8397 +  mat - the matrix
8398 -  nullsp - the null space object
8399 
8400    Level: developer
8401 
8402    Concepts: null space^attaching to matrix
8403 
8404 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8405 @*/
8406 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8407 {
8408   PetscFunctionBegin;
8409   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8410   PetscValidType(mat,1);
8411   PetscValidPointer(nullsp,2);
8412   *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp;
8413   PetscFunctionReturn(0);
8414 }
8415 
8416 /*@
8417    MatSetTransposeNullSpace - attaches a null space to a matrix.
8418 
8419    Logically Collective on Mat and MatNullSpace
8420 
8421    Input Parameters:
8422 +  mat - the matrix
8423 -  nullsp - the null space object
8424 
8425    Level: advanced
8426 
8427    Notes:
8428       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.
8429       You must also call MatSetNullSpace()
8430 
8431 
8432       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8433    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).
8434    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
8435    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
8436    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).
8437 
8438       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8439 
8440    Concepts: null space^attaching to matrix
8441 
8442 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8443 @*/
8444 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8445 {
8446   PetscErrorCode ierr;
8447 
8448   PetscFunctionBegin;
8449   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8450   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8451   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8452   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8453   mat->transnullsp = nullsp;
8454   PetscFunctionReturn(0);
8455 }
8456 
8457 /*@
8458    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8459         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8460 
8461    Logically Collective on Mat and MatNullSpace
8462 
8463    Input Parameters:
8464 +  mat - the matrix
8465 -  nullsp - the null space object
8466 
8467    Level: advanced
8468 
8469    Notes:
8470       Overwrites any previous near null space that may have been attached
8471 
8472       You can remove the null space by calling this routine with an nullsp of NULL
8473 
8474    Concepts: null space^attaching to matrix
8475 
8476 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8477 @*/
8478 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8479 {
8480   PetscErrorCode ierr;
8481 
8482   PetscFunctionBegin;
8483   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8484   PetscValidType(mat,1);
8485   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8486   MatCheckPreallocated(mat,1);
8487   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8488   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8489   mat->nearnullsp = nullsp;
8490   PetscFunctionReturn(0);
8491 }
8492 
8493 /*@
8494    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8495 
8496    Not Collective
8497 
8498    Input Parameters:
8499 .  mat - the matrix
8500 
8501    Output Parameters:
8502 .  nullsp - the null space object, NULL if not set
8503 
8504    Level: developer
8505 
8506    Concepts: null space^attaching to matrix
8507 
8508 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8509 @*/
8510 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8511 {
8512   PetscFunctionBegin;
8513   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8514   PetscValidType(mat,1);
8515   PetscValidPointer(nullsp,2);
8516   MatCheckPreallocated(mat,1);
8517   *nullsp = mat->nearnullsp;
8518   PetscFunctionReturn(0);
8519 }
8520 
8521 /*@C
8522    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8523 
8524    Collective on Mat
8525 
8526    Input Parameters:
8527 +  mat - the matrix
8528 .  row - row/column permutation
8529 .  fill - expected fill factor >= 1.0
8530 -  level - level of fill, for ICC(k)
8531 
8532    Notes:
8533    Probably really in-place only when level of fill is zero, otherwise allocates
8534    new space to store factored matrix and deletes previous memory.
8535 
8536    Most users should employ the simplified KSP interface for linear solvers
8537    instead of working directly with matrix algebra routines such as this.
8538    See, e.g., KSPCreate().
8539 
8540    Level: developer
8541 
8542    Concepts: matrices^incomplete Cholesky factorization
8543    Concepts: Cholesky factorization
8544 
8545 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8546 
8547     Developer Note: fortran interface is not autogenerated as the f90
8548     interface defintion cannot be generated correctly [due to MatFactorInfo]
8549 
8550 @*/
8551 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8552 {
8553   PetscErrorCode ierr;
8554 
8555   PetscFunctionBegin;
8556   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8557   PetscValidType(mat,1);
8558   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8559   PetscValidPointer(info,3);
8560   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8561   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8562   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8563   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8564   MatCheckPreallocated(mat,1);
8565   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8566   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8567   PetscFunctionReturn(0);
8568 }
8569 
8570 /*@
8571    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8572          ghosted ones.
8573 
8574    Not Collective
8575 
8576    Input Parameters:
8577 +  mat - the matrix
8578 -  diag = the diagonal values, including ghost ones
8579 
8580    Level: developer
8581 
8582    Notes:
8583     Works only for MPIAIJ and MPIBAIJ matrices
8584 
8585 .seealso: MatDiagonalScale()
8586 @*/
8587 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8588 {
8589   PetscErrorCode ierr;
8590   PetscMPIInt    size;
8591 
8592   PetscFunctionBegin;
8593   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8594   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8595   PetscValidType(mat,1);
8596 
8597   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8598   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8599   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8600   if (size == 1) {
8601     PetscInt n,m;
8602     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8603     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8604     if (m == n) {
8605       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8606     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8607   } else {
8608     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8609   }
8610   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8611   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8612   PetscFunctionReturn(0);
8613 }
8614 
8615 /*@
8616    MatGetInertia - Gets the inertia from a factored matrix
8617 
8618    Collective on Mat
8619 
8620    Input Parameter:
8621 .  mat - the matrix
8622 
8623    Output Parameters:
8624 +   nneg - number of negative eigenvalues
8625 .   nzero - number of zero eigenvalues
8626 -   npos - number of positive eigenvalues
8627 
8628    Level: advanced
8629 
8630    Notes:
8631     Matrix must have been factored by MatCholeskyFactor()
8632 
8633 
8634 @*/
8635 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8636 {
8637   PetscErrorCode ierr;
8638 
8639   PetscFunctionBegin;
8640   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8641   PetscValidType(mat,1);
8642   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8643   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8644   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8645   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8646   PetscFunctionReturn(0);
8647 }
8648 
8649 /* ----------------------------------------------------------------*/
8650 /*@C
8651    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8652 
8653    Neighbor-wise Collective on Mat and Vecs
8654 
8655    Input Parameters:
8656 +  mat - the factored matrix
8657 -  b - the right-hand-side vectors
8658 
8659    Output Parameter:
8660 .  x - the result vectors
8661 
8662    Notes:
8663    The vectors b and x cannot be the same.  I.e., one cannot
8664    call MatSolves(A,x,x).
8665 
8666    Notes:
8667    Most users should employ the simplified KSP interface for linear solvers
8668    instead of working directly with matrix algebra routines such as this.
8669    See, e.g., KSPCreate().
8670 
8671    Level: developer
8672 
8673    Concepts: matrices^triangular solves
8674 
8675 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8676 @*/
8677 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8678 {
8679   PetscErrorCode ierr;
8680 
8681   PetscFunctionBegin;
8682   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8683   PetscValidType(mat,1);
8684   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8685   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8686   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8687 
8688   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8689   MatCheckPreallocated(mat,1);
8690   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8691   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8692   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8693   PetscFunctionReturn(0);
8694 }
8695 
8696 /*@
8697    MatIsSymmetric - Test whether a matrix is symmetric
8698 
8699    Collective on Mat
8700 
8701    Input Parameter:
8702 +  A - the matrix to test
8703 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8704 
8705    Output Parameters:
8706 .  flg - the result
8707 
8708    Notes:
8709     For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8710 
8711    Level: intermediate
8712 
8713    Concepts: matrix^symmetry
8714 
8715 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8716 @*/
8717 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8718 {
8719   PetscErrorCode ierr;
8720 
8721   PetscFunctionBegin;
8722   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8723   PetscValidPointer(flg,2);
8724 
8725   if (!A->symmetric_set) {
8726     if (!A->ops->issymmetric) {
8727       MatType mattype;
8728       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8729       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8730     }
8731     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8732     if (!tol) {
8733       A->symmetric_set = PETSC_TRUE;
8734       A->symmetric     = *flg;
8735       if (A->symmetric) {
8736         A->structurally_symmetric_set = PETSC_TRUE;
8737         A->structurally_symmetric     = PETSC_TRUE;
8738       }
8739     }
8740   } else if (A->symmetric) {
8741     *flg = PETSC_TRUE;
8742   } else if (!tol) {
8743     *flg = PETSC_FALSE;
8744   } else {
8745     if (!A->ops->issymmetric) {
8746       MatType mattype;
8747       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8748       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8749     }
8750     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8751   }
8752   PetscFunctionReturn(0);
8753 }
8754 
8755 /*@
8756    MatIsHermitian - Test whether a matrix is Hermitian
8757 
8758    Collective on Mat
8759 
8760    Input Parameter:
8761 +  A - the matrix to test
8762 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8763 
8764    Output Parameters:
8765 .  flg - the result
8766 
8767    Level: intermediate
8768 
8769    Concepts: matrix^symmetry
8770 
8771 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8772           MatIsSymmetricKnown(), MatIsSymmetric()
8773 @*/
8774 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8775 {
8776   PetscErrorCode ierr;
8777 
8778   PetscFunctionBegin;
8779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8780   PetscValidPointer(flg,2);
8781 
8782   if (!A->hermitian_set) {
8783     if (!A->ops->ishermitian) {
8784       MatType mattype;
8785       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8786       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8787     }
8788     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8789     if (!tol) {
8790       A->hermitian_set = PETSC_TRUE;
8791       A->hermitian     = *flg;
8792       if (A->hermitian) {
8793         A->structurally_symmetric_set = PETSC_TRUE;
8794         A->structurally_symmetric     = PETSC_TRUE;
8795       }
8796     }
8797   } else if (A->hermitian) {
8798     *flg = PETSC_TRUE;
8799   } else if (!tol) {
8800     *flg = PETSC_FALSE;
8801   } else {
8802     if (!A->ops->ishermitian) {
8803       MatType mattype;
8804       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8805       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8806     }
8807     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8808   }
8809   PetscFunctionReturn(0);
8810 }
8811 
8812 /*@
8813    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8814 
8815    Not Collective
8816 
8817    Input Parameter:
8818 .  A - the matrix to check
8819 
8820    Output Parameters:
8821 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8822 -  flg - the result
8823 
8824    Level: advanced
8825 
8826    Concepts: matrix^symmetry
8827 
8828    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8829          if you want it explicitly checked
8830 
8831 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8832 @*/
8833 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8834 {
8835   PetscFunctionBegin;
8836   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8837   PetscValidPointer(set,2);
8838   PetscValidPointer(flg,3);
8839   if (A->symmetric_set) {
8840     *set = PETSC_TRUE;
8841     *flg = A->symmetric;
8842   } else {
8843     *set = PETSC_FALSE;
8844   }
8845   PetscFunctionReturn(0);
8846 }
8847 
8848 /*@
8849    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8850 
8851    Not Collective
8852 
8853    Input Parameter:
8854 .  A - the matrix to check
8855 
8856    Output Parameters:
8857 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8858 -  flg - the result
8859 
8860    Level: advanced
8861 
8862    Concepts: matrix^symmetry
8863 
8864    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8865          if you want it explicitly checked
8866 
8867 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8868 @*/
8869 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8870 {
8871   PetscFunctionBegin;
8872   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8873   PetscValidPointer(set,2);
8874   PetscValidPointer(flg,3);
8875   if (A->hermitian_set) {
8876     *set = PETSC_TRUE;
8877     *flg = A->hermitian;
8878   } else {
8879     *set = PETSC_FALSE;
8880   }
8881   PetscFunctionReturn(0);
8882 }
8883 
8884 /*@
8885    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8886 
8887    Collective on Mat
8888 
8889    Input Parameter:
8890 .  A - the matrix to test
8891 
8892    Output Parameters:
8893 .  flg - the result
8894 
8895    Level: intermediate
8896 
8897    Concepts: matrix^symmetry
8898 
8899 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8900 @*/
8901 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8902 {
8903   PetscErrorCode ierr;
8904 
8905   PetscFunctionBegin;
8906   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8907   PetscValidPointer(flg,2);
8908   if (!A->structurally_symmetric_set) {
8909     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8910     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8911 
8912     A->structurally_symmetric_set = PETSC_TRUE;
8913   }
8914   *flg = A->structurally_symmetric;
8915   PetscFunctionReturn(0);
8916 }
8917 
8918 /*@
8919    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8920        to be communicated to other processors during the MatAssemblyBegin/End() process
8921 
8922     Not collective
8923 
8924    Input Parameter:
8925 .   vec - the vector
8926 
8927    Output Parameters:
8928 +   nstash   - the size of the stash
8929 .   reallocs - the number of additional mallocs incurred.
8930 .   bnstash   - the size of the block stash
8931 -   breallocs - the number of additional mallocs incurred.in the block stash
8932 
8933    Level: advanced
8934 
8935 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8936 
8937 @*/
8938 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8939 {
8940   PetscErrorCode ierr;
8941 
8942   PetscFunctionBegin;
8943   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8944   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8945   PetscFunctionReturn(0);
8946 }
8947 
8948 /*@C
8949    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8950      parallel layout
8951 
8952    Collective on Mat
8953 
8954    Input Parameter:
8955 .  mat - the matrix
8956 
8957    Output Parameter:
8958 +   right - (optional) vector that the matrix can be multiplied against
8959 -   left - (optional) vector that the matrix vector product can be stored in
8960 
8961    Notes:
8962     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().
8963 
8964   Notes:
8965     These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8966 
8967   Level: advanced
8968 
8969 .seealso: MatCreate(), VecDestroy()
8970 @*/
8971 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8972 {
8973   PetscErrorCode ierr;
8974 
8975   PetscFunctionBegin;
8976   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8977   PetscValidType(mat,1);
8978   if (mat->ops->getvecs) {
8979     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8980   } else {
8981     PetscInt rbs,cbs;
8982     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8983     if (right) {
8984       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8985       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8986       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8987       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8988       ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr);
8989       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8990     }
8991     if (left) {
8992       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8993       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8994       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8995       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8996       ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr);
8997       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8998     }
8999   }
9000   PetscFunctionReturn(0);
9001 }
9002 
9003 /*@C
9004    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
9005      with default values.
9006 
9007    Not Collective
9008 
9009    Input Parameters:
9010 .    info - the MatFactorInfo data structure
9011 
9012 
9013    Notes:
9014     The solvers are generally used through the KSP and PC objects, for example
9015           PCLU, PCILU, PCCHOLESKY, PCICC
9016 
9017    Level: developer
9018 
9019 .seealso: MatFactorInfo
9020 
9021     Developer Note: fortran interface is not autogenerated as the f90
9022     interface defintion cannot be generated correctly [due to MatFactorInfo]
9023 
9024 @*/
9025 
9026 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
9027 {
9028   PetscErrorCode ierr;
9029 
9030   PetscFunctionBegin;
9031   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
9032   PetscFunctionReturn(0);
9033 }
9034 
9035 /*@
9036    MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
9037 
9038    Collective on Mat
9039 
9040    Input Parameters:
9041 +  mat - the factored matrix
9042 -  is - the index set defining the Schur indices (0-based)
9043 
9044    Notes:
9045     Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
9046 
9047    You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
9048 
9049    Level: developer
9050 
9051    Concepts:
9052 
9053 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
9054           MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
9055 
9056 @*/
9057 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
9058 {
9059   PetscErrorCode ierr,(*f)(Mat,IS);
9060 
9061   PetscFunctionBegin;
9062   PetscValidType(mat,1);
9063   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9064   PetscValidType(is,2);
9065   PetscValidHeaderSpecific(is,IS_CLASSID,2);
9066   PetscCheckSameComm(mat,1,is,2);
9067   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
9068   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
9069   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");
9070   if (mat->schur) {
9071     ierr = MatDestroy(&mat->schur);CHKERRQ(ierr);
9072   }
9073   ierr = (*f)(mat,is);CHKERRQ(ierr);
9074   if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
9075   ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr);
9076   PetscFunctionReturn(0);
9077 }
9078 
9079 /*@
9080   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
9081 
9082    Logically Collective on Mat
9083 
9084    Input Parameters:
9085 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
9086 .  S - location where to return the Schur complement, can be NULL
9087 -  status - the status of the Schur complement matrix, can be NULL
9088 
9089    Notes:
9090    You must call MatFactorSetSchurIS() before calling this routine.
9091 
9092    The routine provides a copy of the Schur matrix stored within the solver data structures.
9093    The caller must destroy the object when it is no longer needed.
9094    If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
9095 
9096    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)
9097 
9098    Developer Notes:
9099     The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
9100    matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
9101 
9102    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9103 
9104    Level: advanced
9105 
9106    References:
9107 
9108 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
9109 @*/
9110 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9111 {
9112   PetscErrorCode ierr;
9113 
9114   PetscFunctionBegin;
9115   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9116   if (S) PetscValidPointer(S,2);
9117   if (status) PetscValidPointer(status,3);
9118   if (S) {
9119     PetscErrorCode (*f)(Mat,Mat*);
9120 
9121     ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr);
9122     if (f) {
9123       ierr = (*f)(F,S);CHKERRQ(ierr);
9124     } else {
9125       ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr);
9126     }
9127   }
9128   if (status) *status = F->schur_status;
9129   PetscFunctionReturn(0);
9130 }
9131 
9132 /*@
9133   MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
9134 
9135    Logically Collective on Mat
9136 
9137    Input Parameters:
9138 +  F - the factored matrix obtained by calling MatGetFactor()
9139 .  *S - location where to return the Schur complement, can be NULL
9140 -  status - the status of the Schur complement matrix, can be NULL
9141 
9142    Notes:
9143    You must call MatFactorSetSchurIS() before calling this routine.
9144 
9145    Schur complement mode is currently implemented for sequential matrices.
9146    The routine returns a the Schur Complement stored within the data strutures of the solver.
9147    If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
9148    The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
9149 
9150    Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
9151 
9152    See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
9153 
9154    Level: advanced
9155 
9156    References:
9157 
9158 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9159 @*/
9160 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
9161 {
9162   PetscFunctionBegin;
9163   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9164   if (S) PetscValidPointer(S,2);
9165   if (status) PetscValidPointer(status,3);
9166   if (S) *S = F->schur;
9167   if (status) *status = F->schur_status;
9168   PetscFunctionReturn(0);
9169 }
9170 
9171 /*@
9172   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
9173 
9174    Logically Collective on Mat
9175 
9176    Input Parameters:
9177 +  F - the factored matrix obtained by calling MatGetFactor()
9178 .  *S - location where the Schur complement is stored
9179 -  status - the status of the Schur complement matrix (see MatFactorSchurStatus)
9180 
9181    Notes:
9182 
9183    Level: advanced
9184 
9185    References:
9186 
9187 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
9188 @*/
9189 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
9190 {
9191   PetscErrorCode ierr;
9192 
9193   PetscFunctionBegin;
9194   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9195   if (S) {
9196     PetscValidHeaderSpecific(*S,MAT_CLASSID,2);
9197     *S = NULL;
9198   }
9199   F->schur_status = status;
9200   ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr);
9201   PetscFunctionReturn(0);
9202 }
9203 
9204 /*@
9205   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
9206 
9207    Logically Collective on Mat
9208 
9209    Input Parameters:
9210 +  F - the factored matrix obtained by calling MatGetFactor()
9211 .  rhs - location where the right hand side of the Schur complement system is stored
9212 -  sol - location where the solution of the Schur complement system has to be returned
9213 
9214    Notes:
9215    The sizes of the vectors should match the size of the Schur complement
9216 
9217    Must be called after MatFactorSetSchurIS()
9218 
9219    Level: advanced
9220 
9221    References:
9222 
9223 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
9224 @*/
9225 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9226 {
9227   PetscErrorCode ierr;
9228 
9229   PetscFunctionBegin;
9230   PetscValidType(F,1);
9231   PetscValidType(rhs,2);
9232   PetscValidType(sol,3);
9233   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9234   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9235   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9236   PetscCheckSameComm(F,1,rhs,2);
9237   PetscCheckSameComm(F,1,sol,3);
9238   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9239   switch (F->schur_status) {
9240   case MAT_FACTOR_SCHUR_FACTORED:
9241     ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9242     break;
9243   case MAT_FACTOR_SCHUR_INVERTED:
9244     ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr);
9245     break;
9246   default:
9247     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9248     break;
9249   }
9250   PetscFunctionReturn(0);
9251 }
9252 
9253 /*@
9254   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9255 
9256    Logically Collective on Mat
9257 
9258    Input Parameters:
9259 +  F - the factored matrix obtained by calling MatGetFactor()
9260 .  rhs - location where the right hand side of the Schur complement system is stored
9261 -  sol - location where the solution of the Schur complement system has to be returned
9262 
9263    Notes:
9264    The sizes of the vectors should match the size of the Schur complement
9265 
9266    Must be called after MatFactorSetSchurIS()
9267 
9268    Level: advanced
9269 
9270    References:
9271 
9272 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9273 @*/
9274 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9275 {
9276   PetscErrorCode ierr;
9277 
9278   PetscFunctionBegin;
9279   PetscValidType(F,1);
9280   PetscValidType(rhs,2);
9281   PetscValidType(sol,3);
9282   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9283   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9284   PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
9285   PetscCheckSameComm(F,1,rhs,2);
9286   PetscCheckSameComm(F,1,sol,3);
9287   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9288   switch (F->schur_status) {
9289   case MAT_FACTOR_SCHUR_FACTORED:
9290     ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr);
9291     break;
9292   case MAT_FACTOR_SCHUR_INVERTED:
9293     ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr);
9294     break;
9295   default:
9296     SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9297     break;
9298   }
9299   PetscFunctionReturn(0);
9300 }
9301 
9302 /*@
9303   MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9304 
9305    Logically Collective on Mat
9306 
9307    Input Parameters:
9308 +  F - the factored matrix obtained by calling MatGetFactor()
9309 
9310    Notes:
9311     Must be called after MatFactorSetSchurIS().
9312 
9313    Call MatFactorGetSchurComplement() or  MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9314 
9315    Level: advanced
9316 
9317    References:
9318 
9319 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9320 @*/
9321 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9322 {
9323   PetscErrorCode ierr;
9324 
9325   PetscFunctionBegin;
9326   PetscValidType(F,1);
9327   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9328   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0);
9329   ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr);
9330   ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr);
9331   F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9332   PetscFunctionReturn(0);
9333 }
9334 
9335 /*@
9336   MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9337 
9338    Logically Collective on Mat
9339 
9340    Input Parameters:
9341 +  F - the factored matrix obtained by calling MatGetFactor()
9342 
9343    Notes:
9344     Must be called after MatFactorSetSchurIS().
9345 
9346    Level: advanced
9347 
9348    References:
9349 
9350 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9351 @*/
9352 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9353 {
9354   PetscErrorCode ierr;
9355 
9356   PetscFunctionBegin;
9357   PetscValidType(F,1);
9358   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9359   if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0);
9360   ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr);
9361   F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9362   PetscFunctionReturn(0);
9363 }
9364 
9365 /*@
9366    MatPtAP - Creates the matrix product C = P^T * A * P
9367 
9368    Neighbor-wise Collective on Mat
9369 
9370    Input Parameters:
9371 +  A - the matrix
9372 .  P - the projection matrix
9373 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9374 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9375           if the result is a dense matrix this is irrelevent
9376 
9377    Output Parameters:
9378 .  C - the product matrix
9379 
9380    Notes:
9381    C will be created and must be destroyed by the user with MatDestroy().
9382 
9383    This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes
9384    which inherit from AIJ.
9385 
9386    Level: intermediate
9387 
9388 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9389 @*/
9390 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9391 {
9392   PetscErrorCode ierr;
9393   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9394   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9395   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9396   PetscBool      sametype;
9397 
9398   PetscFunctionBegin;
9399   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9400   PetscValidType(A,1);
9401   MatCheckPreallocated(A,1);
9402   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9403   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9404   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9405   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9406   PetscValidType(P,2);
9407   MatCheckPreallocated(P,2);
9408   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9409   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9410 
9411   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);
9412   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);
9413   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9414   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9415 
9416   if (scall == MAT_REUSE_MATRIX) {
9417     PetscValidPointer(*C,5);
9418     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9419 
9420     if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX");
9421     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9422     ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9423     ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9424     ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9425     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9426     PetscFunctionReturn(0);
9427   }
9428 
9429   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9430   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9431 
9432   fA = A->ops->ptap;
9433   fP = P->ops->ptap;
9434   ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr);
9435   if (fP == fA && sametype) {
9436     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9437     ptap = fA;
9438   } else {
9439     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9440     char ptapname[256];
9441     ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr);
9442     ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9443     ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr);
9444     ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr);
9445     ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9446     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9447     if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname);
9448   }
9449 
9450   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9451   ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9452   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9453   if (A->symmetric_set && A->symmetric) {
9454     ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
9455   }
9456   PetscFunctionReturn(0);
9457 }
9458 
9459 /*@
9460    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9461 
9462    Neighbor-wise Collective on Mat
9463 
9464    Input Parameters:
9465 +  A - the matrix
9466 -  P - the projection matrix
9467 
9468    Output Parameters:
9469 .  C - the product matrix
9470 
9471    Notes:
9472    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9473    the user using MatDeatroy().
9474 
9475    This routine is currently only implemented for pairs of AIJ matrices and classes
9476    which inherit from AIJ.  C will be of type MATAIJ.
9477 
9478    Level: intermediate
9479 
9480 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9481 @*/
9482 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9483 {
9484   PetscErrorCode ierr;
9485 
9486   PetscFunctionBegin;
9487   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9488   PetscValidType(A,1);
9489   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9490   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9491   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9492   PetscValidType(P,2);
9493   MatCheckPreallocated(P,2);
9494   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9495   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9496   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9497   PetscValidType(C,3);
9498   MatCheckPreallocated(C,3);
9499   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9500   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);
9501   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);
9502   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);
9503   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);
9504   MatCheckPreallocated(A,1);
9505 
9506   if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first");
9507   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9508   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9509   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9510   PetscFunctionReturn(0);
9511 }
9512 
9513 /*@
9514    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9515 
9516    Neighbor-wise Collective on Mat
9517 
9518    Input Parameters:
9519 +  A - the matrix
9520 -  P - the projection matrix
9521 
9522    Output Parameters:
9523 .  C - the (i,j) structure of the product matrix
9524 
9525    Notes:
9526    C will be created and must be destroyed by the user with MatDestroy().
9527 
9528    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9529    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9530    this (i,j) structure by calling MatPtAPNumeric().
9531 
9532    Level: intermediate
9533 
9534 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9535 @*/
9536 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9537 {
9538   PetscErrorCode ierr;
9539 
9540   PetscFunctionBegin;
9541   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9542   PetscValidType(A,1);
9543   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9544   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9545   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9546   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9547   PetscValidType(P,2);
9548   MatCheckPreallocated(P,2);
9549   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9550   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9551   PetscValidPointer(C,3);
9552 
9553   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);
9554   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);
9555   MatCheckPreallocated(A,1);
9556 
9557   if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name);
9558   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9559   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9560   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9561 
9562   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9563   PetscFunctionReturn(0);
9564 }
9565 
9566 /*@
9567    MatRARt - Creates the matrix product C = R * A * R^T
9568 
9569    Neighbor-wise Collective on Mat
9570 
9571    Input Parameters:
9572 +  A - the matrix
9573 .  R - the projection matrix
9574 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9575 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9576           if the result is a dense matrix this is irrelevent
9577 
9578    Output Parameters:
9579 .  C - the product matrix
9580 
9581    Notes:
9582    C will be created and must be destroyed by the user with MatDestroy().
9583 
9584    This routine is currently only implemented for pairs of AIJ matrices and classes
9585    which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9586    parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9587    We recommend using MatPtAP().
9588 
9589    Level: intermediate
9590 
9591 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9592 @*/
9593 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9594 {
9595   PetscErrorCode ierr;
9596 
9597   PetscFunctionBegin;
9598   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9599   PetscValidType(A,1);
9600   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9601   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9602   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9603   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9604   PetscValidType(R,2);
9605   MatCheckPreallocated(R,2);
9606   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9607   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9608   PetscValidPointer(C,3);
9609   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);
9610 
9611   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9612   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9613   MatCheckPreallocated(A,1);
9614 
9615   if (!A->ops->rart) {
9616     Mat Rt;
9617     ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
9618     ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr);
9619     ierr = MatDestroy(&Rt);CHKERRQ(ierr);
9620     PetscFunctionReturn(0);
9621   }
9622   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9623   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9624   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9625   PetscFunctionReturn(0);
9626 }
9627 
9628 /*@
9629    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9630 
9631    Neighbor-wise Collective on Mat
9632 
9633    Input Parameters:
9634 +  A - the matrix
9635 -  R - the projection matrix
9636 
9637    Output Parameters:
9638 .  C - the product matrix
9639 
9640    Notes:
9641    C must have been created by calling MatRARtSymbolic and must be destroyed by
9642    the user using MatDestroy().
9643 
9644    This routine is currently only implemented for pairs of AIJ matrices and classes
9645    which inherit from AIJ.  C will be of type MATAIJ.
9646 
9647    Level: intermediate
9648 
9649 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9650 @*/
9651 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9652 {
9653   PetscErrorCode ierr;
9654 
9655   PetscFunctionBegin;
9656   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9657   PetscValidType(A,1);
9658   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9659   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9660   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9661   PetscValidType(R,2);
9662   MatCheckPreallocated(R,2);
9663   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9664   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9665   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9666   PetscValidType(C,3);
9667   MatCheckPreallocated(C,3);
9668   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9669   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);
9670   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);
9671   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);
9672   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);
9673   MatCheckPreallocated(A,1);
9674 
9675   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9676   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9677   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9678   PetscFunctionReturn(0);
9679 }
9680 
9681 /*@
9682    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9683 
9684    Neighbor-wise Collective on Mat
9685 
9686    Input Parameters:
9687 +  A - the matrix
9688 -  R - the projection matrix
9689 
9690    Output Parameters:
9691 .  C - the (i,j) structure of the product matrix
9692 
9693    Notes:
9694    C will be created and must be destroyed by the user with MatDestroy().
9695 
9696    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9697    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9698    this (i,j) structure by calling MatRARtNumeric().
9699 
9700    Level: intermediate
9701 
9702 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9703 @*/
9704 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9705 {
9706   PetscErrorCode ierr;
9707 
9708   PetscFunctionBegin;
9709   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9710   PetscValidType(A,1);
9711   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9712   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9713   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9714   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9715   PetscValidType(R,2);
9716   MatCheckPreallocated(R,2);
9717   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9718   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9719   PetscValidPointer(C,3);
9720 
9721   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);
9722   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);
9723   MatCheckPreallocated(A,1);
9724   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9725   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9726   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9727 
9728   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9729   PetscFunctionReturn(0);
9730 }
9731 
9732 /*@
9733    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9734 
9735    Neighbor-wise Collective on Mat
9736 
9737    Input Parameters:
9738 +  A - the left matrix
9739 .  B - the right matrix
9740 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9741 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9742           if the result is a dense matrix this is irrelevent
9743 
9744    Output Parameters:
9745 .  C - the product matrix
9746 
9747    Notes:
9748    Unless scall is MAT_REUSE_MATRIX C will be created.
9749 
9750    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
9751    call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9752 
9753    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9754    actually needed.
9755 
9756    If you have many matrices with the same non-zero structure to multiply, you
9757    should either
9758 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9759 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9760    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
9761    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9762 
9763    Level: intermediate
9764 
9765 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9766 @*/
9767 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9768 {
9769   PetscErrorCode ierr;
9770   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9771   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9772   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9773 
9774   PetscFunctionBegin;
9775   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9776   PetscValidType(A,1);
9777   MatCheckPreallocated(A,1);
9778   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9779   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9780   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9781   PetscValidType(B,2);
9782   MatCheckPreallocated(B,2);
9783   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9784   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9785   PetscValidPointer(C,3);
9786   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9787   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);
9788   if (scall == MAT_REUSE_MATRIX) {
9789     PetscValidPointer(*C,5);
9790     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9791     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9792     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9793     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9794     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9795     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9796     PetscFunctionReturn(0);
9797   }
9798   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9799   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9800 
9801   fA = A->ops->matmult;
9802   fB = B->ops->matmult;
9803   if (fB == fA) {
9804     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9805     mult = fB;
9806   } else {
9807     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9808     char multname[256];
9809     ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr);
9810     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
9811     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
9812     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
9813     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9814     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9815     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);
9816   }
9817   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9818   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9819   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9820   PetscFunctionReturn(0);
9821 }
9822 
9823 /*@
9824    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9825    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9826 
9827    Neighbor-wise Collective on Mat
9828 
9829    Input Parameters:
9830 +  A - the left matrix
9831 .  B - the right matrix
9832 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9833       if C is a dense matrix this is irrelevent
9834 
9835    Output Parameters:
9836 .  C - the product matrix
9837 
9838    Notes:
9839    Unless scall is MAT_REUSE_MATRIX C will be created.
9840 
9841    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9842    actually needed.
9843 
9844    This routine is currently implemented for
9845     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9846     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9847     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9848 
9849    Level: intermediate
9850 
9851    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9852      We should incorporate them into PETSc.
9853 
9854 .seealso: MatMatMult(), MatMatMultNumeric()
9855 @*/
9856 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9857 {
9858   PetscErrorCode ierr;
9859   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9860   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9861   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9862 
9863   PetscFunctionBegin;
9864   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9865   PetscValidType(A,1);
9866   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9867   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9868 
9869   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9870   PetscValidType(B,2);
9871   MatCheckPreallocated(B,2);
9872   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9873   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9874   PetscValidPointer(C,3);
9875 
9876   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);
9877   if (fill == PETSC_DEFAULT) fill = 2.0;
9878   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9879   MatCheckPreallocated(A,1);
9880 
9881   Asymbolic = A->ops->matmultsymbolic;
9882   Bsymbolic = B->ops->matmultsymbolic;
9883   if (Asymbolic == Bsymbolic) {
9884     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9885     symbolic = Bsymbolic;
9886   } else { /* dispatch based on the type of A and B */
9887     char symbolicname[256];
9888     ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr);
9889     ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9890     ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr);
9891     ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr);
9892     ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr);
9893     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9894     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);
9895   }
9896   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9897   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9898   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9899   PetscFunctionReturn(0);
9900 }
9901 
9902 /*@
9903    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9904    Call this routine after first calling MatMatMultSymbolic().
9905 
9906    Neighbor-wise Collective on Mat
9907 
9908    Input Parameters:
9909 +  A - the left matrix
9910 -  B - the right matrix
9911 
9912    Output Parameters:
9913 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9914 
9915    Notes:
9916    C must have been created with MatMatMultSymbolic().
9917 
9918    This routine is currently implemented for
9919     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9920     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9921     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9922 
9923    Level: intermediate
9924 
9925 .seealso: MatMatMult(), MatMatMultSymbolic()
9926 @*/
9927 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9928 {
9929   PetscErrorCode ierr;
9930 
9931   PetscFunctionBegin;
9932   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9933   PetscFunctionReturn(0);
9934 }
9935 
9936 /*@
9937    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9938 
9939    Neighbor-wise Collective on Mat
9940 
9941    Input Parameters:
9942 +  A - the left matrix
9943 .  B - the right matrix
9944 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9945 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9946 
9947    Output Parameters:
9948 .  C - the product matrix
9949 
9950    Notes:
9951    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9952 
9953    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9954 
9955   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9956    actually needed.
9957 
9958    This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class,
9959    and for pairs of MPIDense matrices.
9960 
9961    Options Database Keys:
9962 +  -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the
9963                                                                 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity;
9964                                                                 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity.
9965 
9966    Level: intermediate
9967 
9968 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9969 @*/
9970 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9971 {
9972   PetscErrorCode ierr;
9973   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9974   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9975 
9976   PetscFunctionBegin;
9977   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9978   PetscValidType(A,1);
9979   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9980   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9981   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9982   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9983   PetscValidType(B,2);
9984   MatCheckPreallocated(B,2);
9985   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9986   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9987   PetscValidPointer(C,3);
9988   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);
9989   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9990   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9991   MatCheckPreallocated(A,1);
9992 
9993   fA = A->ops->mattransposemult;
9994   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9995   fB = B->ops->mattransposemult;
9996   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9997   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);
9998 
9999   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10000   if (scall == MAT_INITIAL_MATRIX) {
10001     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10002     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
10003     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
10004   }
10005   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10006   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
10007   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
10008   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
10009   PetscFunctionReturn(0);
10010 }
10011 
10012 /*@
10013    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
10014 
10015    Neighbor-wise Collective on Mat
10016 
10017    Input Parameters:
10018 +  A - the left matrix
10019 .  B - the right matrix
10020 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10021 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
10022 
10023    Output Parameters:
10024 .  C - the product matrix
10025 
10026    Notes:
10027    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
10028 
10029    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
10030 
10031   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10032    actually needed.
10033 
10034    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
10035    which inherit from SeqAIJ.  C will be of same type as the input matrices.
10036 
10037    Level: intermediate
10038 
10039 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
10040 @*/
10041 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
10042 {
10043   PetscErrorCode ierr;
10044   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
10045   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
10046   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
10047 
10048   PetscFunctionBegin;
10049   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10050   PetscValidType(A,1);
10051   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10052   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10053   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10054   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10055   PetscValidType(B,2);
10056   MatCheckPreallocated(B,2);
10057   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10058   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10059   PetscValidPointer(C,3);
10060   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);
10061   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10062   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
10063   MatCheckPreallocated(A,1);
10064 
10065   fA = A->ops->transposematmult;
10066   fB = B->ops->transposematmult;
10067   if (fB==fA) {
10068     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10069     transposematmult = fA;
10070   } else {
10071     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
10072     char multname[256];
10073     ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr);
10074     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10075     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10076     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10077     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
10078     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
10079     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);
10080   }
10081   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10082   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
10083   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
10084   PetscFunctionReturn(0);
10085 }
10086 
10087 /*@
10088    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
10089 
10090    Neighbor-wise Collective on Mat
10091 
10092    Input Parameters:
10093 +  A - the left matrix
10094 .  B - the middle matrix
10095 .  C - the right matrix
10096 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10097 -  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
10098           if the result is a dense matrix this is irrelevent
10099 
10100    Output Parameters:
10101 .  D - the product matrix
10102 
10103    Notes:
10104    Unless scall is MAT_REUSE_MATRIX D will be created.
10105 
10106    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
10107 
10108    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
10109    actually needed.
10110 
10111    If you have many matrices with the same non-zero structure to multiply, you
10112    should use MAT_REUSE_MATRIX in all calls but the first or
10113 
10114    Level: intermediate
10115 
10116 .seealso: MatMatMult, MatPtAP()
10117 @*/
10118 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
10119 {
10120   PetscErrorCode ierr;
10121   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10122   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10123   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
10124   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
10125 
10126   PetscFunctionBegin;
10127   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
10128   PetscValidType(A,1);
10129   MatCheckPreallocated(A,1);
10130   if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10131   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10132   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10133   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
10134   PetscValidType(B,2);
10135   MatCheckPreallocated(B,2);
10136   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10137   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10138   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
10139   PetscValidPointer(C,3);
10140   MatCheckPreallocated(C,3);
10141   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10142   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10143   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);
10144   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);
10145   if (scall == MAT_REUSE_MATRIX) {
10146     PetscValidPointer(*D,6);
10147     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
10148     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10149     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10150     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10151     PetscFunctionReturn(0);
10152   }
10153   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
10154   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
10155 
10156   fA = A->ops->matmatmult;
10157   fB = B->ops->matmatmult;
10158   fC = C->ops->matmatmult;
10159   if (fA == fB && fA == fC) {
10160     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
10161     mult = fA;
10162   } else {
10163     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
10164     char multname[256];
10165     ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr);
10166     ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr);
10167     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10168     ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr);
10169     ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr);
10170     ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr);
10171     ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr);
10172     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
10173     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);
10174   }
10175   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10176   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
10177   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
10178   PetscFunctionReturn(0);
10179 }
10180 
10181 /*@
10182    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
10183 
10184    Collective on Mat
10185 
10186    Input Parameters:
10187 +  mat - the matrix
10188 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
10189 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
10190 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10191 
10192    Output Parameter:
10193 .  matredundant - redundant matrix
10194 
10195    Notes:
10196    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
10197    original matrix has not changed from that last call to MatCreateRedundantMatrix().
10198 
10199    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
10200    calling it.
10201 
10202    Level: advanced
10203 
10204    Concepts: subcommunicator
10205    Concepts: duplicate matrix
10206 
10207 .seealso: MatDestroy()
10208 @*/
10209 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
10210 {
10211   PetscErrorCode ierr;
10212   MPI_Comm       comm;
10213   PetscMPIInt    size;
10214   PetscInt       mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
10215   Mat_Redundant  *redund=NULL;
10216   PetscSubcomm   psubcomm=NULL;
10217   MPI_Comm       subcomm_in=subcomm;
10218   Mat            *matseq;
10219   IS             isrow,iscol;
10220   PetscBool      newsubcomm=PETSC_FALSE;
10221 
10222   PetscFunctionBegin;
10223   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10224   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
10225     PetscValidPointer(*matredundant,5);
10226     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
10227   }
10228 
10229   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
10230   if (size == 1 || nsubcomm == 1) {
10231     if (reuse == MAT_INITIAL_MATRIX) {
10232       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
10233     } else {
10234       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");
10235       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10236     }
10237     PetscFunctionReturn(0);
10238   }
10239 
10240   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10241   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10242   MatCheckPreallocated(mat,1);
10243 
10244   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10245   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
10246     /* create psubcomm, then get subcomm */
10247     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10248     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10249     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10250 
10251     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
10252     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
10253     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
10254     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
10255     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
10256     newsubcomm = PETSC_TRUE;
10257     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10258   }
10259 
10260   /* get isrow, iscol and a local sequential matrix matseq[0] */
10261   if (reuse == MAT_INITIAL_MATRIX) {
10262     mloc_sub = PETSC_DECIDE;
10263     nloc_sub = PETSC_DECIDE;
10264     if (bs < 1) {
10265       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10266       ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr);
10267     } else {
10268       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10269       ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr);
10270     }
10271     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10272     rstart = rend - mloc_sub;
10273     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10274     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10275   } else { /* reuse == MAT_REUSE_MATRIX */
10276     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");
10277     /* retrieve subcomm */
10278     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10279     redund = (*matredundant)->redundant;
10280     isrow  = redund->isrow;
10281     iscol  = redund->iscol;
10282     matseq = redund->matseq;
10283   }
10284   ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10285 
10286   /* get matredundant over subcomm */
10287   if (reuse == MAT_INITIAL_MATRIX) {
10288     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr);
10289 
10290     /* create a supporting struct and attach it to C for reuse */
10291     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10292     (*matredundant)->redundant = redund;
10293     redund->isrow              = isrow;
10294     redund->iscol              = iscol;
10295     redund->matseq             = matseq;
10296     if (newsubcomm) {
10297       redund->subcomm          = subcomm;
10298     } else {
10299       redund->subcomm          = MPI_COMM_NULL;
10300     }
10301   } else {
10302     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10303   }
10304   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10305   PetscFunctionReturn(0);
10306 }
10307 
10308 /*@C
10309    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10310    a given 'mat' object. Each submatrix can span multiple procs.
10311 
10312    Collective on Mat
10313 
10314    Input Parameters:
10315 +  mat - the matrix
10316 .  subcomm - the subcommunicator obtained by com_split(comm)
10317 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10318 
10319    Output Parameter:
10320 .  subMat - 'parallel submatrices each spans a given subcomm
10321 
10322   Notes:
10323   The submatrix partition across processors is dictated by 'subComm' a
10324   communicator obtained by com_split(comm). The comm_split
10325   is not restriced to be grouped with consecutive original ranks.
10326 
10327   Due the comm_split() usage, the parallel layout of the submatrices
10328   map directly to the layout of the original matrix [wrt the local
10329   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10330   into the 'DiagonalMat' of the subMat, hence it is used directly from
10331   the subMat. However the offDiagMat looses some columns - and this is
10332   reconstructed with MatSetValues()
10333 
10334   Level: advanced
10335 
10336   Concepts: subcommunicator
10337   Concepts: submatrices
10338 
10339 .seealso: MatCreateSubMatrices()
10340 @*/
10341 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10342 {
10343   PetscErrorCode ierr;
10344   PetscMPIInt    commsize,subCommSize;
10345 
10346   PetscFunctionBegin;
10347   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10348   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10349   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10350 
10351   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");
10352   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10353   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10354   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10355   PetscFunctionReturn(0);
10356 }
10357 
10358 /*@
10359    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10360 
10361    Not Collective
10362 
10363    Input Arguments:
10364    mat - matrix to extract local submatrix from
10365    isrow - local row indices for submatrix
10366    iscol - local column indices for submatrix
10367 
10368    Output Arguments:
10369    submat - the submatrix
10370 
10371    Level: intermediate
10372 
10373    Notes:
10374    The submat should be returned with MatRestoreLocalSubMatrix().
10375 
10376    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10377    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10378 
10379    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10380    MatSetValuesBlockedLocal() will also be implemented.
10381 
10382    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10383    matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided.
10384 
10385 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10386 @*/
10387 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10388 {
10389   PetscErrorCode ierr;
10390 
10391   PetscFunctionBegin;
10392   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10393   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10394   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10395   PetscCheckSameComm(isrow,2,iscol,3);
10396   PetscValidPointer(submat,4);
10397   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10398 
10399   if (mat->ops->getlocalsubmatrix) {
10400     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10401   } else {
10402     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10403   }
10404   PetscFunctionReturn(0);
10405 }
10406 
10407 /*@
10408    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10409 
10410    Not Collective
10411 
10412    Input Arguments:
10413    mat - matrix to extract local submatrix from
10414    isrow - local row indices for submatrix
10415    iscol - local column indices for submatrix
10416    submat - the submatrix
10417 
10418    Level: intermediate
10419 
10420 .seealso: MatGetLocalSubMatrix()
10421 @*/
10422 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10423 {
10424   PetscErrorCode ierr;
10425 
10426   PetscFunctionBegin;
10427   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10428   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10429   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10430   PetscCheckSameComm(isrow,2,iscol,3);
10431   PetscValidPointer(submat,4);
10432   if (*submat) {
10433     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10434   }
10435 
10436   if (mat->ops->restorelocalsubmatrix) {
10437     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10438   } else {
10439     ierr = MatDestroy(submat);CHKERRQ(ierr);
10440   }
10441   *submat = NULL;
10442   PetscFunctionReturn(0);
10443 }
10444 
10445 /* --------------------------------------------------------*/
10446 /*@
10447    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10448 
10449    Collective on Mat
10450 
10451    Input Parameter:
10452 .  mat - the matrix
10453 
10454    Output Parameter:
10455 .  is - if any rows have zero diagonals this contains the list of them
10456 
10457    Level: developer
10458 
10459    Concepts: matrix-vector product
10460 
10461 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10462 @*/
10463 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10464 {
10465   PetscErrorCode ierr;
10466 
10467   PetscFunctionBegin;
10468   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10469   PetscValidType(mat,1);
10470   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10471   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10472 
10473   if (!mat->ops->findzerodiagonals) {
10474     Vec                diag;
10475     const PetscScalar *a;
10476     PetscInt          *rows;
10477     PetscInt           rStart, rEnd, r, nrow = 0;
10478 
10479     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10480     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10481     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10482     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10483     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10484     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10485     nrow = 0;
10486     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10487     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10488     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10489     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10490   } else {
10491     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10492   }
10493   PetscFunctionReturn(0);
10494 }
10495 
10496 /*@
10497    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10498 
10499    Collective on Mat
10500 
10501    Input Parameter:
10502 .  mat - the matrix
10503 
10504    Output Parameter:
10505 .  is - contains the list of rows with off block diagonal entries
10506 
10507    Level: developer
10508 
10509    Concepts: matrix-vector product
10510 
10511 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10512 @*/
10513 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10514 {
10515   PetscErrorCode ierr;
10516 
10517   PetscFunctionBegin;
10518   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10519   PetscValidType(mat,1);
10520   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10521   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10522 
10523   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10524   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10525   PetscFunctionReturn(0);
10526 }
10527 
10528 /*@C
10529   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10530 
10531   Collective on Mat
10532 
10533   Input Parameters:
10534 . mat - the matrix
10535 
10536   Output Parameters:
10537 . values - the block inverses in column major order (FORTRAN-like)
10538 
10539    Note:
10540    This routine is not available from Fortran.
10541 
10542   Level: advanced
10543 
10544 .seealso: MatInvertBockDiagonalMat
10545 @*/
10546 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10547 {
10548   PetscErrorCode ierr;
10549 
10550   PetscFunctionBegin;
10551   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10552   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10553   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10554   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10555   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10556   PetscFunctionReturn(0);
10557 }
10558 
10559 /*@C
10560   MatInvertVariableBlockDiagonal - Inverts the block diagonal entries.
10561 
10562   Collective on Mat
10563 
10564   Input Parameters:
10565 + mat - the matrix
10566 . nblocks - the number of blocks
10567 - bsizes - the size of each block
10568 
10569   Output Parameters:
10570 . values - the block inverses in column major order (FORTRAN-like)
10571 
10572    Note:
10573    This routine is not available from Fortran.
10574 
10575   Level: advanced
10576 
10577 .seealso: MatInvertBockDiagonal()
10578 @*/
10579 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values)
10580 {
10581   PetscErrorCode ierr;
10582 
10583   PetscFunctionBegin;
10584   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10585   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10586   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10587   if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10588   ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr);
10589   PetscFunctionReturn(0);
10590 }
10591 
10592 /*@
10593   MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A
10594 
10595   Collective on Mat
10596 
10597   Input Parameters:
10598 . A - the matrix
10599 
10600   Output Parameters:
10601 . C - matrix with inverted block diagonal of A.  This matrix should be created and may have its type set.
10602 
10603   Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C
10604 
10605   Level: advanced
10606 
10607 .seealso: MatInvertBockDiagonal()
10608 @*/
10609 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C)
10610 {
10611   PetscErrorCode     ierr;
10612   const PetscScalar *vals;
10613   PetscInt          *dnnz;
10614   PetscInt           M,N,m,n,rstart,rend,bs,i,j;
10615 
10616   PetscFunctionBegin;
10617   ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr);
10618   ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr);
10619   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
10620   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
10621   ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
10622   ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr);
10623   ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr);
10624   for (j = 0; j < m/bs; j++) dnnz[j] = 1;
10625   ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr);
10626   ierr = PetscFree(dnnz);CHKERRQ(ierr);
10627   ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr);
10628   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr);
10629   for (i = rstart/bs; i < rend/bs; i++) {
10630     ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr);
10631   }
10632   ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10633   ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10634   ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr);
10635   PetscFunctionReturn(0);
10636 }
10637 
10638 /*@C
10639     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10640     via MatTransposeColoringCreate().
10641 
10642     Collective on MatTransposeColoring
10643 
10644     Input Parameter:
10645 .   c - coloring context
10646 
10647     Level: intermediate
10648 
10649 .seealso: MatTransposeColoringCreate()
10650 @*/
10651 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10652 {
10653   PetscErrorCode       ierr;
10654   MatTransposeColoring matcolor=*c;
10655 
10656   PetscFunctionBegin;
10657   if (!matcolor) PetscFunctionReturn(0);
10658   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10659 
10660   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10661   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10662   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10663   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10664   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10665   if (matcolor->brows>0) {
10666     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10667   }
10668   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10669   PetscFunctionReturn(0);
10670 }
10671 
10672 /*@C
10673     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10674     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10675     MatTransposeColoring to sparse B.
10676 
10677     Collective on MatTransposeColoring
10678 
10679     Input Parameters:
10680 +   B - sparse matrix B
10681 .   Btdense - symbolic dense matrix B^T
10682 -   coloring - coloring context created with MatTransposeColoringCreate()
10683 
10684     Output Parameter:
10685 .   Btdense - dense matrix B^T
10686 
10687     Level: advanced
10688 
10689      Notes:
10690     These are used internally for some implementations of MatRARt()
10691 
10692 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10693 
10694 .keywords: coloring
10695 @*/
10696 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10697 {
10698   PetscErrorCode ierr;
10699 
10700   PetscFunctionBegin;
10701   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10702   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10703   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10704 
10705   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10706   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10707   PetscFunctionReturn(0);
10708 }
10709 
10710 /*@C
10711     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10712     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10713     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10714     Csp from Cden.
10715 
10716     Collective on MatTransposeColoring
10717 
10718     Input Parameters:
10719 +   coloring - coloring context created with MatTransposeColoringCreate()
10720 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10721 
10722     Output Parameter:
10723 .   Csp - sparse matrix
10724 
10725     Level: advanced
10726 
10727      Notes:
10728     These are used internally for some implementations of MatRARt()
10729 
10730 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10731 
10732 .keywords: coloring
10733 @*/
10734 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10735 {
10736   PetscErrorCode ierr;
10737 
10738   PetscFunctionBegin;
10739   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10740   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10741   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10742 
10743   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10744   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10745   PetscFunctionReturn(0);
10746 }
10747 
10748 /*@C
10749    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10750 
10751    Collective on Mat
10752 
10753    Input Parameters:
10754 +  mat - the matrix product C
10755 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10756 
10757     Output Parameter:
10758 .   color - the new coloring context
10759 
10760     Level: intermediate
10761 
10762 .seealso: MatTransposeColoringDestroy(),  MatTransColoringApplySpToDen(),
10763            MatTransColoringApplyDenToSp()
10764 @*/
10765 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10766 {
10767   MatTransposeColoring c;
10768   MPI_Comm             comm;
10769   PetscErrorCode       ierr;
10770 
10771   PetscFunctionBegin;
10772   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10773   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10774   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10775 
10776   c->ctype = iscoloring->ctype;
10777   if (mat->ops->transposecoloringcreate) {
10778     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10779   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10780 
10781   *color = c;
10782   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10783   PetscFunctionReturn(0);
10784 }
10785 
10786 /*@
10787       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10788         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10789         same, otherwise it will be larger
10790 
10791      Not Collective
10792 
10793   Input Parameter:
10794 .    A  - the matrix
10795 
10796   Output Parameter:
10797 .    state - the current state
10798 
10799   Notes:
10800     You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10801          different matrices
10802 
10803   Level: intermediate
10804 
10805 @*/
10806 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10807 {
10808   PetscFunctionBegin;
10809   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10810   *state = mat->nonzerostate;
10811   PetscFunctionReturn(0);
10812 }
10813 
10814 /*@
10815       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10816                  matrices from each processor
10817 
10818     Collective on MPI_Comm
10819 
10820    Input Parameters:
10821 +    comm - the communicators the parallel matrix will live on
10822 .    seqmat - the input sequential matrices
10823 .    n - number of local columns (or PETSC_DECIDE)
10824 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10825 
10826    Output Parameter:
10827 .    mpimat - the parallel matrix generated
10828 
10829     Level: advanced
10830 
10831    Notes:
10832     The number of columns of the matrix in EACH processor MUST be the same.
10833 
10834 @*/
10835 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10836 {
10837   PetscErrorCode ierr;
10838 
10839   PetscFunctionBegin;
10840   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10841   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");
10842 
10843   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10844   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10845   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10846   PetscFunctionReturn(0);
10847 }
10848 
10849 /*@
10850      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10851                  ranks' ownership ranges.
10852 
10853     Collective on A
10854 
10855    Input Parameters:
10856 +    A   - the matrix to create subdomains from
10857 -    N   - requested number of subdomains
10858 
10859 
10860    Output Parameters:
10861 +    n   - number of subdomains resulting on this rank
10862 -    iss - IS list with indices of subdomains on this rank
10863 
10864     Level: advanced
10865 
10866     Notes:
10867     number of subdomains must be smaller than the communicator size
10868 @*/
10869 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10870 {
10871   MPI_Comm        comm,subcomm;
10872   PetscMPIInt     size,rank,color;
10873   PetscInt        rstart,rend,k;
10874   PetscErrorCode  ierr;
10875 
10876   PetscFunctionBegin;
10877   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10878   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10879   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10880   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);
10881   *n = 1;
10882   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10883   color = rank/k;
10884   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10885   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10886   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10887   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10888   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10889   PetscFunctionReturn(0);
10890 }
10891 
10892 /*@
10893    MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10894 
10895    If the interpolation and restriction operators are the same, uses MatPtAP.
10896    If they are not the same, use MatMatMatMult.
10897 
10898    Once the coarse grid problem is constructed, correct for interpolation operators
10899    that are not of full rank, which can legitimately happen in the case of non-nested
10900    geometric multigrid.
10901 
10902    Input Parameters:
10903 +  restrct - restriction operator
10904 .  dA - fine grid matrix
10905 .  interpolate - interpolation operator
10906 .  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10907 -  fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10908 
10909    Output Parameters:
10910 .  A - the Galerkin coarse matrix
10911 
10912    Options Database Key:
10913 .  -pc_mg_galerkin <both,pmat,mat,none>
10914 
10915    Level: developer
10916 
10917 .keywords: MG, multigrid, Galerkin
10918 
10919 .seealso: MatPtAP(), MatMatMatMult()
10920 @*/
10921 PetscErrorCode  MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10922 {
10923   PetscErrorCode ierr;
10924   IS             zerorows;
10925   Vec            diag;
10926 
10927   PetscFunctionBegin;
10928   if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10929   /* Construct the coarse grid matrix */
10930   if (interpolate == restrct) {
10931     ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10932   } else {
10933     ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr);
10934   }
10935 
10936   /* If the interpolation matrix is not of full rank, A will have zero rows.
10937      This can legitimately happen in the case of non-nested geometric multigrid.
10938      In that event, we set the rows of the matrix to the rows of the identity,
10939      ignoring the equations (as the RHS will also be zero). */
10940 
10941   ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr);
10942 
10943   if (zerorows != NULL) { /* if there are any zero rows */
10944     ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr);
10945     ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr);
10946     ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr);
10947     ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr);
10948     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10949     ierr = ISDestroy(&zerorows);CHKERRQ(ierr);
10950   }
10951   PetscFunctionReturn(0);
10952 }
10953 
10954 /*@C
10955     MatSetOperation - Allows user to set a matrix operation for any matrix type
10956 
10957    Logically Collective on Mat
10958 
10959     Input Parameters:
10960 +   mat - the matrix
10961 .   op - the name of the operation
10962 -   f - the function that provides the operation
10963 
10964    Level: developer
10965 
10966     Usage:
10967 $      extern PetscErrorCode usermult(Mat,Vec,Vec);
10968 $      ierr = MatCreateXXX(comm,...&A);
10969 $      ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult);
10970 
10971     Notes:
10972     See the file include/petscmat.h for a complete list of matrix
10973     operations, which all have the form MATOP_<OPERATION>, where
10974     <OPERATION> is the name (in all capital letters) of the
10975     user interface routine (e.g., MatMult() -> MATOP_MULT).
10976 
10977     All user-provided functions (except for MATOP_DESTROY) should have the same calling
10978     sequence as the usual matrix interface routines, since they
10979     are intended to be accessed via the usual matrix interface
10980     routines, e.g.,
10981 $       MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec)
10982 
10983     In particular each function MUST return an error code of 0 on success and
10984     nonzero on failure.
10985 
10986     This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type.
10987 
10988 .keywords: matrix, set, operation
10989 
10990 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation()
10991 @*/
10992 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void))
10993 {
10994   PetscFunctionBegin;
10995   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10996   if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) {
10997     mat->ops->viewnative = mat->ops->view;
10998   }
10999   (((void(**)(void))mat->ops)[op]) = f;
11000   PetscFunctionReturn(0);
11001 }
11002 
11003 /*@C
11004     MatGetOperation - Gets a matrix operation for any matrix type.
11005 
11006     Not Collective
11007 
11008     Input Parameters:
11009 +   mat - the matrix
11010 -   op - the name of the operation
11011 
11012     Output Parameter:
11013 .   f - the function that provides the operation
11014 
11015     Level: developer
11016 
11017     Usage:
11018 $      PetscErrorCode (*usermult)(Mat,Vec,Vec);
11019 $      ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult);
11020 
11021     Notes:
11022     See the file include/petscmat.h for a complete list of matrix
11023     operations, which all have the form MATOP_<OPERATION>, where
11024     <OPERATION> is the name (in all capital letters) of the
11025     user interface routine (e.g., MatMult() -> MATOP_MULT).
11026 
11027     This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type.
11028 
11029 .keywords: matrix, get, operation
11030 
11031 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation()
11032 @*/
11033 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void))
11034 {
11035   PetscFunctionBegin;
11036   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11037   *f = (((void (**)(void))mat->ops)[op]);
11038   PetscFunctionReturn(0);
11039 }
11040 
11041 /*@
11042     MatHasOperation - Determines whether the given matrix supports the particular
11043     operation.
11044 
11045    Not Collective
11046 
11047    Input Parameters:
11048 +  mat - the matrix
11049 -  op - the operation, for example, MATOP_GET_DIAGONAL
11050 
11051    Output Parameter:
11052 .  has - either PETSC_TRUE or PETSC_FALSE
11053 
11054    Level: advanced
11055 
11056    Notes:
11057    See the file include/petscmat.h for a complete list of matrix
11058    operations, which all have the form MATOP_<OPERATION>, where
11059    <OPERATION> is the name (in all capital letters) of the
11060    user-level routine.  E.g., MatNorm() -> MATOP_NORM.
11061 
11062 .keywords: matrix, has, operation
11063 
11064 .seealso: MatCreateShell()
11065 @*/
11066 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has)
11067 {
11068   PetscErrorCode ierr;
11069 
11070   PetscFunctionBegin;
11071   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11072   PetscValidType(mat,1);
11073   PetscValidPointer(has,3);
11074   if (mat->ops->hasoperation) {
11075     ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr);
11076   } else {
11077     if (((void**)mat->ops)[op]) *has =  PETSC_TRUE;
11078     else {
11079       *has = PETSC_FALSE;
11080       if (op == MATOP_CREATE_SUBMATRIX) {
11081         PetscMPIInt size;
11082 
11083         ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
11084         if (size == 1) {
11085           ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr);
11086         }
11087       }
11088     }
11089   }
11090   PetscFunctionReturn(0);
11091 }
11092 
11093 /*@
11094     MatHasCongruentLayouts - Determines whether the rows and columns layouts
11095     of the matrix are congruent
11096 
11097    Collective on mat
11098 
11099    Input Parameters:
11100 .  mat - the matrix
11101 
11102    Output Parameter:
11103 .  cong - either PETSC_TRUE or PETSC_FALSE
11104 
11105    Level: beginner
11106 
11107    Notes:
11108 
11109 .keywords: matrix, has
11110 
11111 .seealso: MatCreate(), MatSetSizes()
11112 @*/
11113 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong)
11114 {
11115   PetscErrorCode ierr;
11116 
11117   PetscFunctionBegin;
11118   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11119   PetscValidType(mat,1);
11120   PetscValidPointer(cong,2);
11121   if (!mat->rmap || !mat->cmap) {
11122     *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE;
11123     PetscFunctionReturn(0);
11124   }
11125   if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */
11126     ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr);
11127     if (*cong) mat->congruentlayouts = 1;
11128     else       mat->congruentlayouts = 0;
11129   } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE;
11130   PetscFunctionReturn(0);
11131 }
11132 
11133 /*@
11134     MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse,
11135     e.g., matrx product of MatPtAP.
11136 
11137    Collective on mat
11138 
11139    Input Parameters:
11140 .  mat - the matrix
11141 
11142    Output Parameter:
11143 .  mat - the matrix with intermediate data structures released
11144 
11145    Level: advanced
11146 
11147    Notes:
11148 
11149 .keywords: matrix
11150 
11151 .seealso: MatPtAP(), MatMatMult()
11152 @*/
11153 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat)
11154 {
11155   PetscErrorCode ierr;
11156 
11157   PetscFunctionBegin;
11158   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
11159   PetscValidType(mat,1);
11160   if (mat->ops->freeintermediatedatastructures) {
11161     ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr);
11162   }
11163   PetscFunctionReturn(0);
11164 }
11165