xref: /petsc/src/mat/interface/matrix.c (revision 183a438d00460f76454d6178dfee464d405a69ff)
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 to 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    Notes:
8146       This null space is used by solvers. Overwrites any previous null space that may have been attached
8147 
8148    Concepts: null space^attaching to matrix
8149 
8150 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
8151 @*/
8152 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8153 {
8154   PetscFunctionBegin;
8155   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8156   PetscValidType(mat,1);
8157   PetscValidPointer(nullsp,2);
8158   *nullsp = mat->transnullsp;
8159   PetscFunctionReturn(0);
8160 }
8161 
8162 #undef __FUNCT__
8163 #define __FUNCT__ "MatSetTransposeNullSpace"
8164 /*@
8165    MatSetTransposeNullSpace - attaches a null space to a matrix.
8166 
8167    Logically Collective on Mat and MatNullSpace
8168 
8169    Input Parameters:
8170 +  mat - the matrix
8171 -  nullsp - the null space object
8172 
8173    Level: advanced
8174 
8175    Notes:
8176       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.
8177       You must also call MatSetNullSpace()
8178 
8179 
8180       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8181    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).
8182    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
8183    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
8184    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).
8185 
8186       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8187 
8188    Concepts: null space^attaching to matrix
8189 
8190 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetNullSpace(), MatNullSpaceRemove()
8191 @*/
8192 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8193 {
8194   PetscErrorCode ierr;
8195 
8196   PetscFunctionBegin;
8197   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8198   PetscValidType(mat,1);
8199   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8200   MatCheckPreallocated(mat,1);
8201   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8202   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8203   mat->transnullsp = nullsp;
8204   PetscFunctionReturn(0);
8205 }
8206 
8207 #undef __FUNCT__
8208 #define __FUNCT__ "MatSetNearNullSpace"
8209 /*@
8210    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8211         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8212 
8213    Logically Collective on Mat and MatNullSpace
8214 
8215    Input Parameters:
8216 +  mat - the matrix
8217 -  nullsp - the null space object
8218 
8219    Level: advanced
8220 
8221    Notes:
8222       Overwrites any previous near null space that may have been attached
8223 
8224       You can remove the null space by calling this routine with an nullsp of NULL
8225 
8226    Concepts: null space^attaching to matrix
8227 
8228 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody()
8229 @*/
8230 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8231 {
8232   PetscErrorCode ierr;
8233 
8234   PetscFunctionBegin;
8235   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8236   PetscValidType(mat,1);
8237   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8238   MatCheckPreallocated(mat,1);
8239   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8240   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8241   mat->nearnullsp = nullsp;
8242   PetscFunctionReturn(0);
8243 }
8244 
8245 #undef __FUNCT__
8246 #define __FUNCT__ "MatGetNearNullSpace"
8247 /*@
8248    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8249 
8250    Not Collective
8251 
8252    Input Parameters:
8253 .  mat - the matrix
8254 
8255    Output Parameters:
8256 .  nullsp - the null space object, NULL if not set
8257 
8258    Level: developer
8259 
8260    Concepts: null space^attaching to matrix
8261 
8262 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
8263 @*/
8264 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8265 {
8266   PetscFunctionBegin;
8267   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8268   PetscValidType(mat,1);
8269   PetscValidPointer(nullsp,2);
8270   MatCheckPreallocated(mat,1);
8271   *nullsp = mat->nearnullsp;
8272   PetscFunctionReturn(0);
8273 }
8274 
8275 #undef __FUNCT__
8276 #define __FUNCT__ "MatICCFactor"
8277 /*@C
8278    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8279 
8280    Collective on Mat
8281 
8282    Input Parameters:
8283 +  mat - the matrix
8284 .  row - row/column permutation
8285 .  fill - expected fill factor >= 1.0
8286 -  level - level of fill, for ICC(k)
8287 
8288    Notes:
8289    Probably really in-place only when level of fill is zero, otherwise allocates
8290    new space to store factored matrix and deletes previous memory.
8291 
8292    Most users should employ the simplified KSP interface for linear solvers
8293    instead of working directly with matrix algebra routines such as this.
8294    See, e.g., KSPCreate().
8295 
8296    Level: developer
8297 
8298    Concepts: matrices^incomplete Cholesky factorization
8299    Concepts: Cholesky factorization
8300 
8301 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8302 
8303     Developer Note: fortran interface is not autogenerated as the f90
8304     interface defintion cannot be generated correctly [due to MatFactorInfo]
8305 
8306 @*/
8307 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8308 {
8309   PetscErrorCode ierr;
8310 
8311   PetscFunctionBegin;
8312   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8313   PetscValidType(mat,1);
8314   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8315   PetscValidPointer(info,3);
8316   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8317   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8318   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8319   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8320   MatCheckPreallocated(mat,1);
8321   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8322   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8323   PetscFunctionReturn(0);
8324 }
8325 
8326 #undef __FUNCT__
8327 #define __FUNCT__ "MatSetValuesAdifor"
8328 /*@
8329    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
8330 
8331    Not Collective
8332 
8333    Input Parameters:
8334 +  mat - the matrix
8335 .  nl - leading dimension of v
8336 -  v - the values compute with ADIFOR
8337 
8338    Level: developer
8339 
8340    Notes:
8341      Must call MatSetColoring() before using this routine. Also this matrix must already
8342      have its nonzero pattern determined.
8343 
8344 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8345           MatSetValues(), MatSetColoring()
8346 @*/
8347 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8348 {
8349   PetscErrorCode ierr;
8350 
8351   PetscFunctionBegin;
8352   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8353   PetscValidType(mat,1);
8354   PetscValidPointer(v,3);
8355 
8356   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8357   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
8358   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8359   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
8360   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
8361   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8362   PetscFunctionReturn(0);
8363 }
8364 
8365 #undef __FUNCT__
8366 #define __FUNCT__ "MatDiagonalScaleLocal"
8367 /*@
8368    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8369          ghosted ones.
8370 
8371    Not Collective
8372 
8373    Input Parameters:
8374 +  mat - the matrix
8375 -  diag = the diagonal values, including ghost ones
8376 
8377    Level: developer
8378 
8379    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8380 
8381 .seealso: MatDiagonalScale()
8382 @*/
8383 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8384 {
8385   PetscErrorCode ierr;
8386   PetscMPIInt    size;
8387 
8388   PetscFunctionBegin;
8389   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8390   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8391   PetscValidType(mat,1);
8392 
8393   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8394   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8395   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8396   if (size == 1) {
8397     PetscInt n,m;
8398     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8399     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8400     if (m == n) {
8401       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8402     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8403   } else {
8404     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8405   }
8406   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8407   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8408   PetscFunctionReturn(0);
8409 }
8410 
8411 #undef __FUNCT__
8412 #define __FUNCT__ "MatGetInertia"
8413 /*@
8414    MatGetInertia - Gets the inertia from a factored matrix
8415 
8416    Collective on Mat
8417 
8418    Input Parameter:
8419 .  mat - the matrix
8420 
8421    Output Parameters:
8422 +   nneg - number of negative eigenvalues
8423 .   nzero - number of zero eigenvalues
8424 -   npos - number of positive eigenvalues
8425 
8426    Level: advanced
8427 
8428    Notes: Matrix must have been factored by MatCholeskyFactor()
8429 
8430 
8431 @*/
8432 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8433 {
8434   PetscErrorCode ierr;
8435 
8436   PetscFunctionBegin;
8437   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8438   PetscValidType(mat,1);
8439   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8440   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8441   if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8442   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8443   PetscFunctionReturn(0);
8444 }
8445 
8446 /* ----------------------------------------------------------------*/
8447 #undef __FUNCT__
8448 #define __FUNCT__ "MatSolves"
8449 /*@C
8450    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8451 
8452    Neighbor-wise Collective on Mat and Vecs
8453 
8454    Input Parameters:
8455 +  mat - the factored matrix
8456 -  b - the right-hand-side vectors
8457 
8458    Output Parameter:
8459 .  x - the result vectors
8460 
8461    Notes:
8462    The vectors b and x cannot be the same.  I.e., one cannot
8463    call MatSolves(A,x,x).
8464 
8465    Notes:
8466    Most users should employ the simplified KSP interface for linear solvers
8467    instead of working directly with matrix algebra routines such as this.
8468    See, e.g., KSPCreate().
8469 
8470    Level: developer
8471 
8472    Concepts: matrices^triangular solves
8473 
8474 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8475 @*/
8476 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8477 {
8478   PetscErrorCode ierr;
8479 
8480   PetscFunctionBegin;
8481   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8482   PetscValidType(mat,1);
8483   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8484   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8485   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8486 
8487   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8488   MatCheckPreallocated(mat,1);
8489   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8490   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8491   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8492   PetscFunctionReturn(0);
8493 }
8494 
8495 #undef __FUNCT__
8496 #define __FUNCT__ "MatIsSymmetric"
8497 /*@
8498    MatIsSymmetric - Test whether a matrix is symmetric
8499 
8500    Collective on Mat
8501 
8502    Input Parameter:
8503 +  A - the matrix to test
8504 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8505 
8506    Output Parameters:
8507 .  flg - the result
8508 
8509    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8510 
8511    Level: intermediate
8512 
8513    Concepts: matrix^symmetry
8514 
8515 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8516 @*/
8517 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8518 {
8519   PetscErrorCode ierr;
8520 
8521   PetscFunctionBegin;
8522   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8523   PetscValidPointer(flg,2);
8524 
8525   if (!A->symmetric_set) {
8526     if (!A->ops->issymmetric) {
8527       MatType mattype;
8528       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8529       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8530     }
8531     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8532     if (!tol) {
8533       A->symmetric_set = PETSC_TRUE;
8534       A->symmetric     = *flg;
8535       if (A->symmetric) {
8536         A->structurally_symmetric_set = PETSC_TRUE;
8537         A->structurally_symmetric     = PETSC_TRUE;
8538       }
8539     }
8540   } else if (A->symmetric) {
8541     *flg = PETSC_TRUE;
8542   } else if (!tol) {
8543     *flg = PETSC_FALSE;
8544   } else {
8545     if (!A->ops->issymmetric) {
8546       MatType mattype;
8547       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8548       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8549     }
8550     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8551   }
8552   PetscFunctionReturn(0);
8553 }
8554 
8555 #undef __FUNCT__
8556 #define __FUNCT__ "MatIsHermitian"
8557 /*@
8558    MatIsHermitian - Test whether a matrix is Hermitian
8559 
8560    Collective on Mat
8561 
8562    Input Parameter:
8563 +  A - the matrix to test
8564 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8565 
8566    Output Parameters:
8567 .  flg - the result
8568 
8569    Level: intermediate
8570 
8571    Concepts: matrix^symmetry
8572 
8573 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8574           MatIsSymmetricKnown(), MatIsSymmetric()
8575 @*/
8576 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8577 {
8578   PetscErrorCode ierr;
8579 
8580   PetscFunctionBegin;
8581   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8582   PetscValidPointer(flg,2);
8583 
8584   if (!A->hermitian_set) {
8585     if (!A->ops->ishermitian) {
8586       MatType mattype;
8587       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8588       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8589     }
8590     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8591     if (!tol) {
8592       A->hermitian_set = PETSC_TRUE;
8593       A->hermitian     = *flg;
8594       if (A->hermitian) {
8595         A->structurally_symmetric_set = PETSC_TRUE;
8596         A->structurally_symmetric     = PETSC_TRUE;
8597       }
8598     }
8599   } else if (A->hermitian) {
8600     *flg = PETSC_TRUE;
8601   } else if (!tol) {
8602     *flg = PETSC_FALSE;
8603   } else {
8604     if (!A->ops->ishermitian) {
8605       MatType mattype;
8606       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8607       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8608     }
8609     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8610   }
8611   PetscFunctionReturn(0);
8612 }
8613 
8614 #undef __FUNCT__
8615 #define __FUNCT__ "MatIsSymmetricKnown"
8616 /*@
8617    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8618 
8619    Not Collective
8620 
8621    Input Parameter:
8622 .  A - the matrix to check
8623 
8624    Output Parameters:
8625 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8626 -  flg - the result
8627 
8628    Level: advanced
8629 
8630    Concepts: matrix^symmetry
8631 
8632    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8633          if you want it explicitly checked
8634 
8635 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8636 @*/
8637 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8638 {
8639   PetscFunctionBegin;
8640   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8641   PetscValidPointer(set,2);
8642   PetscValidPointer(flg,3);
8643   if (A->symmetric_set) {
8644     *set = PETSC_TRUE;
8645     *flg = A->symmetric;
8646   } else {
8647     *set = PETSC_FALSE;
8648   }
8649   PetscFunctionReturn(0);
8650 }
8651 
8652 #undef __FUNCT__
8653 #define __FUNCT__ "MatIsHermitianKnown"
8654 /*@
8655    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8656 
8657    Not Collective
8658 
8659    Input Parameter:
8660 .  A - the matrix to check
8661 
8662    Output Parameters:
8663 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8664 -  flg - the result
8665 
8666    Level: advanced
8667 
8668    Concepts: matrix^symmetry
8669 
8670    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8671          if you want it explicitly checked
8672 
8673 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8674 @*/
8675 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8676 {
8677   PetscFunctionBegin;
8678   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8679   PetscValidPointer(set,2);
8680   PetscValidPointer(flg,3);
8681   if (A->hermitian_set) {
8682     *set = PETSC_TRUE;
8683     *flg = A->hermitian;
8684   } else {
8685     *set = PETSC_FALSE;
8686   }
8687   PetscFunctionReturn(0);
8688 }
8689 
8690 #undef __FUNCT__
8691 #define __FUNCT__ "MatIsStructurallySymmetric"
8692 /*@
8693    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8694 
8695    Collective on Mat
8696 
8697    Input Parameter:
8698 .  A - the matrix to test
8699 
8700    Output Parameters:
8701 .  flg - the result
8702 
8703    Level: intermediate
8704 
8705    Concepts: matrix^symmetry
8706 
8707 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8708 @*/
8709 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8710 {
8711   PetscErrorCode ierr;
8712 
8713   PetscFunctionBegin;
8714   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8715   PetscValidPointer(flg,2);
8716   if (!A->structurally_symmetric_set) {
8717     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8718     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8719 
8720     A->structurally_symmetric_set = PETSC_TRUE;
8721   }
8722   *flg = A->structurally_symmetric;
8723   PetscFunctionReturn(0);
8724 }
8725 
8726 #undef __FUNCT__
8727 #define __FUNCT__ "MatStashGetInfo"
8728 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8729 /*@
8730    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8731        to be communicated to other processors during the MatAssemblyBegin/End() process
8732 
8733     Not collective
8734 
8735    Input Parameter:
8736 .   vec - the vector
8737 
8738    Output Parameters:
8739 +   nstash   - the size of the stash
8740 .   reallocs - the number of additional mallocs incurred.
8741 .   bnstash   - the size of the block stash
8742 -   breallocs - the number of additional mallocs incurred.in the block stash
8743 
8744    Level: advanced
8745 
8746 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8747 
8748 @*/
8749 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8750 {
8751   PetscErrorCode ierr;
8752 
8753   PetscFunctionBegin;
8754   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8755   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8756   PetscFunctionReturn(0);
8757 }
8758 
8759 #undef __FUNCT__
8760 #define __FUNCT__ "MatCreateVecs"
8761 /*@C
8762    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8763      parallel layout
8764 
8765    Collective on Mat
8766 
8767    Input Parameter:
8768 .  mat - the matrix
8769 
8770    Output Parameter:
8771 +   right - (optional) vector that the matrix can be multiplied against
8772 -   left - (optional) vector that the matrix vector product can be stored in
8773 
8774    Notes:
8775     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().
8776 
8777   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8778 
8779   Level: advanced
8780 
8781 .seealso: MatCreate(), VecDestroy()
8782 @*/
8783 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8784 {
8785   PetscErrorCode ierr;
8786 
8787   PetscFunctionBegin;
8788   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8789   PetscValidType(mat,1);
8790   if (mat->ops->getvecs) {
8791     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8792   } else {
8793     PetscInt rbs,cbs;
8794     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8795     if (right) {
8796       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8797       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8798       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8799       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8800       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8801       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8802     }
8803     if (left) {
8804       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8805       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8806       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8807       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8808       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8809       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8810     }
8811   }
8812   PetscFunctionReturn(0);
8813 }
8814 
8815 #undef __FUNCT__
8816 #define __FUNCT__ "MatFactorInfoInitialize"
8817 /*@C
8818    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8819      with default values.
8820 
8821    Not Collective
8822 
8823    Input Parameters:
8824 .    info - the MatFactorInfo data structure
8825 
8826 
8827    Notes: The solvers are generally used through the KSP and PC objects, for example
8828           PCLU, PCILU, PCCHOLESKY, PCICC
8829 
8830    Level: developer
8831 
8832 .seealso: MatFactorInfo
8833 
8834     Developer Note: fortran interface is not autogenerated as the f90
8835     interface defintion cannot be generated correctly [due to MatFactorInfo]
8836 
8837 @*/
8838 
8839 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8840 {
8841   PetscErrorCode ierr;
8842 
8843   PetscFunctionBegin;
8844   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8845   PetscFunctionReturn(0);
8846 }
8847 
8848 #undef __FUNCT__
8849 #define __FUNCT__ "MatFactorSetSchurIS"
8850 /*@
8851    MatFactorSetSchurIS - Set indices corresponding to the Schur complement
8852 
8853    Collective on Mat
8854 
8855    Input Parameters:
8856 +  mat - the factored matrix
8857 -  is - the index set defining the Schur indices (0-based)
8858 
8859    Notes:
8860 
8861    Level: developer
8862 
8863    Concepts:
8864 
8865 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8866 
8867 @*/
8868 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8869 {
8870   PetscErrorCode ierr,(*f)(Mat,IS);
8871 
8872   PetscFunctionBegin;
8873   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8874   PetscValidType(mat,1);
8875   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8876   PetscValidType(is,2);
8877   PetscCheckSameComm(mat,1,is,2);
8878   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8879   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8880   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");
8881   ierr = (*f)(mat,is);CHKERRQ(ierr);
8882   PetscFunctionReturn(0);
8883 }
8884 
8885 #undef __FUNCT__
8886 #define __FUNCT__ "MatFactorCreateSchurComplement"
8887 /*@
8888   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8889 
8890    Logically Collective on Mat
8891 
8892    Input Parameters:
8893 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8894 .  *S - location where to return the Schur complement (MATDENSE)
8895 
8896    Notes:
8897    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.
8898    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse
8899 
8900    Level: advanced
8901 
8902    References:
8903 
8904 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8905 @*/
8906 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8907 {
8908   PetscErrorCode ierr;
8909 
8910   PetscFunctionBegin;
8911   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8912   ierr = PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr);
8913   PetscFunctionReturn(0);
8914 }
8915 
8916 #undef __FUNCT__
8917 #define __FUNCT__ "MatFactorGetSchurComplement"
8918 /*@
8919   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data
8920 
8921    Logically Collective on Mat
8922 
8923    Input Parameters:
8924 +  F - the factored matrix obtained by calling MatGetFactor()
8925 .  *S - location where to return the Schur complement (in MATDENSE format)
8926 
8927    Notes:
8928    Schur complement mode is currently implemented for sequential matrices.
8929    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.
8930    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.
8931 
8932    Level: advanced
8933 
8934    References:
8935 
8936 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8937 @*/
8938 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8939 {
8940   PetscErrorCode ierr;
8941 
8942   PetscFunctionBegin;
8943   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8944   ierr = PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr);
8945   PetscFunctionReturn(0);
8946 }
8947 
8948 #undef __FUNCT__
8949 #define __FUNCT__ "MatFactorRestoreSchurComplement"
8950 /*@
8951   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8952 
8953    Logically Collective on Mat
8954 
8955    Input Parameters:
8956 +  F - the factored matrix obtained by calling MatGetFactor()
8957 .  *S - location where the Schur complement is stored
8958 
8959    Notes:
8960 
8961    Level: advanced
8962 
8963    References:
8964 
8965 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8966 @*/
8967 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8968 {
8969   PetscErrorCode ierr;
8970 
8971   PetscFunctionBegin;
8972   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8973   PetscValidHeaderSpecific(*S,MAT_CLASSID,1);
8974   ierr = MatDestroy(S);CHKERRQ(ierr);
8975   PetscFunctionReturn(0);
8976 }
8977 
8978 #undef __FUNCT__
8979 #define __FUNCT__ "MatFactorSolveSchurComplementTranspose"
8980 /*@
8981   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8982 
8983    Logically Collective on Mat
8984 
8985    Input Parameters:
8986 +  F - the factored matrix obtained by calling MatGetFactor()
8987 .  rhs - location where the right hand side of the Schur complement system is stored
8988 -  sol - location where the solution of the Schur complement system has to be returned
8989 
8990    Notes:
8991    The sizes of the vectors should match the size of the Schur complement
8992 
8993    Level: advanced
8994 
8995    References:
8996 
8997 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8998 @*/
8999 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
9000 {
9001   PetscErrorCode ierr;
9002 
9003   PetscFunctionBegin;
9004   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9005   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9006   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
9007   PetscCheckSameComm(F,1,rhs,2);
9008   PetscCheckSameComm(F,1,sol,3);
9009   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
9010   PetscFunctionReturn(0);
9011 }
9012 
9013 #undef __FUNCT__
9014 #define __FUNCT__ "MatFactorSolveSchurComplement"
9015 /*@
9016   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
9017 
9018    Logically Collective on Mat
9019 
9020    Input Parameters:
9021 +  F - the factored matrix obtained by calling MatGetFactor()
9022 .  rhs - location where the right hand side of the Schur complement system is stored
9023 -  sol - location where the solution of the Schur complement system has to be returned
9024 
9025    Notes:
9026    The sizes of the vectors should match the size of the Schur complement
9027 
9028    Level: advanced
9029 
9030    References:
9031 
9032 .seealso: MatGetFactor(), MatFactorSetSchurIS()
9033 @*/
9034 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9035 {
9036   PetscErrorCode ierr;
9037 
9038   PetscFunctionBegin;
9039   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9040   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
9041   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
9042   PetscCheckSameComm(F,1,rhs,2);
9043   PetscCheckSameComm(F,1,sol,3);
9044   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
9045   PetscFunctionReturn(0);
9046 }
9047 
9048 #undef __FUNCT__
9049 #define __FUNCT__ "MatFactorInvertSchurComplement"
9050 /*@
9051   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step
9052 
9053    Logically Collective on Mat
9054 
9055    Input Parameters:
9056 +  F - the factored matrix obtained by calling MatGetFactor()
9057 
9058    Notes:
9059 
9060    Level: advanced
9061 
9062    References:
9063 
9064 .seealso: MatGetFactor(), MatFactorSetSchurIS()
9065 @*/
9066 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9067 {
9068   PetscErrorCode ierr;
9069 
9070   PetscFunctionBegin;
9071   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
9072   ierr = PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));CHKERRQ(ierr);
9073   PetscFunctionReturn(0);
9074 }
9075 
9076 
9077 #undef __FUNCT__
9078 #define __FUNCT__ "MatPtAP"
9079 /*@
9080    MatPtAP - Creates the matrix product C = P^T * A * P
9081 
9082    Neighbor-wise Collective on Mat
9083 
9084    Input Parameters:
9085 +  A - the matrix
9086 .  P - the projection matrix
9087 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9088 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9089           if the result is a dense matrix this is irrelevent
9090 
9091    Output Parameters:
9092 .  C - the product matrix
9093 
9094    Notes:
9095    C will be created and must be destroyed by the user with MatDestroy().
9096 
9097    This routine is currently only implemented for pairs of AIJ matrices and classes
9098    which inherit from AIJ.
9099 
9100    Level: intermediate
9101 
9102 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9103 @*/
9104 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9105 {
9106   PetscErrorCode ierr;
9107   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9108   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9109   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9110   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9111 
9112   PetscFunctionBegin;
9113   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr);
9114   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr);
9115 
9116   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9117   PetscValidType(A,1);
9118   MatCheckPreallocated(A,1);
9119   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9120   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9121   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9122   PetscValidType(P,2);
9123   MatCheckPreallocated(P,2);
9124   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9125   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9126 
9127   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);
9128   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);
9129   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9130   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9131 
9132   if (scall == MAT_REUSE_MATRIX) {
9133     PetscValidPointer(*C,5);
9134     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9135     if (viatranspose || viamatmatmatmult) {
9136       Mat Pt;
9137       ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9138       if (viamatmatmatmult) {
9139         ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9140       } else {
9141         Mat AP;
9142         ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9143         ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9144         ierr = MatDestroy(&AP);CHKERRQ(ierr);
9145       }
9146       ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9147     } else {
9148       ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9149       ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9150       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9151       ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9152       ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9153     }
9154     PetscFunctionReturn(0);
9155   }
9156 
9157   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9158   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9159 
9160   fA = A->ops->ptap;
9161   fP = P->ops->ptap;
9162   if (fP == fA) {
9163     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9164     ptap = fA;
9165   } else {
9166     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9167     char ptapname[256];
9168     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
9169     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9170     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
9171     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
9172     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9173     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9174     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);
9175   }
9176 
9177   if (viatranspose || viamatmatmatmult) {
9178     Mat Pt;
9179     ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9180     if (viamatmatmatmult) {
9181       ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9182       ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr);
9183     } else {
9184       Mat AP;
9185       ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9186       ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9187       ierr = MatDestroy(&AP);CHKERRQ(ierr);
9188       ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr);
9189     }
9190     ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9191   } else {
9192     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9193     ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9194     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9195   }
9196   PetscFunctionReturn(0);
9197 }
9198 
9199 #undef __FUNCT__
9200 #define __FUNCT__ "MatPtAPNumeric"
9201 /*@
9202    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9203 
9204    Neighbor-wise Collective on Mat
9205 
9206    Input Parameters:
9207 +  A - the matrix
9208 -  P - the projection matrix
9209 
9210    Output Parameters:
9211 .  C - the product matrix
9212 
9213    Notes:
9214    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9215    the user using MatDeatroy().
9216 
9217    This routine is currently only implemented for pairs of AIJ matrices and classes
9218    which inherit from AIJ.  C will be of type MATAIJ.
9219 
9220    Level: intermediate
9221 
9222 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9223 @*/
9224 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9225 {
9226   PetscErrorCode ierr;
9227 
9228   PetscFunctionBegin;
9229   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9230   PetscValidType(A,1);
9231   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9232   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9233   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9234   PetscValidType(P,2);
9235   MatCheckPreallocated(P,2);
9236   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9237   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9238   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9239   PetscValidType(C,3);
9240   MatCheckPreallocated(C,3);
9241   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9242   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);
9243   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);
9244   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);
9245   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);
9246   MatCheckPreallocated(A,1);
9247 
9248   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9249   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9250   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9251   PetscFunctionReturn(0);
9252 }
9253 
9254 #undef __FUNCT__
9255 #define __FUNCT__ "MatPtAPSymbolic"
9256 /*@
9257    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9258 
9259    Neighbor-wise Collective on Mat
9260 
9261    Input Parameters:
9262 +  A - the matrix
9263 -  P - the projection matrix
9264 
9265    Output Parameters:
9266 .  C - the (i,j) structure of the product matrix
9267 
9268    Notes:
9269    C will be created and must be destroyed by the user with MatDestroy().
9270 
9271    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9272    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9273    this (i,j) structure by calling MatPtAPNumeric().
9274 
9275    Level: intermediate
9276 
9277 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9278 @*/
9279 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9280 {
9281   PetscErrorCode ierr;
9282 
9283   PetscFunctionBegin;
9284   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9285   PetscValidType(A,1);
9286   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9287   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9288   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9289   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9290   PetscValidType(P,2);
9291   MatCheckPreallocated(P,2);
9292   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9293   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9294   PetscValidPointer(C,3);
9295 
9296   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);
9297   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);
9298   MatCheckPreallocated(A,1);
9299   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9300   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9301   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9302 
9303   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9304   PetscFunctionReturn(0);
9305 }
9306 
9307 #undef __FUNCT__
9308 #define __FUNCT__ "MatRARt"
9309 /*@
9310    MatRARt - Creates the matrix product C = R * A * R^T
9311 
9312    Neighbor-wise Collective on Mat
9313 
9314    Input Parameters:
9315 +  A - the matrix
9316 .  R - the projection matrix
9317 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9318 -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9319           if the result is a dense matrix this is irrelevent
9320 
9321    Output Parameters:
9322 .  C - the product matrix
9323 
9324    Notes:
9325    C will be created and must be destroyed by the user with MatDestroy().
9326 
9327    This routine is currently only implemented for pairs of AIJ matrices and classes
9328    which inherit from AIJ.
9329 
9330    Level: intermediate
9331 
9332 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9333 @*/
9334 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9335 {
9336   PetscErrorCode ierr;
9337 
9338   PetscFunctionBegin;
9339   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9340   PetscValidType(A,1);
9341   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9342   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9343   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9344   PetscValidType(R,2);
9345   MatCheckPreallocated(R,2);
9346   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9347   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9348   PetscValidPointer(C,3);
9349   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);
9350 
9351   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9352   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9353   MatCheckPreallocated(A,1);
9354 
9355   if (!A->ops->rart) {
9356     MatType mattype;
9357     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9358     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9359   }
9360   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9361   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9362   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9363   PetscFunctionReturn(0);
9364 }
9365 
9366 #undef __FUNCT__
9367 #define __FUNCT__ "MatRARtNumeric"
9368 /*@
9369    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9370 
9371    Neighbor-wise Collective on Mat
9372 
9373    Input Parameters:
9374 +  A - the matrix
9375 -  R - the projection matrix
9376 
9377    Output Parameters:
9378 .  C - the product matrix
9379 
9380    Notes:
9381    C must have been created by calling MatRARtSymbolic and must be destroyed by
9382    the user using MatDestroy().
9383 
9384    This routine is currently only implemented for pairs of AIJ matrices and classes
9385    which inherit from AIJ.  C will be of type MATAIJ.
9386 
9387    Level: intermediate
9388 
9389 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9390 @*/
9391 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9392 {
9393   PetscErrorCode ierr;
9394 
9395   PetscFunctionBegin;
9396   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9397   PetscValidType(A,1);
9398   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9399   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9400   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9401   PetscValidType(R,2);
9402   MatCheckPreallocated(R,2);
9403   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9404   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9405   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9406   PetscValidType(C,3);
9407   MatCheckPreallocated(C,3);
9408   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9409   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);
9410   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);
9411   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
9412   if (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);
9413   MatCheckPreallocated(A,1);
9414 
9415   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9416   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9417   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9418   PetscFunctionReturn(0);
9419 }
9420 
9421 #undef __FUNCT__
9422 #define __FUNCT__ "MatRARtSymbolic"
9423 /*@
9424    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9425 
9426    Neighbor-wise Collective on Mat
9427 
9428    Input Parameters:
9429 +  A - the matrix
9430 -  R - the projection matrix
9431 
9432    Output Parameters:
9433 .  C - the (i,j) structure of the product matrix
9434 
9435    Notes:
9436    C will be created and must be destroyed by the user with MatDestroy().
9437 
9438    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9439    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9440    this (i,j) structure by calling MatRARtNumeric().
9441 
9442    Level: intermediate
9443 
9444 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9445 @*/
9446 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9447 {
9448   PetscErrorCode ierr;
9449 
9450   PetscFunctionBegin;
9451   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9452   PetscValidType(A,1);
9453   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9454   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9455   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9456   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9457   PetscValidType(R,2);
9458   MatCheckPreallocated(R,2);
9459   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9460   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9461   PetscValidPointer(C,3);
9462 
9463   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);
9464   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);
9465   MatCheckPreallocated(A,1);
9466   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9467   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9468   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9469 
9470   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9471   PetscFunctionReturn(0);
9472 }
9473 
9474 #undef __FUNCT__
9475 #define __FUNCT__ "MatMatMult"
9476 /*@
9477    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9478 
9479    Neighbor-wise Collective on Mat
9480 
9481    Input Parameters:
9482 +  A - the left matrix
9483 .  B - the right matrix
9484 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9485 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9486           if the result is a dense matrix this is irrelevent
9487 
9488    Output Parameters:
9489 .  C - the product matrix
9490 
9491    Notes:
9492    Unless scall is MAT_REUSE_MATRIX C will be created.
9493 
9494    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9495 
9496    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9497    actually needed.
9498 
9499    If you have many matrices with the same non-zero structure to multiply, you
9500    should either
9501 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9502 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9503    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
9504    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9505 
9506    Level: intermediate
9507 
9508 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9509 @*/
9510 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9511 {
9512   PetscErrorCode ierr;
9513   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9514   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9515   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9516 
9517   PetscFunctionBegin;
9518   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9519   PetscValidType(A,1);
9520   MatCheckPreallocated(A,1);
9521   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9522   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9523   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9524   PetscValidType(B,2);
9525   MatCheckPreallocated(B,2);
9526   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9527   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9528   PetscValidPointer(C,3);
9529   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);
9530   if (scall == MAT_REUSE_MATRIX) {
9531     PetscValidPointer(*C,5);
9532     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9533     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9534     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9535     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9536     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9537     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9538     PetscFunctionReturn(0);
9539   }
9540   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9541   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9542 
9543   fA = A->ops->matmult;
9544   fB = B->ops->matmult;
9545   if (fB == fA) {
9546     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9547     mult = fB;
9548   } else {
9549     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9550     char multname[256];
9551     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
9552     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9553     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9554     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9555     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9556     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9557     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);
9558   }
9559   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9560   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9561   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9562   PetscFunctionReturn(0);
9563 }
9564 
9565 #undef __FUNCT__
9566 #define __FUNCT__ "MatMatMultSymbolic"
9567 /*@
9568    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9569    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9570 
9571    Neighbor-wise Collective on Mat
9572 
9573    Input Parameters:
9574 +  A - the left matrix
9575 .  B - the right matrix
9576 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9577       if C is a dense matrix this is irrelevent
9578 
9579    Output Parameters:
9580 .  C - the product matrix
9581 
9582    Notes:
9583    Unless scall is MAT_REUSE_MATRIX C will be created.
9584 
9585    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9586    actually needed.
9587 
9588    This routine is currently implemented for
9589     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9590     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9591     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9592 
9593    Level: intermediate
9594 
9595    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9596      We should incorporate them into PETSc.
9597 
9598 .seealso: MatMatMult(), MatMatMultNumeric()
9599 @*/
9600 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9601 {
9602   PetscErrorCode ierr;
9603   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9604   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9605   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9606 
9607   PetscFunctionBegin;
9608   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9609   PetscValidType(A,1);
9610   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9611   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9612 
9613   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9614   PetscValidType(B,2);
9615   MatCheckPreallocated(B,2);
9616   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9617   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9618   PetscValidPointer(C,3);
9619 
9620   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);
9621   if (fill == PETSC_DEFAULT) fill = 2.0;
9622   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9623   MatCheckPreallocated(A,1);
9624 
9625   Asymbolic = A->ops->matmultsymbolic;
9626   Bsymbolic = B->ops->matmultsymbolic;
9627   if (Asymbolic == Bsymbolic) {
9628     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9629     symbolic = Bsymbolic;
9630   } else { /* dispatch based on the type of A and B */
9631     char symbolicname[256];
9632     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
9633     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9634     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
9635     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9636     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
9637     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9638     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);
9639   }
9640   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9641   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9642   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9643   PetscFunctionReturn(0);
9644 }
9645 
9646 #undef __FUNCT__
9647 #define __FUNCT__ "MatMatMultNumeric"
9648 /*@
9649    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9650    Call this routine after first calling MatMatMultSymbolic().
9651 
9652    Neighbor-wise Collective on Mat
9653 
9654    Input Parameters:
9655 +  A - the left matrix
9656 -  B - the right matrix
9657 
9658    Output Parameters:
9659 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9660 
9661    Notes:
9662    C must have been created with MatMatMultSymbolic().
9663 
9664    This routine is currently implemented for
9665     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9666     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9667     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9668 
9669    Level: intermediate
9670 
9671 .seealso: MatMatMult(), MatMatMultSymbolic()
9672 @*/
9673 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9674 {
9675   PetscErrorCode ierr;
9676 
9677   PetscFunctionBegin;
9678   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9679   PetscFunctionReturn(0);
9680 }
9681 
9682 #undef __FUNCT__
9683 #define __FUNCT__ "MatMatTransposeMult"
9684 /*@
9685    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9686 
9687    Neighbor-wise Collective on Mat
9688 
9689    Input Parameters:
9690 +  A - the left matrix
9691 .  B - the right matrix
9692 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9693 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9694 
9695    Output Parameters:
9696 .  C - the product matrix
9697 
9698    Notes:
9699    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9700 
9701    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9702 
9703   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9704    actually needed.
9705 
9706    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
9707 
9708    Level: intermediate
9709 
9710 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9711 @*/
9712 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9713 {
9714   PetscErrorCode ierr;
9715   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9716   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9717 
9718   PetscFunctionBegin;
9719   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9720   PetscValidType(A,1);
9721   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9722   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9723   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9724   PetscValidType(B,2);
9725   MatCheckPreallocated(B,2);
9726   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9727   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9728   PetscValidPointer(C,3);
9729   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);
9730   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9731   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9732   MatCheckPreallocated(A,1);
9733 
9734   fA = A->ops->mattransposemult;
9735   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9736   fB = B->ops->mattransposemult;
9737   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9738   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);
9739 
9740   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9741   if (scall == MAT_INITIAL_MATRIX) {
9742     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9743     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9744     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9745   }
9746   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9747   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9748   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9749   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9750   PetscFunctionReturn(0);
9751 }
9752 
9753 #undef __FUNCT__
9754 #define __FUNCT__ "MatTransposeMatMult"
9755 /*@
9756    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9757 
9758    Neighbor-wise Collective on Mat
9759 
9760    Input Parameters:
9761 +  A - the left matrix
9762 .  B - the right matrix
9763 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9764 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9765 
9766    Output Parameters:
9767 .  C - the product matrix
9768 
9769    Notes:
9770    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9771 
9772    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9773 
9774   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9775    actually needed.
9776 
9777    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9778    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9779 
9780    Level: intermediate
9781 
9782 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9783 @*/
9784 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9785 {
9786   PetscErrorCode ierr;
9787   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9788   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9789   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9790 
9791   PetscFunctionBegin;
9792   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9793   PetscValidType(A,1);
9794   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9795   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9796   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9797   PetscValidType(B,2);
9798   MatCheckPreallocated(B,2);
9799   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9800   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9801   PetscValidPointer(C,3);
9802   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);
9803   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9804   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9805   MatCheckPreallocated(A,1);
9806 
9807   fA = A->ops->transposematmult;
9808   fB = B->ops->transposematmult;
9809   if (fB==fA) {
9810     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9811     transposematmult = fA;
9812   } else {
9813     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9814     char multname[256];
9815     ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);
9816     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9817     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9818     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9819     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9820     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9821     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);
9822   }
9823   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9824   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9825   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9826   PetscFunctionReturn(0);
9827 }
9828 
9829 #undef __FUNCT__
9830 #define __FUNCT__ "MatMatMatMult"
9831 /*@
9832    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9833 
9834    Neighbor-wise Collective on Mat
9835 
9836    Input Parameters:
9837 +  A - the left matrix
9838 .  B - the middle matrix
9839 .  C - the right matrix
9840 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9841 -  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
9842           if the result is a dense matrix this is irrelevent
9843 
9844    Output Parameters:
9845 .  D - the product matrix
9846 
9847    Notes:
9848    Unless scall is MAT_REUSE_MATRIX D will be created.
9849 
9850    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9851 
9852    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9853    actually needed.
9854 
9855    If you have many matrices with the same non-zero structure to multiply, you
9856    should use MAT_REUSE_MATRIX in all calls but the first or
9857 
9858    Level: intermediate
9859 
9860 .seealso: MatMatMult, MatPtAP()
9861 @*/
9862 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9863 {
9864   PetscErrorCode ierr;
9865   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9866   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9867   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9868   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9869 
9870   PetscFunctionBegin;
9871   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9872   PetscValidType(A,1);
9873   MatCheckPreallocated(A,1);
9874   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9875   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9876   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9877   PetscValidType(B,2);
9878   MatCheckPreallocated(B,2);
9879   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9880   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9881   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9882   PetscValidPointer(C,3);
9883   MatCheckPreallocated(C,3);
9884   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9885   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9886   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);
9887   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);
9888   if (scall == MAT_REUSE_MATRIX) {
9889     PetscValidPointer(*D,6);
9890     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9891     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9892     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9893     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9894     PetscFunctionReturn(0);
9895   }
9896   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9897   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9898 
9899   fA = A->ops->matmatmult;
9900   fB = B->ops->matmatmult;
9901   fC = C->ops->matmatmult;
9902   if (fA == fB && fA == fC) {
9903     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9904     mult = fA;
9905   } else {
9906     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9907     char multname[256];
9908     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9909     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9910     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9911     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9912     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9913     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9914     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9915     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9916     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);
9917   }
9918   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9919   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9920   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9921   PetscFunctionReturn(0);
9922 }
9923 
9924 #undef __FUNCT__
9925 #define __FUNCT__ "MatCreateRedundantMatrix"
9926 /*@C
9927    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9928 
9929    Collective on Mat
9930 
9931    Input Parameters:
9932 +  mat - the matrix
9933 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9934 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9935 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9936 
9937    Output Parameter:
9938 .  matredundant - redundant matrix
9939 
9940    Notes:
9941    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9942    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9943 
9944    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9945    calling it.
9946 
9947    Level: advanced
9948 
9949    Concepts: subcommunicator
9950    Concepts: duplicate matrix
9951 
9952 .seealso: MatDestroy()
9953 @*/
9954 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9955 {
9956   PetscErrorCode ierr;
9957   MPI_Comm       comm;
9958   PetscMPIInt    size;
9959   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9960   Mat_Redundant  *redund=NULL;
9961   PetscSubcomm   psubcomm=NULL;
9962   MPI_Comm       subcomm_in=subcomm;
9963   Mat            *matseq;
9964   IS             isrow,iscol;
9965   PetscBool      newsubcomm=PETSC_FALSE;
9966 
9967   PetscFunctionBegin;
9968   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9969   if (size == 1 || nsubcomm == 1) {
9970     if (reuse == MAT_INITIAL_MATRIX) {
9971       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9972     } else {
9973       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9974     }
9975     PetscFunctionReturn(0);
9976   }
9977 
9978   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9979   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9980     PetscValidPointer(*matredundant,5);
9981     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9982   }
9983   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9984   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9985   MatCheckPreallocated(mat,1);
9986 
9987   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9988   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9989     /* create psubcomm, then get subcomm */
9990     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9991     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9992     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9993 
9994     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9995     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9996     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9997     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9998     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9999     newsubcomm = PETSC_TRUE;
10000     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
10001   }
10002 
10003   /* get isrow, iscol and a local sequential matrix matseq[0] */
10004   if (reuse == MAT_INITIAL_MATRIX) {
10005     mloc_sub = PETSC_DECIDE;
10006     if (bs < 1) {
10007       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
10008     } else {
10009       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
10010     }
10011     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
10012     rstart = rend - mloc_sub;
10013     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
10014     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
10015   } else { /* reuse == MAT_REUSE_MATRIX */
10016     /* retrieve subcomm */
10017     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
10018     redund = (*matredundant)->redundant;
10019     isrow  = redund->isrow;
10020     iscol  = redund->iscol;
10021     matseq = redund->matseq;
10022   }
10023   ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
10024 
10025   /* get matredundant over subcomm */
10026   if (reuse == MAT_INITIAL_MATRIX) {
10027     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);CHKERRQ(ierr);
10028 
10029     /* create a supporting struct and attach it to C for reuse */
10030     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
10031     (*matredundant)->redundant = redund;
10032     redund->isrow              = isrow;
10033     redund->iscol              = iscol;
10034     redund->matseq             = matseq;
10035     if (newsubcomm) {
10036       redund->subcomm          = subcomm;
10037     } else {
10038       redund->subcomm          = MPI_COMM_NULL;
10039     }
10040   } else {
10041     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
10042   }
10043   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
10044   PetscFunctionReturn(0);
10045 }
10046 
10047 #undef __FUNCT__
10048 #define __FUNCT__ "MatGetMultiProcBlock"
10049 /*@C
10050    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10051    a given 'mat' object. Each submatrix can span multiple procs.
10052 
10053    Collective on Mat
10054 
10055    Input Parameters:
10056 +  mat - the matrix
10057 .  subcomm - the subcommunicator obtained by com_split(comm)
10058 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10059 
10060    Output Parameter:
10061 .  subMat - 'parallel submatrices each spans a given subcomm
10062 
10063   Notes:
10064   The submatrix partition across processors is dictated by 'subComm' a
10065   communicator obtained by com_split(comm). The comm_split
10066   is not restriced to be grouped with consecutive original ranks.
10067 
10068   Due the comm_split() usage, the parallel layout of the submatrices
10069   map directly to the layout of the original matrix [wrt the local
10070   row,col partitioning]. So the original 'DiagonalMat' naturally maps
10071   into the 'DiagonalMat' of the subMat, hence it is used directly from
10072   the subMat. However the offDiagMat looses some columns - and this is
10073   reconstructed with MatSetValues()
10074 
10075   Level: advanced
10076 
10077   Concepts: subcommunicator
10078   Concepts: submatrices
10079 
10080 .seealso: MatGetSubMatrices()
10081 @*/
10082 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10083 {
10084   PetscErrorCode ierr;
10085   PetscMPIInt    commsize,subCommSize;
10086 
10087   PetscFunctionBegin;
10088   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
10089   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
10090   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10091 
10092   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10093   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
10094   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
10095   PetscFunctionReturn(0);
10096 }
10097 
10098 #undef __FUNCT__
10099 #define __FUNCT__ "MatGetLocalSubMatrix"
10100 /*@
10101    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10102 
10103    Not Collective
10104 
10105    Input Arguments:
10106    mat - matrix to extract local submatrix from
10107    isrow - local row indices for submatrix
10108    iscol - local column indices for submatrix
10109 
10110    Output Arguments:
10111    submat - the submatrix
10112 
10113    Level: intermediate
10114 
10115    Notes:
10116    The submat should be returned with MatRestoreLocalSubMatrix().
10117 
10118    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
10119    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10120 
10121    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
10122    MatSetValuesBlockedLocal() will also be implemented.
10123 
10124    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10125    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10126 
10127 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10128 @*/
10129 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10130 {
10131   PetscErrorCode ierr;
10132 
10133   PetscFunctionBegin;
10134   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10135   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10136   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10137   PetscCheckSameComm(isrow,2,iscol,3);
10138   PetscValidPointer(submat,4);
10139   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10140 
10141   if (mat->ops->getlocalsubmatrix) {
10142     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10143   } else {
10144     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
10145   }
10146   PetscFunctionReturn(0);
10147 }
10148 
10149 #undef __FUNCT__
10150 #define __FUNCT__ "MatRestoreLocalSubMatrix"
10151 /*@
10152    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10153 
10154    Not Collective
10155 
10156    Input Arguments:
10157    mat - matrix to extract local submatrix from
10158    isrow - local row indices for submatrix
10159    iscol - local column indices for submatrix
10160    submat - the submatrix
10161 
10162    Level: intermediate
10163 
10164 .seealso: MatGetLocalSubMatrix()
10165 @*/
10166 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10167 {
10168   PetscErrorCode ierr;
10169 
10170   PetscFunctionBegin;
10171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10172   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10173   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10174   PetscCheckSameComm(isrow,2,iscol,3);
10175   PetscValidPointer(submat,4);
10176   if (*submat) {
10177     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10178   }
10179 
10180   if (mat->ops->restorelocalsubmatrix) {
10181     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10182   } else {
10183     ierr = MatDestroy(submat);CHKERRQ(ierr);
10184   }
10185   *submat = NULL;
10186   PetscFunctionReturn(0);
10187 }
10188 
10189 /* --------------------------------------------------------*/
10190 #undef __FUNCT__
10191 #define __FUNCT__ "MatFindZeroDiagonals"
10192 /*@
10193    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
10194 
10195    Collective on Mat
10196 
10197    Input Parameter:
10198 .  mat - the matrix
10199 
10200    Output Parameter:
10201 .  is - if any rows have zero diagonals this contains the list of them
10202 
10203    Level: developer
10204 
10205    Concepts: matrix-vector product
10206 
10207 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10208 @*/
10209 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10210 {
10211   PetscErrorCode ierr;
10212 
10213   PetscFunctionBegin;
10214   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10215   PetscValidType(mat,1);
10216   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10217   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10218 
10219   if (!mat->ops->findzerodiagonals) {
10220     Vec                diag;
10221     const PetscScalar *a;
10222     PetscInt          *rows;
10223     PetscInt           rStart, rEnd, r, nrow = 0;
10224 
10225     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10226     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10227     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10228     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10229     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10230     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10231     nrow = 0;
10232     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10233     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10234     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10235     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10236   } else {
10237     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10238   }
10239   PetscFunctionReturn(0);
10240 }
10241 
10242 #undef __FUNCT__
10243 #define __FUNCT__ "MatFindOffBlockDiagonalEntries"
10244 /*@
10245    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10246 
10247    Collective on Mat
10248 
10249    Input Parameter:
10250 .  mat - the matrix
10251 
10252    Output Parameter:
10253 .  is - contains the list of rows with off block diagonal entries
10254 
10255    Level: developer
10256 
10257    Concepts: matrix-vector product
10258 
10259 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10260 @*/
10261 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10262 {
10263   PetscErrorCode ierr;
10264 
10265   PetscFunctionBegin;
10266   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10267   PetscValidType(mat,1);
10268   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10269   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10270 
10271   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10272   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10273   PetscFunctionReturn(0);
10274 }
10275 
10276 #undef __FUNCT__
10277 #define __FUNCT__ "MatInvertBlockDiagonal"
10278 /*@C
10279   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10280 
10281   Collective on Mat
10282 
10283   Input Parameters:
10284 . mat - the matrix
10285 
10286   Output Parameters:
10287 . values - the block inverses in column major order (FORTRAN-like)
10288 
10289    Note:
10290    This routine is not available from Fortran.
10291 
10292   Level: advanced
10293 @*/
10294 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10295 {
10296   PetscErrorCode ierr;
10297 
10298   PetscFunctionBegin;
10299   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10300   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10301   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10302   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10303   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10304   PetscFunctionReturn(0);
10305 }
10306 
10307 #undef __FUNCT__
10308 #define __FUNCT__ "MatTransposeColoringDestroy"
10309 /*@C
10310     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10311     via MatTransposeColoringCreate().
10312 
10313     Collective on MatTransposeColoring
10314 
10315     Input Parameter:
10316 .   c - coloring context
10317 
10318     Level: intermediate
10319 
10320 .seealso: MatTransposeColoringCreate()
10321 @*/
10322 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10323 {
10324   PetscErrorCode       ierr;
10325   MatTransposeColoring matcolor=*c;
10326 
10327   PetscFunctionBegin;
10328   if (!matcolor) PetscFunctionReturn(0);
10329   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10330 
10331   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10332   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10333   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10334   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10335   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10336   if (matcolor->brows>0) {
10337     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10338   }
10339   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10340   PetscFunctionReturn(0);
10341 }
10342 
10343 #undef __FUNCT__
10344 #define __FUNCT__ "MatTransColoringApplySpToDen"
10345 /*@C
10346     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10347     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10348     MatTransposeColoring to sparse B.
10349 
10350     Collective on MatTransposeColoring
10351 
10352     Input Parameters:
10353 +   B - sparse matrix B
10354 .   Btdense - symbolic dense matrix B^T
10355 -   coloring - coloring context created with MatTransposeColoringCreate()
10356 
10357     Output Parameter:
10358 .   Btdense - dense matrix B^T
10359 
10360     Options Database Keys:
10361 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
10362 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
10363 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
10364 
10365     Level: intermediate
10366 
10367 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
10368 
10369 .keywords: coloring
10370 @*/
10371 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10372 {
10373   PetscErrorCode ierr;
10374 
10375   PetscFunctionBegin;
10376   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10377   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10378   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10379 
10380   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10381   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10382   PetscFunctionReturn(0);
10383 }
10384 
10385 #undef __FUNCT__
10386 #define __FUNCT__ "MatTransColoringApplyDenToSp"
10387 /*@C
10388     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10389     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10390     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10391     Csp from Cden.
10392 
10393     Collective on MatTransposeColoring
10394 
10395     Input Parameters:
10396 +   coloring - coloring context created with MatTransposeColoringCreate()
10397 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10398 
10399     Output Parameter:
10400 .   Csp - sparse matrix
10401 
10402     Options Database Keys:
10403 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
10404 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
10405 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
10406 
10407     Level: intermediate
10408 
10409 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10410 
10411 .keywords: coloring
10412 @*/
10413 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10414 {
10415   PetscErrorCode ierr;
10416 
10417   PetscFunctionBegin;
10418   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10419   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10420   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10421 
10422   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10423   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10424   PetscFunctionReturn(0);
10425 }
10426 
10427 #undef __FUNCT__
10428 #define __FUNCT__ "MatTransposeColoringCreate"
10429 /*@C
10430    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10431 
10432    Collective on Mat
10433 
10434    Input Parameters:
10435 +  mat - the matrix product C
10436 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10437 
10438     Output Parameter:
10439 .   color - the new coloring context
10440 
10441     Level: intermediate
10442 
10443 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
10444            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
10445 @*/
10446 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10447 {
10448   MatTransposeColoring c;
10449   MPI_Comm             comm;
10450   PetscErrorCode       ierr;
10451 
10452   PetscFunctionBegin;
10453   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10454   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10455   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10456 
10457   c->ctype = iscoloring->ctype;
10458   if (mat->ops->transposecoloringcreate) {
10459     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10460   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10461 
10462   *color = c;
10463   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10464   PetscFunctionReturn(0);
10465 }
10466 
10467 #undef __FUNCT__
10468 #define __FUNCT__ "MatGetNonzeroState"
10469 /*@
10470       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10471         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10472         same, otherwise it will be larger
10473 
10474      Not Collective
10475 
10476   Input Parameter:
10477 .    A  - the matrix
10478 
10479   Output Parameter:
10480 .    state - the current state
10481 
10482   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10483          different matrices
10484 
10485   Level: intermediate
10486 
10487 @*/
10488 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10489 {
10490   PetscFunctionBegin;
10491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10492   *state = mat->nonzerostate;
10493   PetscFunctionReturn(0);
10494 }
10495 
10496 #undef __FUNCT__
10497 #define __FUNCT__ "MatCreateMPIMatConcatenateSeqMat"
10498 /*@
10499       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10500                  matrices from each processor
10501 
10502     Collective on MPI_Comm
10503 
10504    Input Parameters:
10505 +    comm - the communicators the parallel matrix will live on
10506 .    seqmat - the input sequential matrices
10507 .    n - number of local columns (or PETSC_DECIDE)
10508 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10509 
10510    Output Parameter:
10511 .    mpimat - the parallel matrix generated
10512 
10513     Level: advanced
10514 
10515    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10516 
10517 @*/
10518 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10519 {
10520   PetscErrorCode ierr;
10521   PetscMPIInt    size;
10522 
10523   PetscFunctionBegin;
10524   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10525   if (size == 1) {
10526     if (reuse == MAT_INITIAL_MATRIX) {
10527       ierr = MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);CHKERRQ(ierr);
10528     } else {
10529       ierr = MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10530     }
10531     PetscFunctionReturn(0);
10532   }
10533 
10534   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10535   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10536   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10537   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10538   PetscFunctionReturn(0);
10539 }
10540 
10541 #undef __FUNCT__
10542 #define __FUNCT__ "MatSubdomainsCreateCoalesce"
10543 /*@
10544      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10545                  ranks' ownership ranges.
10546 
10547     Collective on A
10548 
10549    Input Parameters:
10550 +    A   - the matrix to create subdomains from
10551 -    N   - requested number of subdomains
10552 
10553 
10554    Output Parameters:
10555 +    n   - number of subdomains resulting on this rank
10556 -    iss - IS list with indices of subdomains on this rank
10557 
10558     Level: advanced
10559 
10560     Notes: number of subdomains must be smaller than the communicator size
10561 @*/
10562 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10563 {
10564   MPI_Comm        comm,subcomm;
10565   PetscMPIInt     size,rank,color;
10566   PetscInt        rstart,rend,k;
10567   PetscErrorCode  ierr;
10568 
10569   PetscFunctionBegin;
10570   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10571   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10572   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10573   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);
10574   *n = 1;
10575   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10576   color = rank/k;
10577   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10578   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10579   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10580   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10581   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10582   PetscFunctionReturn(0);
10583 }
10584