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