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