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