xref: /petsc/src/mat/interface/matrix.c (revision 1b581b665160bc053f1db6f623a6eaab6b98fcae)
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 PetscViewerSetFormat() 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: PetscViewerSetFormat(), 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   while (next) {
4089     ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr);
4090     if (flg) {
4091       if (foundpackage) *foundpackage = PETSC_TRUE;
4092       inext = next->handlers;
4093       while (inext) {
4094         ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr);
4095         if (flg) {
4096           if (foundmtype) *foundmtype = PETSC_TRUE;
4097           if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
4098           PetscFunctionReturn(0);
4099         }
4100         inext = inext->next;
4101       }
4102     }
4103     next = next->next;
4104   }
4105   PetscFunctionReturn(0);
4106 }
4107 
4108 #undef __FUNCT__
4109 #define __FUNCT__ "MatSolverPackageDestroy"
4110 PetscErrorCode MatSolverPackageDestroy(void)
4111 {
4112   PetscErrorCode                 ierr;
4113   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
4114   MatSolverPackageForSpecifcType inext,iprev;
4115 
4116   PetscFunctionBegin;
4117   while (next) {
4118     ierr = PetscFree(next->name);CHKERRQ(ierr);
4119     inext = next->handlers;
4120     while (inext) {
4121       ierr = PetscFree(inext->mtype);CHKERRQ(ierr);
4122       iprev = inext;
4123       inext = inext->next;
4124       ierr = PetscFree(iprev);CHKERRQ(ierr);
4125     }
4126     prev = next;
4127     next = next->next;
4128     ierr = PetscFree(prev);CHKERRQ(ierr);
4129   }
4130   MatSolverPackageHolders = NULL;
4131   PetscFunctionReturn(0);
4132 }
4133 
4134 #undef __FUNCT__
4135 #define __FUNCT__ "MatGetFactor"
4136 /*@C
4137    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4138 
4139    Collective on Mat
4140 
4141    Input Parameters:
4142 +  mat - the matrix
4143 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4144 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4145 
4146    Output Parameters:
4147 .  f - the factor matrix used with MatXXFactorSymbolic() calls
4148 
4149    Notes:
4150       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4151      such as pastix, superlu, mumps etc.
4152 
4153       PETSc must have been ./configure to use the external solver, using the option --download-package
4154 
4155    Level: intermediate
4156 
4157 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4158 @*/
4159 PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4160 {
4161   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4162   PetscBool      foundpackage,foundmtype;
4163 
4164   PetscFunctionBegin;
4165   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4166   PetscValidType(mat,1);
4167 
4168   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4169   MatCheckPreallocated(mat,1);
4170 
4171   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr);
4172   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);
4173   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4174   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);
4175 
4176   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
4177   PetscFunctionReturn(0);
4178 }
4179 
4180 #undef __FUNCT__
4181 #define __FUNCT__ "MatGetFactorAvailable"
4182 /*@C
4183    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4184 
4185    Not Collective
4186 
4187    Input Parameters:
4188 +  mat - the matrix
4189 .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4190 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4191 
4192    Output Parameter:
4193 .    flg - PETSC_TRUE if the factorization is available
4194 
4195    Notes:
4196       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4197      such as pastix, superlu, mumps etc.
4198 
4199       PETSc must have been ./configure to use the external solver, using the option --download-package
4200 
4201    Level: intermediate
4202 
4203 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4204 @*/
4205 PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4206 {
4207   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4208 
4209   PetscFunctionBegin;
4210   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4211   PetscValidType(mat,1);
4212 
4213   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4214   MatCheckPreallocated(mat,1);
4215 
4216   *flg = PETSC_FALSE;
4217   ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr);
4218   if (gconv) {
4219     *flg = PETSC_TRUE;
4220   }
4221   PetscFunctionReturn(0);
4222 }
4223 
4224 #include <petscdmtypes.h>
4225 
4226 #undef __FUNCT__
4227 #define __FUNCT__ "MatDuplicate"
4228 /*@
4229    MatDuplicate - Duplicates a matrix including the non-zero structure.
4230 
4231    Collective on Mat
4232 
4233    Input Parameters:
4234 +  mat - the matrix
4235 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4236         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4237 
4238    Output Parameter:
4239 .  M - pointer to place new matrix
4240 
4241    Level: intermediate
4242 
4243    Concepts: matrices^duplicating
4244 
4245     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4246 
4247 .seealso: MatCopy(), MatConvert()
4248 @*/
4249 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4250 {
4251   PetscErrorCode ierr;
4252   Mat            B;
4253   PetscInt       i;
4254   DM             dm;
4255 
4256   PetscFunctionBegin;
4257   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4258   PetscValidType(mat,1);
4259   PetscValidPointer(M,3);
4260   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4261   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4262   MatCheckPreallocated(mat,1);
4263 
4264   *M = 0;
4265   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4266   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4267   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4268   B    = *M;
4269 
4270   B->stencil.dim = mat->stencil.dim;
4271   B->stencil.noc = mat->stencil.noc;
4272   for (i=0; i<=mat->stencil.dim; i++) {
4273     B->stencil.dims[i]   = mat->stencil.dims[i];
4274     B->stencil.starts[i] = mat->stencil.starts[i];
4275   }
4276 
4277   B->nooffproczerorows = mat->nooffproczerorows;
4278   B->nooffprocentries  = mat->nooffprocentries;
4279 
4280   ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr);
4281   if (dm) {
4282     ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr);
4283   }
4284   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4285   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4286   PetscFunctionReturn(0);
4287 }
4288 
4289 #undef __FUNCT__
4290 #define __FUNCT__ "MatGetDiagonal"
4291 /*@
4292    MatGetDiagonal - Gets the diagonal of a matrix.
4293 
4294    Logically Collective on Mat and Vec
4295 
4296    Input Parameters:
4297 +  mat - the matrix
4298 -  v - the vector for storing the diagonal
4299 
4300    Output Parameter:
4301 .  v - the diagonal of the matrix
4302 
4303    Level: intermediate
4304 
4305    Note:
4306    Currently only correct in parallel for square matrices.
4307 
4308    Concepts: matrices^accessing diagonals
4309 
4310 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4311 @*/
4312 PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4313 {
4314   PetscErrorCode ierr;
4315 
4316   PetscFunctionBegin;
4317   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4318   PetscValidType(mat,1);
4319   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4320   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4321   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4322   MatCheckPreallocated(mat,1);
4323 
4324   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4325   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4326   PetscFunctionReturn(0);
4327 }
4328 
4329 #undef __FUNCT__
4330 #define __FUNCT__ "MatGetRowMin"
4331 /*@C
4332    MatGetRowMin - Gets the minimum value (of the real part) of each
4333         row of the matrix
4334 
4335    Logically Collective on Mat and Vec
4336 
4337    Input Parameters:
4338 .  mat - the matrix
4339 
4340    Output Parameter:
4341 +  v - the vector for storing the maximums
4342 -  idx - the indices of the column found for each row (optional)
4343 
4344    Level: intermediate
4345 
4346    Notes: The result of this call are the same as if one converted the matrix to dense format
4347       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4348 
4349     This code is only implemented for a couple of matrix formats.
4350 
4351    Concepts: matrices^getting row maximums
4352 
4353 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4354           MatGetRowMax()
4355 @*/
4356 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4357 {
4358   PetscErrorCode ierr;
4359 
4360   PetscFunctionBegin;
4361   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4362   PetscValidType(mat,1);
4363   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4364   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4365   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4366   MatCheckPreallocated(mat,1);
4367 
4368   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4369   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4370   PetscFunctionReturn(0);
4371 }
4372 
4373 #undef __FUNCT__
4374 #define __FUNCT__ "MatGetRowMinAbs"
4375 /*@C
4376    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4377         row of the matrix
4378 
4379    Logically Collective on Mat and Vec
4380 
4381    Input Parameters:
4382 .  mat - the matrix
4383 
4384    Output Parameter:
4385 +  v - the vector for storing the minimums
4386 -  idx - the indices of the column found for each row (or NULL if not needed)
4387 
4388    Level: intermediate
4389 
4390    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4391     row is 0 (the first column).
4392 
4393     This code is only implemented for a couple of matrix formats.
4394 
4395    Concepts: matrices^getting row maximums
4396 
4397 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4398 @*/
4399 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4400 {
4401   PetscErrorCode ierr;
4402 
4403   PetscFunctionBegin;
4404   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4405   PetscValidType(mat,1);
4406   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4407   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4408   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4409   MatCheckPreallocated(mat,1);
4410   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4411 
4412   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4413   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4414   PetscFunctionReturn(0);
4415 }
4416 
4417 #undef __FUNCT__
4418 #define __FUNCT__ "MatGetRowMax"
4419 /*@C
4420    MatGetRowMax - Gets the maximum value (of the real part) of each
4421         row of the matrix
4422 
4423    Logically Collective on Mat and Vec
4424 
4425    Input Parameters:
4426 .  mat - the matrix
4427 
4428    Output Parameter:
4429 +  v - the vector for storing the maximums
4430 -  idx - the indices of the column found for each row (optional)
4431 
4432    Level: intermediate
4433 
4434    Notes: The result of this call are the same as if one converted the matrix to dense format
4435       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4436 
4437     This code is only implemented for a couple of matrix formats.
4438 
4439    Concepts: matrices^getting row maximums
4440 
4441 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4442 @*/
4443 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4444 {
4445   PetscErrorCode ierr;
4446 
4447   PetscFunctionBegin;
4448   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4449   PetscValidType(mat,1);
4450   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4451   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4452   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4453   MatCheckPreallocated(mat,1);
4454 
4455   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4456   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4457   PetscFunctionReturn(0);
4458 }
4459 
4460 #undef __FUNCT__
4461 #define __FUNCT__ "MatGetRowMaxAbs"
4462 /*@C
4463    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4464         row of the matrix
4465 
4466    Logically Collective on Mat and Vec
4467 
4468    Input Parameters:
4469 .  mat - the matrix
4470 
4471    Output Parameter:
4472 +  v - the vector for storing the maximums
4473 -  idx - the indices of the column found for each row (or NULL if not needed)
4474 
4475    Level: intermediate
4476 
4477    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4478     row is 0 (the first column).
4479 
4480     This code is only implemented for a couple of matrix formats.
4481 
4482    Concepts: matrices^getting row maximums
4483 
4484 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4485 @*/
4486 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4487 {
4488   PetscErrorCode ierr;
4489 
4490   PetscFunctionBegin;
4491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4492   PetscValidType(mat,1);
4493   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4494   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4495   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4496   MatCheckPreallocated(mat,1);
4497   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4498 
4499   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4500   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4501   PetscFunctionReturn(0);
4502 }
4503 
4504 #undef __FUNCT__
4505 #define __FUNCT__ "MatGetRowSum"
4506 /*@
4507    MatGetRowSum - Gets the sum of each row of the matrix
4508 
4509    Logically Collective on Mat and Vec
4510 
4511    Input Parameters:
4512 .  mat - the matrix
4513 
4514    Output Parameter:
4515 .  v - the vector for storing the sum of rows
4516 
4517    Level: intermediate
4518 
4519    Notes: This code is slow since it is not currently specialized for different formats
4520 
4521    Concepts: matrices^getting row sums
4522 
4523 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4524 @*/
4525 PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4526 {
4527   PetscInt       start = 0, end = 0, row;
4528   PetscScalar    *array;
4529   PetscErrorCode ierr;
4530 
4531   PetscFunctionBegin;
4532   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4533   PetscValidType(mat,1);
4534   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4535   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4536   MatCheckPreallocated(mat,1);
4537   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
4538   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
4539   for (row = start; row < end; ++row) {
4540     PetscInt          ncols, col;
4541     const PetscInt    *cols;
4542     const PetscScalar *vals;
4543 
4544     array[row - start] = 0.0;
4545 
4546     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4547     for (col = 0; col < ncols; col++) {
4548       array[row - start] += vals[col];
4549     }
4550     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4551   }
4552   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
4553   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
4554   PetscFunctionReturn(0);
4555 }
4556 
4557 #undef __FUNCT__
4558 #define __FUNCT__ "MatTranspose"
4559 /*@
4560    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4561 
4562    Collective on Mat
4563 
4564    Input Parameter:
4565 +  mat - the matrix to transpose
4566 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4567 
4568    Output Parameters:
4569 .  B - the transpose
4570 
4571    Notes:
4572      If you  pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4573 
4574      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4575 
4576    Level: intermediate
4577 
4578    Concepts: matrices^transposing
4579 
4580 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4581 @*/
4582 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4583 {
4584   PetscErrorCode ierr;
4585 
4586   PetscFunctionBegin;
4587   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4588   PetscValidType(mat,1);
4589   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4590   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4591   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4592   MatCheckPreallocated(mat,1);
4593 
4594   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4595   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4596   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4597   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4598   PetscFunctionReturn(0);
4599 }
4600 
4601 #undef __FUNCT__
4602 #define __FUNCT__ "MatIsTranspose"
4603 /*@
4604    MatIsTranspose - Test whether a matrix is another one's transpose,
4605         or its own, in which case it tests symmetry.
4606 
4607    Collective on Mat
4608 
4609    Input Parameter:
4610 +  A - the matrix to test
4611 -  B - the matrix to test against, this can equal the first parameter
4612 
4613    Output Parameters:
4614 .  flg - the result
4615 
4616    Notes:
4617    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4618    has a running time of the order of the number of nonzeros; the parallel
4619    test involves parallel copies of the block-offdiagonal parts of the matrix.
4620 
4621    Level: intermediate
4622 
4623    Concepts: matrices^transposing, matrix^symmetry
4624 
4625 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4626 @*/
4627 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4628 {
4629   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4630 
4631   PetscFunctionBegin;
4632   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4633   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4634   PetscValidPointer(flg,3);
4635   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr);
4636   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr);
4637   *flg = PETSC_FALSE;
4638   if (f && g) {
4639     if (f == g) {
4640       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4641     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4642   } else {
4643     MatType mattype;
4644     if (!f) {
4645       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
4646     } else {
4647       ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
4648     }
4649     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4650   }
4651   PetscFunctionReturn(0);
4652 }
4653 
4654 #undef __FUNCT__
4655 #define __FUNCT__ "MatHermitianTranspose"
4656 /*@
4657    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4658 
4659    Collective on Mat
4660 
4661    Input Parameter:
4662 +  mat - the matrix to transpose and complex conjugate
4663 -  reuse - store the transpose matrix in the provided B
4664 
4665    Output Parameters:
4666 .  B - the Hermitian
4667 
4668    Notes:
4669      If you  pass in &mat for B the Hermitian will be done in place
4670 
4671    Level: intermediate
4672 
4673    Concepts: matrices^transposing, complex conjugatex
4674 
4675 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4676 @*/
4677 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4678 {
4679   PetscErrorCode ierr;
4680 
4681   PetscFunctionBegin;
4682   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4683 #if defined(PETSC_USE_COMPLEX)
4684   ierr = MatConjugate(*B);CHKERRQ(ierr);
4685 #endif
4686   PetscFunctionReturn(0);
4687 }
4688 
4689 #undef __FUNCT__
4690 #define __FUNCT__ "MatIsHermitianTranspose"
4691 /*@
4692    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4693 
4694    Collective on Mat
4695 
4696    Input Parameter:
4697 +  A - the matrix to test
4698 -  B - the matrix to test against, this can equal the first parameter
4699 
4700    Output Parameters:
4701 .  flg - the result
4702 
4703    Notes:
4704    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4705    has a running time of the order of the number of nonzeros; the parallel
4706    test involves parallel copies of the block-offdiagonal parts of the matrix.
4707 
4708    Level: intermediate
4709 
4710    Concepts: matrices^transposing, matrix^symmetry
4711 
4712 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4713 @*/
4714 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4715 {
4716   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4717 
4718   PetscFunctionBegin;
4719   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4720   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4721   PetscValidPointer(flg,3);
4722   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr);
4723   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr);
4724   if (f && g) {
4725     if (f==g) {
4726       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4727     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4728   }
4729   PetscFunctionReturn(0);
4730 }
4731 
4732 #undef __FUNCT__
4733 #define __FUNCT__ "MatPermute"
4734 /*@
4735    MatPermute - Creates a new matrix with rows and columns permuted from the
4736    original.
4737 
4738    Collective on Mat
4739 
4740    Input Parameters:
4741 +  mat - the matrix to permute
4742 .  row - row permutation, each processor supplies only the permutation for its rows
4743 -  col - column permutation, each processor supplies only the permutation for its columns
4744 
4745    Output Parameters:
4746 .  B - the permuted matrix
4747 
4748    Level: advanced
4749 
4750    Note:
4751    The index sets map from row/col of permuted matrix to row/col of original matrix.
4752    The index sets should be on the same communicator as Mat and have the same local sizes.
4753 
4754    Concepts: matrices^permuting
4755 
4756 .seealso: MatGetOrdering(), ISAllGather()
4757 
4758 @*/
4759 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4760 {
4761   PetscErrorCode ierr;
4762 
4763   PetscFunctionBegin;
4764   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4765   PetscValidType(mat,1);
4766   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4767   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4768   PetscValidPointer(B,4);
4769   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4770   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4771   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4772   MatCheckPreallocated(mat,1);
4773 
4774   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4775   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4776   PetscFunctionReturn(0);
4777 }
4778 
4779 #undef __FUNCT__
4780 #define __FUNCT__ "MatEqual"
4781 /*@
4782    MatEqual - Compares two matrices.
4783 
4784    Collective on Mat
4785 
4786    Input Parameters:
4787 +  A - the first matrix
4788 -  B - the second matrix
4789 
4790    Output Parameter:
4791 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4792 
4793    Level: intermediate
4794 
4795    Concepts: matrices^equality between
4796 @*/
4797 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
4798 {
4799   PetscErrorCode ierr;
4800 
4801   PetscFunctionBegin;
4802   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4803   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4804   PetscValidType(A,1);
4805   PetscValidType(B,2);
4806   PetscValidIntPointer(flg,3);
4807   PetscCheckSameComm(A,1,B,2);
4808   MatCheckPreallocated(B,2);
4809   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4810   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4811   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);
4812   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4813   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4814   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);
4815   MatCheckPreallocated(A,1);
4816 
4817   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4818   PetscFunctionReturn(0);
4819 }
4820 
4821 #undef __FUNCT__
4822 #define __FUNCT__ "MatDiagonalScale"
4823 /*@
4824    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4825    matrices that are stored as vectors.  Either of the two scaling
4826    matrices can be NULL.
4827 
4828    Collective on Mat
4829 
4830    Input Parameters:
4831 +  mat - the matrix to be scaled
4832 .  l - the left scaling vector (or NULL)
4833 -  r - the right scaling vector (or NULL)
4834 
4835    Notes:
4836    MatDiagonalScale() computes A = LAR, where
4837    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4838    The L scales the rows of the matrix, the R scales the columns of the matrix.
4839 
4840    Level: intermediate
4841 
4842    Concepts: matrices^diagonal scaling
4843    Concepts: diagonal scaling of matrices
4844 
4845 .seealso: MatScale()
4846 @*/
4847 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4848 {
4849   PetscErrorCode ierr;
4850 
4851   PetscFunctionBegin;
4852   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4853   PetscValidType(mat,1);
4854   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4855   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4856   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4857   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4858   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4859   MatCheckPreallocated(mat,1);
4860 
4861   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4862   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4863   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4864   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4865 #if defined(PETSC_HAVE_CUSP)
4866   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4867     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4868   }
4869 #endif
4870 #if defined(PETSC_HAVE_VIENNACL)
4871   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4872     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4873   }
4874 #endif
4875   PetscFunctionReturn(0);
4876 }
4877 
4878 #undef __FUNCT__
4879 #define __FUNCT__ "MatScale"
4880 /*@
4881     MatScale - Scales all elements of a matrix by a given number.
4882 
4883     Logically Collective on Mat
4884 
4885     Input Parameters:
4886 +   mat - the matrix to be scaled
4887 -   a  - the scaling value
4888 
4889     Output Parameter:
4890 .   mat - the scaled matrix
4891 
4892     Level: intermediate
4893 
4894     Concepts: matrices^scaling all entries
4895 
4896 .seealso: MatDiagonalScale()
4897 @*/
4898 PetscErrorCode MatScale(Mat mat,PetscScalar a)
4899 {
4900   PetscErrorCode ierr;
4901 
4902   PetscFunctionBegin;
4903   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4904   PetscValidType(mat,1);
4905   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4906   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4907   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4908   PetscValidLogicalCollectiveScalar(mat,a,2);
4909   MatCheckPreallocated(mat,1);
4910 
4911   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4912   if (a != (PetscScalar)1.0) {
4913     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4914     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4915   }
4916   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4917 #if defined(PETSC_HAVE_CUSP)
4918   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4919     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4920   }
4921 #endif
4922 #if defined(PETSC_HAVE_VIENNACL)
4923   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4924     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4925   }
4926 #endif
4927   PetscFunctionReturn(0);
4928 }
4929 
4930 #undef __FUNCT__
4931 #define __FUNCT__ "MatNorm"
4932 /*@
4933    MatNorm - Calculates various norms of a matrix.
4934 
4935    Collective on Mat
4936 
4937    Input Parameters:
4938 +  mat - the matrix
4939 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4940 
4941    Output Parameters:
4942 .  nrm - the resulting norm
4943 
4944    Level: intermediate
4945 
4946    Concepts: matrices^norm
4947    Concepts: norm^of matrix
4948 @*/
4949 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4950 {
4951   PetscErrorCode ierr;
4952 
4953   PetscFunctionBegin;
4954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4955   PetscValidType(mat,1);
4956   PetscValidScalarPointer(nrm,3);
4957 
4958   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4959   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4960   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4961   MatCheckPreallocated(mat,1);
4962 
4963   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4964   PetscFunctionReturn(0);
4965 }
4966 
4967 /*
4968      This variable is used to prevent counting of MatAssemblyBegin() that
4969    are called from within a MatAssemblyEnd().
4970 */
4971 static PetscInt MatAssemblyEnd_InUse = 0;
4972 #undef __FUNCT__
4973 #define __FUNCT__ "MatAssemblyBegin"
4974 /*@
4975    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4976    be called after completing all calls to MatSetValues().
4977 
4978    Collective on Mat
4979 
4980    Input Parameters:
4981 +  mat - the matrix
4982 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4983 
4984    Notes:
4985    MatSetValues() generally caches the values.  The matrix is ready to
4986    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4987    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4988    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4989    using the matrix.
4990 
4991    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4992    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
4993    a global collective operation requring all processes that share the matrix.
4994 
4995    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4996    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4997    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4998 
4999    Level: beginner
5000 
5001    Concepts: matrices^assembling
5002 
5003 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5004 @*/
5005 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5006 {
5007   PetscErrorCode ierr;
5008 
5009   PetscFunctionBegin;
5010   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5011   PetscValidType(mat,1);
5012   MatCheckPreallocated(mat,1);
5013   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5014   if (mat->assembled) {
5015     mat->was_assembled = PETSC_TRUE;
5016     mat->assembled     = PETSC_FALSE;
5017   }
5018   if (!MatAssemblyEnd_InUse) {
5019     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5020     if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
5021     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
5022   } else if (mat->ops->assemblybegin) {
5023     ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);
5024   }
5025   PetscFunctionReturn(0);
5026 }
5027 
5028 #undef __FUNCT__
5029 #define __FUNCT__ "MatAssembled"
5030 /*@
5031    MatAssembled - Indicates if a matrix has been assembled and is ready for
5032      use; for example, in matrix-vector product.
5033 
5034    Not Collective
5035 
5036    Input Parameter:
5037 .  mat - the matrix
5038 
5039    Output Parameter:
5040 .  assembled - PETSC_TRUE or PETSC_FALSE
5041 
5042    Level: advanced
5043 
5044    Concepts: matrices^assembled?
5045 
5046 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5047 @*/
5048 PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
5049 {
5050   PetscFunctionBegin;
5051   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5052   PetscValidType(mat,1);
5053   PetscValidPointer(assembled,2);
5054   *assembled = mat->assembled;
5055   PetscFunctionReturn(0);
5056 }
5057 
5058 #undef __FUNCT__
5059 #define __FUNCT__ "MatAssemblyEnd"
5060 /*@
5061    MatAssemblyEnd - Completes assembling the matrix.  This routine should
5062    be called after MatAssemblyBegin().
5063 
5064    Collective on Mat
5065 
5066    Input Parameters:
5067 +  mat - the matrix
5068 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5069 
5070    Options Database Keys:
5071 +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5072 .  -mat_view ::ascii_info_detail - Prints more detailed info
5073 .  -mat_view - Prints matrix in ASCII format
5074 .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
5075 .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5076 .  -display <name> - Sets display name (default is host)
5077 .  -draw_pause <sec> - Sets number of seconds to pause after display
5078 .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab )
5079 .  -viewer_socket_machine <machine> - Machine to use for socket
5080 .  -viewer_socket_port <port> - Port number to use for socket
5081 -  -mat_view binary:filename[:append] - Save matrix to file in binary format
5082 
5083    Notes:
5084    MatSetValues() generally caches the values.  The matrix is ready to
5085    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5086    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5087    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5088    using the matrix.
5089 
5090    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5091    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5092    before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5093 
5094    Level: beginner
5095 
5096 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5097 @*/
5098 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5099 {
5100   PetscErrorCode  ierr;
5101   static PetscInt inassm = 0;
5102   PetscBool       flg    = PETSC_FALSE;
5103 
5104   PetscFunctionBegin;
5105   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5106   PetscValidType(mat,1);
5107 
5108   inassm++;
5109   MatAssemblyEnd_InUse++;
5110   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5111     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5112     if (mat->ops->assemblyend) {
5113       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5114     }
5115     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
5116   } else if (mat->ops->assemblyend) {
5117     ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
5118   }
5119 
5120   /* Flush assembly is not a true assembly */
5121   if (type != MAT_FLUSH_ASSEMBLY) {
5122     mat->assembled = PETSC_TRUE; mat->num_ass++;
5123   }
5124   mat->insertmode = NOT_SET_VALUES;
5125   MatAssemblyEnd_InUse--;
5126   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5127   if (!mat->symmetric_eternal) {
5128     mat->symmetric_set              = PETSC_FALSE;
5129     mat->hermitian_set              = PETSC_FALSE;
5130     mat->structurally_symmetric_set = PETSC_FALSE;
5131   }
5132 #if defined(PETSC_HAVE_CUSP)
5133   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5134     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5135   }
5136 #endif
5137 #if defined(PETSC_HAVE_VIENNACL)
5138   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5139     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5140   }
5141 #endif
5142   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5143     ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5144 
5145     if (mat->checksymmetryonassembly) {
5146       ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr);
5147       if (flg) {
5148         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5149       } else {
5150         ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr);
5151       }
5152     }
5153     if (mat->nullsp && mat->checknullspaceonassembly) {
5154       ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr);
5155     }
5156   }
5157   inassm--;
5158   PetscFunctionReturn(0);
5159 }
5160 
5161 #undef __FUNCT__
5162 #define __FUNCT__ "MatSetOption"
5163 /*@
5164    MatSetOption - Sets a parameter option for a matrix. Some options
5165    may be specific to certain storage formats.  Some options
5166    determine how values will be inserted (or added). Sorted,
5167    row-oriented input will generally assemble the fastest. The default
5168    is row-oriented.
5169 
5170    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5171 
5172    Input Parameters:
5173 +  mat - the matrix
5174 .  option - the option, one of those listed below (and possibly others),
5175 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5176 
5177   Options Describing Matrix Structure:
5178 +    MAT_SPD - symmetric positive definite
5179 .    MAT_SYMMETRIC - symmetric in terms of both structure and value
5180 .    MAT_HERMITIAN - transpose is the complex conjugation
5181 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5182 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5183                             you set to be kept with all future use of the matrix
5184                             including after MatAssemblyBegin/End() which could
5185                             potentially change the symmetry structure, i.e. you
5186                             KNOW the matrix will ALWAYS have the property you set.
5187 
5188 
5189    Options For Use with MatSetValues():
5190    Insert a logically dense subblock, which can be
5191 .    MAT_ROW_ORIENTED - row-oriented (default)
5192 
5193    Note these options reflect the data you pass in with MatSetValues(); it has
5194    nothing to do with how the data is stored internally in the matrix
5195    data structure.
5196 
5197    When (re)assembling a matrix, we can restrict the input for
5198    efficiency/debugging purposes.  These options include:
5199 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5200 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5201 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5202 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5203 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5204 .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5205         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5206         performance for very large process counts.
5207 -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5208         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5209         functions, instead sending only neighbor messages.
5210 
5211    Notes:
5212    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5213 
5214    Some options are relevant only for particular matrix types and
5215    are thus ignored by others.  Other options are not supported by
5216    certain matrix types and will generate an error message if set.
5217 
5218    If using a Fortran 77 module to compute a matrix, one may need to
5219    use the column-oriented option (or convert to the row-oriented
5220    format).
5221 
5222    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5223    that would generate a new entry in the nonzero structure is instead
5224    ignored.  Thus, if memory has not alredy been allocated for this particular
5225    data, then the insertion is ignored. For dense matrices, in which
5226    the entire array is allocated, no entries are ever ignored.
5227    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5228 
5229    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5230    that would generate a new entry in the nonzero structure instead produces
5231    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
5232 
5233    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5234    that would generate a new entry that has not been preallocated will
5235    instead produce an error. (Currently supported for AIJ and BAIJ formats
5236    only.) This is a useful flag when debugging matrix memory preallocation.
5237    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5238 
5239    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5240    other processors should be dropped, rather than stashed.
5241    This is useful if you know that the "owning" processor is also
5242    always generating the correct matrix entries, so that PETSc need
5243    not transfer duplicate entries generated on another processor.
5244 
5245    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5246    searches during matrix assembly. When this flag is set, the hash table
5247    is created during the first Matrix Assembly. This hash table is
5248    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5249    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5250    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5251    supported by MATMPIBAIJ format only.
5252 
5253    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5254    are kept in the nonzero structure
5255 
5256    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5257    a zero location in the matrix
5258 
5259    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5260 
5261    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5262         zero row routines and thus improves performance for very large process counts.
5263 
5264    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5265         part of the matrix (since they should match the upper triangular part).
5266 
5267    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5268 
5269    Level: intermediate
5270 
5271    Concepts: matrices^setting options
5272 
5273 .seealso:  MatOption, Mat
5274 
5275 @*/
5276 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5277 {
5278   PetscErrorCode ierr;
5279 
5280   PetscFunctionBegin;
5281   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5282   PetscValidType(mat,1);
5283   if (op > 0) {
5284     PetscValidLogicalCollectiveEnum(mat,op,2);
5285     PetscValidLogicalCollectiveBool(mat,flg,3);
5286   }
5287 
5288   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);
5289   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()");
5290 
5291   switch (op) {
5292   case MAT_NO_OFF_PROC_ENTRIES:
5293     mat->nooffprocentries = flg;
5294     PetscFunctionReturn(0);
5295     break;
5296   case MAT_SUBSET_OFF_PROC_ENTRIES:
5297     mat->subsetoffprocentries = flg;
5298     PetscFunctionReturn(0);
5299   case MAT_NO_OFF_PROC_ZERO_ROWS:
5300     mat->nooffproczerorows = flg;
5301     PetscFunctionReturn(0);
5302     break;
5303   case MAT_SPD:
5304     mat->spd_set = PETSC_TRUE;
5305     mat->spd     = flg;
5306     if (flg) {
5307       mat->symmetric                  = PETSC_TRUE;
5308       mat->structurally_symmetric     = PETSC_TRUE;
5309       mat->symmetric_set              = PETSC_TRUE;
5310       mat->structurally_symmetric_set = PETSC_TRUE;
5311     }
5312     break;
5313   case MAT_SYMMETRIC:
5314     mat->symmetric = flg;
5315     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5316     mat->symmetric_set              = PETSC_TRUE;
5317     mat->structurally_symmetric_set = flg;
5318     break;
5319   case MAT_HERMITIAN:
5320     mat->hermitian = flg;
5321     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5322     mat->hermitian_set              = PETSC_TRUE;
5323     mat->structurally_symmetric_set = flg;
5324     break;
5325   case MAT_STRUCTURALLY_SYMMETRIC:
5326     mat->structurally_symmetric     = flg;
5327     mat->structurally_symmetric_set = PETSC_TRUE;
5328     break;
5329   case MAT_SYMMETRY_ETERNAL:
5330     mat->symmetric_eternal = flg;
5331     break;
5332   default:
5333     break;
5334   }
5335   if (mat->ops->setoption) {
5336     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5337   }
5338   PetscFunctionReturn(0);
5339 }
5340 
5341 #undef __FUNCT__
5342 #define __FUNCT__ "MatGetOption"
5343 /*@
5344    MatGetOption - Gets a parameter option that has been set for a matrix.
5345 
5346    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5347 
5348    Input Parameters:
5349 +  mat - the matrix
5350 -  option - the option, this only responds to certain options, check the code for which ones
5351 
5352    Output Parameter:
5353 .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5354 
5355     Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5356 
5357    Level: intermediate
5358 
5359    Concepts: matrices^setting options
5360 
5361 .seealso:  MatOption, MatSetOption()
5362 
5363 @*/
5364 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5365 {
5366   PetscFunctionBegin;
5367   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5368   PetscValidType(mat,1);
5369 
5370   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);
5371   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()");
5372 
5373   switch (op) {
5374   case MAT_NO_OFF_PROC_ENTRIES:
5375     *flg = mat->nooffprocentries;
5376     break;
5377   case MAT_NO_OFF_PROC_ZERO_ROWS:
5378     *flg = mat->nooffproczerorows;
5379     break;
5380   case MAT_SYMMETRIC:
5381     *flg = mat->symmetric;
5382     break;
5383   case MAT_HERMITIAN:
5384     *flg = mat->hermitian;
5385     break;
5386   case MAT_STRUCTURALLY_SYMMETRIC:
5387     *flg = mat->structurally_symmetric;
5388     break;
5389   case MAT_SYMMETRY_ETERNAL:
5390     *flg = mat->symmetric_eternal;
5391     break;
5392   default:
5393     break;
5394   }
5395   PetscFunctionReturn(0);
5396 }
5397 
5398 #undef __FUNCT__
5399 #define __FUNCT__ "MatZeroEntries"
5400 /*@
5401    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5402    this routine retains the old nonzero structure.
5403 
5404    Logically Collective on Mat
5405 
5406    Input Parameters:
5407 .  mat - the matrix
5408 
5409    Level: intermediate
5410 
5411    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.
5412    See the Performance chapter of the users manual for information on preallocating matrices.
5413 
5414    Concepts: matrices^zeroing
5415 
5416 .seealso: MatZeroRows()
5417 @*/
5418 PetscErrorCode MatZeroEntries(Mat mat)
5419 {
5420   PetscErrorCode ierr;
5421 
5422   PetscFunctionBegin;
5423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5424   PetscValidType(mat,1);
5425   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5426   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");
5427   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5428   MatCheckPreallocated(mat,1);
5429 
5430   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5431   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5432   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5433   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5434 #if defined(PETSC_HAVE_CUSP)
5435   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5436     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5437   }
5438 #endif
5439 #if defined(PETSC_HAVE_VIENNACL)
5440   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5441     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5442   }
5443 #endif
5444   PetscFunctionReturn(0);
5445 }
5446 
5447 #undef __FUNCT__
5448 #define __FUNCT__ "MatZeroRowsColumns"
5449 /*@C
5450    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5451    of a set of rows and columns of a matrix.
5452 
5453    Collective on Mat
5454 
5455    Input Parameters:
5456 +  mat - the matrix
5457 .  numRows - the number of rows to remove
5458 .  rows - the global row indices
5459 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5460 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5461 -  b - optional vector of right hand side, that will be adjusted by provided solution
5462 
5463    Notes:
5464    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5465 
5466    The user can set a value in the diagonal entry (or for the AIJ and
5467    row formats can optionally remove the main diagonal entry from the
5468    nonzero structure as well, by passing 0.0 as the final argument).
5469 
5470    For the parallel case, all processes that share the matrix (i.e.,
5471    those in the communicator used for matrix creation) MUST call this
5472    routine, regardless of whether any rows being zeroed are owned by
5473    them.
5474 
5475    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5476    list only rows local to itself).
5477 
5478    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5479 
5480    Level: intermediate
5481 
5482    Concepts: matrices^zeroing rows
5483 
5484 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5485 @*/
5486 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5487 {
5488   PetscErrorCode ierr;
5489 
5490   PetscFunctionBegin;
5491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5492   PetscValidType(mat,1);
5493   if (numRows) PetscValidIntPointer(rows,3);
5494   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5495   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5496   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5497   MatCheckPreallocated(mat,1);
5498 
5499   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5500   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5501   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5502 #if defined(PETSC_HAVE_CUSP)
5503   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5504     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5505   }
5506 #endif
5507 #if defined(PETSC_HAVE_VIENNACL)
5508   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5509     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5510   }
5511 #endif
5512   PetscFunctionReturn(0);
5513 }
5514 
5515 #undef __FUNCT__
5516 #define __FUNCT__ "MatZeroRowsColumnsIS"
5517 /*@C
5518    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5519    of a set of rows and columns of a matrix.
5520 
5521    Collective on Mat
5522 
5523    Input Parameters:
5524 +  mat - the matrix
5525 .  is - the rows to zero
5526 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5527 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5528 -  b - optional vector of right hand side, that will be adjusted by provided solution
5529 
5530    Notes:
5531    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5532 
5533    The user can set a value in the diagonal entry (or for the AIJ and
5534    row formats can optionally remove the main diagonal entry from the
5535    nonzero structure as well, by passing 0.0 as the final argument).
5536 
5537    For the parallel case, all processes that share the matrix (i.e.,
5538    those in the communicator used for matrix creation) MUST call this
5539    routine, regardless of whether any rows being zeroed are owned by
5540    them.
5541 
5542    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5543    list only rows local to itself).
5544 
5545    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5546 
5547    Level: intermediate
5548 
5549    Concepts: matrices^zeroing rows
5550 
5551 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5552 @*/
5553 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5554 {
5555   PetscErrorCode ierr;
5556   PetscInt       numRows;
5557   const PetscInt *rows;
5558 
5559   PetscFunctionBegin;
5560   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5561   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5562   PetscValidType(mat,1);
5563   PetscValidType(is,2);
5564   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5565   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5566   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5567   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5568   PetscFunctionReturn(0);
5569 }
5570 
5571 #undef __FUNCT__
5572 #define __FUNCT__ "MatZeroRows"
5573 /*@C
5574    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5575    of a set of rows of a matrix.
5576 
5577    Collective on Mat
5578 
5579    Input Parameters:
5580 +  mat - the matrix
5581 .  numRows - the number of rows to remove
5582 .  rows - the global row indices
5583 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5584 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5585 -  b - optional vector of right hand side, that will be adjusted by provided solution
5586 
5587    Notes:
5588    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5589    but does not release memory.  For the dense and block diagonal
5590    formats this does not alter the nonzero structure.
5591 
5592    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5593    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5594    merely zeroed.
5595 
5596    The user can set a value in the diagonal entry (or for the AIJ and
5597    row formats can optionally remove the main diagonal entry from the
5598    nonzero structure as well, by passing 0.0 as the final argument).
5599 
5600    For the parallel case, all processes that share the matrix (i.e.,
5601    those in the communicator used for matrix creation) MUST call this
5602    routine, regardless of whether any rows being zeroed are owned by
5603    them.
5604 
5605    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5606    list only rows local to itself).
5607 
5608    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5609    owns that are to be zeroed. This saves a global synchronization in the implementation.
5610 
5611    Level: intermediate
5612 
5613    Concepts: matrices^zeroing rows
5614 
5615 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5616 @*/
5617 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5618 {
5619   PetscErrorCode ierr;
5620 
5621   PetscFunctionBegin;
5622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5623   PetscValidType(mat,1);
5624   if (numRows) PetscValidIntPointer(rows,3);
5625   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5626   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5627   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5628   MatCheckPreallocated(mat,1);
5629 
5630   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5631   ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr);
5632   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5633 #if defined(PETSC_HAVE_CUSP)
5634   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5635     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5636   }
5637 #endif
5638 #if defined(PETSC_HAVE_VIENNACL)
5639   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5640     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5641   }
5642 #endif
5643   PetscFunctionReturn(0);
5644 }
5645 
5646 #undef __FUNCT__
5647 #define __FUNCT__ "MatZeroRowsIS"
5648 /*@C
5649    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5650    of a set of rows of a matrix.
5651 
5652    Collective on Mat
5653 
5654    Input Parameters:
5655 +  mat - the matrix
5656 .  is - index set of rows to remove
5657 .  diag - value put in all diagonals of eliminated rows
5658 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5659 -  b - optional vector of right hand side, that will be adjusted by provided solution
5660 
5661    Notes:
5662    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5663    but does not release memory.  For the dense and block diagonal
5664    formats this does not alter the nonzero structure.
5665 
5666    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5667    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5668    merely zeroed.
5669 
5670    The user can set a value in the diagonal entry (or for the AIJ and
5671    row formats can optionally remove the main diagonal entry from the
5672    nonzero structure as well, by passing 0.0 as the final argument).
5673 
5674    For the parallel case, all processes that share the matrix (i.e.,
5675    those in the communicator used for matrix creation) MUST call this
5676    routine, regardless of whether any rows being zeroed are owned by
5677    them.
5678 
5679    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5680    list only rows local to itself).
5681 
5682    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5683    owns that are to be zeroed. This saves a global synchronization in the implementation.
5684 
5685    Level: intermediate
5686 
5687    Concepts: matrices^zeroing rows
5688 
5689 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5690 @*/
5691 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5692 {
5693   PetscInt       numRows;
5694   const PetscInt *rows;
5695   PetscErrorCode ierr;
5696 
5697   PetscFunctionBegin;
5698   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5699   PetscValidType(mat,1);
5700   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5701   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5702   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5703   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5704   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5705   PetscFunctionReturn(0);
5706 }
5707 
5708 #undef __FUNCT__
5709 #define __FUNCT__ "MatZeroRowsStencil"
5710 /*@C
5711    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5712    of a set of rows of a matrix. These rows must be local to the process.
5713 
5714    Collective on Mat
5715 
5716    Input Parameters:
5717 +  mat - the matrix
5718 .  numRows - the number of rows to remove
5719 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5720 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5721 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5722 -  b - optional vector of right hand side, that will be adjusted by provided solution
5723 
5724    Notes:
5725    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5726    but does not release memory.  For the dense and block diagonal
5727    formats this does not alter the nonzero structure.
5728 
5729    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5730    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5731    merely zeroed.
5732 
5733    The user can set a value in the diagonal entry (or for the AIJ and
5734    row formats can optionally remove the main diagonal entry from the
5735    nonzero structure as well, by passing 0.0 as the final argument).
5736 
5737    For the parallel case, all processes that share the matrix (i.e.,
5738    those in the communicator used for matrix creation) MUST call this
5739    routine, regardless of whether any rows being zeroed are owned by
5740    them.
5741 
5742    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5743    list only rows local to itself).
5744 
5745    The grid coordinates are across the entire grid, not just the local portion
5746 
5747    In Fortran idxm and idxn should be declared as
5748 $     MatStencil idxm(4,m)
5749    and the values inserted using
5750 $    idxm(MatStencil_i,1) = i
5751 $    idxm(MatStencil_j,1) = j
5752 $    idxm(MatStencil_k,1) = k
5753 $    idxm(MatStencil_c,1) = c
5754    etc
5755 
5756    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5757    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5758    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5759    DM_BOUNDARY_PERIODIC boundary type.
5760 
5761    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
5762    a single value per point) you can skip filling those indices.
5763 
5764    Level: intermediate
5765 
5766    Concepts: matrices^zeroing rows
5767 
5768 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5769 @*/
5770 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5771 {
5772   PetscInt       dim     = mat->stencil.dim;
5773   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5774   PetscInt       *dims   = mat->stencil.dims+1;
5775   PetscInt       *starts = mat->stencil.starts;
5776   PetscInt       *dxm    = (PetscInt*) rows;
5777   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5778   PetscErrorCode ierr;
5779 
5780   PetscFunctionBegin;
5781   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5782   PetscValidType(mat,1);
5783   if (numRows) PetscValidIntPointer(rows,3);
5784 
5785   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5786   for (i = 0; i < numRows; ++i) {
5787     /* Skip unused dimensions (they are ordered k, j, i, c) */
5788     for (j = 0; j < 3-sdim; ++j) dxm++;
5789     /* Local index in X dir */
5790     tmp = *dxm++ - starts[0];
5791     /* Loop over remaining dimensions */
5792     for (j = 0; j < dim-1; ++j) {
5793       /* If nonlocal, set index to be negative */
5794       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5795       /* Update local index */
5796       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5797     }
5798     /* Skip component slot if necessary */
5799     if (mat->stencil.noc) dxm++;
5800     /* Local row number */
5801     if (tmp >= 0) {
5802       jdxm[numNewRows++] = tmp;
5803     }
5804   }
5805   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5806   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5807   PetscFunctionReturn(0);
5808 }
5809 
5810 #undef __FUNCT__
5811 #define __FUNCT__ "MatZeroRowsColumnsStencil"
5812 /*@C
5813    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5814    of a set of rows and columns of a matrix.
5815 
5816    Collective on Mat
5817 
5818    Input Parameters:
5819 +  mat - the matrix
5820 .  numRows - the number of rows/columns to remove
5821 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5822 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5823 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5824 -  b - optional vector of right hand side, that will be adjusted by provided solution
5825 
5826    Notes:
5827    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5828    but does not release memory.  For the dense and block diagonal
5829    formats this does not alter the nonzero structure.
5830 
5831    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5832    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5833    merely zeroed.
5834 
5835    The user can set a value in the diagonal entry (or for the AIJ and
5836    row formats can optionally remove the main diagonal entry from the
5837    nonzero structure as well, by passing 0.0 as the final argument).
5838 
5839    For the parallel case, all processes that share the matrix (i.e.,
5840    those in the communicator used for matrix creation) MUST call this
5841    routine, regardless of whether any rows being zeroed are owned by
5842    them.
5843 
5844    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5845    list only rows local to itself, but the row/column numbers are given in local numbering).
5846 
5847    The grid coordinates are across the entire grid, not just the local portion
5848 
5849    In Fortran idxm and idxn should be declared as
5850 $     MatStencil idxm(4,m)
5851    and the values inserted using
5852 $    idxm(MatStencil_i,1) = i
5853 $    idxm(MatStencil_j,1) = j
5854 $    idxm(MatStencil_k,1) = k
5855 $    idxm(MatStencil_c,1) = c
5856    etc
5857 
5858    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5859    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5860    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5861    DM_BOUNDARY_PERIODIC boundary type.
5862 
5863    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
5864    a single value per point) you can skip filling those indices.
5865 
5866    Level: intermediate
5867 
5868    Concepts: matrices^zeroing rows
5869 
5870 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5871 @*/
5872 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5873 {
5874   PetscInt       dim     = mat->stencil.dim;
5875   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
5876   PetscInt       *dims   = mat->stencil.dims+1;
5877   PetscInt       *starts = mat->stencil.starts;
5878   PetscInt       *dxm    = (PetscInt*) rows;
5879   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;
5880   PetscErrorCode ierr;
5881 
5882   PetscFunctionBegin;
5883   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5884   PetscValidType(mat,1);
5885   if (numRows) PetscValidIntPointer(rows,3);
5886 
5887   ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr);
5888   for (i = 0; i < numRows; ++i) {
5889     /* Skip unused dimensions (they are ordered k, j, i, c) */
5890     for (j = 0; j < 3-sdim; ++j) dxm++;
5891     /* Local index in X dir */
5892     tmp = *dxm++ - starts[0];
5893     /* Loop over remaining dimensions */
5894     for (j = 0; j < dim-1; ++j) {
5895       /* If nonlocal, set index to be negative */
5896       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5897       /* Update local index */
5898       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5899     }
5900     /* Skip component slot if necessary */
5901     if (mat->stencil.noc) dxm++;
5902     /* Local row number */
5903     if (tmp >= 0) {
5904       jdxm[numNewRows++] = tmp;
5905     }
5906   }
5907   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5908   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5909   PetscFunctionReturn(0);
5910 }
5911 
5912 #undef __FUNCT__
5913 #define __FUNCT__ "MatZeroRowsLocal"
5914 /*@C
5915    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5916    of a set of rows of a matrix; using local numbering of rows.
5917 
5918    Collective on Mat
5919 
5920    Input Parameters:
5921 +  mat - the matrix
5922 .  numRows - the number of rows to remove
5923 .  rows - the global row indices
5924 .  diag - value put in all diagonals of eliminated rows
5925 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5926 -  b - optional vector of right hand side, that will be adjusted by provided solution
5927 
5928    Notes:
5929    Before calling MatZeroRowsLocal(), the user must first set the
5930    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5931 
5932    For the AIJ matrix formats this removes the old nonzero structure,
5933    but does not release memory.  For the dense and block diagonal
5934    formats this does not alter the nonzero structure.
5935 
5936    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5937    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5938    merely zeroed.
5939 
5940    The user can set a value in the diagonal entry (or for the AIJ and
5941    row formats can optionally remove the main diagonal entry from the
5942    nonzero structure as well, by passing 0.0 as the final argument).
5943 
5944    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5945    owns that are to be zeroed. This saves a global synchronization in the implementation.
5946 
5947    Level: intermediate
5948 
5949    Concepts: matrices^zeroing
5950 
5951 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5952 @*/
5953 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5954 {
5955   PetscErrorCode ierr;
5956 
5957   PetscFunctionBegin;
5958   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5959   PetscValidType(mat,1);
5960   if (numRows) PetscValidIntPointer(rows,3);
5961   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5962   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5963   MatCheckPreallocated(mat,1);
5964 
5965   if (mat->ops->zerorowslocal) {
5966     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5967   } else {
5968     IS             is, newis;
5969     const PetscInt *newRows;
5970 
5971     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5972     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5973     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5974     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5975     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5976     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5977     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5978     ierr = ISDestroy(&is);CHKERRQ(ierr);
5979   }
5980   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5981 #if defined(PETSC_HAVE_CUSP)
5982   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5983     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5984   }
5985 #endif
5986 #if defined(PETSC_HAVE_VIENNACL)
5987   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5988     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5989   }
5990 #endif
5991   PetscFunctionReturn(0);
5992 }
5993 
5994 #undef __FUNCT__
5995 #define __FUNCT__ "MatZeroRowsLocalIS"
5996 /*@C
5997    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5998    of a set of rows of a matrix; using local numbering of rows.
5999 
6000    Collective on Mat
6001 
6002    Input Parameters:
6003 +  mat - the matrix
6004 .  is - index set of rows to remove
6005 .  diag - value put in all diagonals of eliminated rows
6006 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6007 -  b - optional vector of right hand side, that will be adjusted by provided solution
6008 
6009    Notes:
6010    Before calling MatZeroRowsLocalIS(), the user must first set the
6011    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6012 
6013    For the AIJ matrix formats this removes the old nonzero structure,
6014    but does not release memory.  For the dense and block diagonal
6015    formats this does not alter the nonzero structure.
6016 
6017    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6018    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6019    merely zeroed.
6020 
6021    The user can set a value in the diagonal entry (or for the AIJ and
6022    row formats can optionally remove the main diagonal entry from the
6023    nonzero structure as well, by passing 0.0 as the final argument).
6024 
6025    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6026    owns that are to be zeroed. This saves a global synchronization in the implementation.
6027 
6028    Level: intermediate
6029 
6030    Concepts: matrices^zeroing
6031 
6032 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6033 @*/
6034 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6035 {
6036   PetscErrorCode ierr;
6037   PetscInt       numRows;
6038   const PetscInt *rows;
6039 
6040   PetscFunctionBegin;
6041   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6042   PetscValidType(mat,1);
6043   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6044   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6045   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6046   MatCheckPreallocated(mat,1);
6047 
6048   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6049   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6050   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6051   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6052   PetscFunctionReturn(0);
6053 }
6054 
6055 #undef __FUNCT__
6056 #define __FUNCT__ "MatZeroRowsColumnsLocal"
6057 /*@C
6058    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6059    of a set of rows and columns of a matrix; using local numbering of rows.
6060 
6061    Collective on Mat
6062 
6063    Input Parameters:
6064 +  mat - the matrix
6065 .  numRows - the number of rows to remove
6066 .  rows - the global row indices
6067 .  diag - value put in all diagonals of eliminated rows
6068 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6069 -  b - optional vector of right hand side, that will be adjusted by provided solution
6070 
6071    Notes:
6072    Before calling MatZeroRowsColumnsLocal(), the user must first set the
6073    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6074 
6075    The user can set a value in the diagonal entry (or for the AIJ and
6076    row formats can optionally remove the main diagonal entry from the
6077    nonzero structure as well, by passing 0.0 as the final argument).
6078 
6079    Level: intermediate
6080 
6081    Concepts: matrices^zeroing
6082 
6083 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6084 @*/
6085 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6086 {
6087   PetscErrorCode ierr;
6088   IS             is, newis;
6089   const PetscInt *newRows;
6090 
6091   PetscFunctionBegin;
6092   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6093   PetscValidType(mat,1);
6094   if (numRows) PetscValidIntPointer(rows,3);
6095   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6096   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6097   MatCheckPreallocated(mat,1);
6098 
6099   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6100   ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
6101   ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
6102   ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
6103   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
6104   ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
6105   ierr = ISDestroy(&newis);CHKERRQ(ierr);
6106   ierr = ISDestroy(&is);CHKERRQ(ierr);
6107   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6108 #if defined(PETSC_HAVE_CUSP)
6109   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6110     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6111   }
6112 #endif
6113 #if defined(PETSC_HAVE_VIENNACL)
6114   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6115     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6116   }
6117 #endif
6118   PetscFunctionReturn(0);
6119 }
6120 
6121 #undef __FUNCT__
6122 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
6123 /*@C
6124    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6125    of a set of rows and columns of a matrix; using local numbering of rows.
6126 
6127    Collective on Mat
6128 
6129    Input Parameters:
6130 +  mat - the matrix
6131 .  is - index set of rows to remove
6132 .  diag - value put in all diagonals of eliminated rows
6133 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6134 -  b - optional vector of right hand side, that will be adjusted by provided solution
6135 
6136    Notes:
6137    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6138    local-to-global mapping by calling MatSetLocalToGlobalMapping().
6139 
6140    The user can set a value in the diagonal entry (or for the AIJ and
6141    row formats can optionally remove the main diagonal entry from the
6142    nonzero structure as well, by passing 0.0 as the final argument).
6143 
6144    Level: intermediate
6145 
6146    Concepts: matrices^zeroing
6147 
6148 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6149 @*/
6150 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6151 {
6152   PetscErrorCode ierr;
6153   PetscInt       numRows;
6154   const PetscInt *rows;
6155 
6156   PetscFunctionBegin;
6157   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6158   PetscValidType(mat,1);
6159   PetscValidHeaderSpecific(is,IS_CLASSID,2);
6160   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6161   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6162   MatCheckPreallocated(mat,1);
6163 
6164   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
6165   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
6166   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
6167   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
6168   PetscFunctionReturn(0);
6169 }
6170 
6171 #undef __FUNCT__
6172 #define __FUNCT__ "MatGetSize"
6173 /*@
6174    MatGetSize - Returns the numbers of rows and columns in a matrix.
6175 
6176    Not Collective
6177 
6178    Input Parameter:
6179 .  mat - the matrix
6180 
6181    Output Parameters:
6182 +  m - the number of global rows
6183 -  n - the number of global columns
6184 
6185    Note: both output parameters can be NULL on input.
6186 
6187    Level: beginner
6188 
6189    Concepts: matrices^size
6190 
6191 .seealso: MatGetLocalSize()
6192 @*/
6193 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6194 {
6195   PetscFunctionBegin;
6196   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6197   if (m) *m = mat->rmap->N;
6198   if (n) *n = mat->cmap->N;
6199   PetscFunctionReturn(0);
6200 }
6201 
6202 #undef __FUNCT__
6203 #define __FUNCT__ "MatGetLocalSize"
6204 /*@
6205    MatGetLocalSize - Returns the number of rows and columns in a matrix
6206    stored locally.  This information may be implementation dependent, so
6207    use with care.
6208 
6209    Not Collective
6210 
6211    Input Parameters:
6212 .  mat - the matrix
6213 
6214    Output Parameters:
6215 +  m - the number of local rows
6216 -  n - the number of local columns
6217 
6218    Note: both output parameters can be NULL on input.
6219 
6220    Level: beginner
6221 
6222    Concepts: matrices^local size
6223 
6224 .seealso: MatGetSize()
6225 @*/
6226 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6227 {
6228   PetscFunctionBegin;
6229   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6230   if (m) PetscValidIntPointer(m,2);
6231   if (n) PetscValidIntPointer(n,3);
6232   if (m) *m = mat->rmap->n;
6233   if (n) *n = mat->cmap->n;
6234   PetscFunctionReturn(0);
6235 }
6236 
6237 #undef __FUNCT__
6238 #define __FUNCT__ "MatGetOwnershipRangeColumn"
6239 /*@
6240    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6241    this processor. (The columns of the "diagonal block")
6242 
6243    Not Collective, unless matrix has not been allocated, then collective on Mat
6244 
6245    Input Parameters:
6246 .  mat - the matrix
6247 
6248    Output Parameters:
6249 +  m - the global index of the first local column
6250 -  n - one more than the global index of the last local column
6251 
6252    Notes: both output parameters can be NULL on input.
6253 
6254    Level: developer
6255 
6256    Concepts: matrices^column ownership
6257 
6258 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6259 
6260 @*/
6261 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6262 {
6263   PetscFunctionBegin;
6264   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6265   PetscValidType(mat,1);
6266   if (m) PetscValidIntPointer(m,2);
6267   if (n) PetscValidIntPointer(n,3);
6268   MatCheckPreallocated(mat,1);
6269   if (m) *m = mat->cmap->rstart;
6270   if (n) *n = mat->cmap->rend;
6271   PetscFunctionReturn(0);
6272 }
6273 
6274 #undef __FUNCT__
6275 #define __FUNCT__ "MatGetOwnershipRange"
6276 /*@
6277    MatGetOwnershipRange - Returns the range of matrix rows owned by
6278    this processor, assuming that the matrix is laid out with the first
6279    n1 rows on the first processor, the next n2 rows on the second, etc.
6280    For certain parallel layouts this range may not be well defined.
6281 
6282    Not Collective
6283 
6284    Input Parameters:
6285 .  mat - the matrix
6286 
6287    Output Parameters:
6288 +  m - the global index of the first local row
6289 -  n - one more than the global index of the last local row
6290 
6291    Note: Both output parameters can be NULL on input.
6292 $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
6293 $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6294 $  and then MPI_Scan() to calculate prefix sums of the local sizes.
6295 
6296    Level: beginner
6297 
6298    Concepts: matrices^row ownership
6299 
6300 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6301 
6302 @*/
6303 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6304 {
6305   PetscFunctionBegin;
6306   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6307   PetscValidType(mat,1);
6308   if (m) PetscValidIntPointer(m,2);
6309   if (n) PetscValidIntPointer(n,3);
6310   MatCheckPreallocated(mat,1);
6311   if (m) *m = mat->rmap->rstart;
6312   if (n) *n = mat->rmap->rend;
6313   PetscFunctionReturn(0);
6314 }
6315 
6316 #undef __FUNCT__
6317 #define __FUNCT__ "MatGetOwnershipRanges"
6318 /*@C
6319    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6320    each process
6321 
6322    Not Collective, unless matrix has not been allocated, then collective on Mat
6323 
6324    Input Parameters:
6325 .  mat - the matrix
6326 
6327    Output Parameters:
6328 .  ranges - start of each processors portion plus one more than the total length at the end
6329 
6330    Level: beginner
6331 
6332    Concepts: matrices^row ownership
6333 
6334 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6335 
6336 @*/
6337 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6338 {
6339   PetscErrorCode ierr;
6340 
6341   PetscFunctionBegin;
6342   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6343   PetscValidType(mat,1);
6344   MatCheckPreallocated(mat,1);
6345   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6346   PetscFunctionReturn(0);
6347 }
6348 
6349 #undef __FUNCT__
6350 #define __FUNCT__ "MatGetOwnershipRangesColumn"
6351 /*@C
6352    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6353    this processor. (The columns of the "diagonal blocks" for each process)
6354 
6355    Not Collective, unless matrix has not been allocated, then collective on Mat
6356 
6357    Input Parameters:
6358 .  mat - the matrix
6359 
6360    Output Parameters:
6361 .  ranges - start of each processors portion plus one more then the total length at the end
6362 
6363    Level: beginner
6364 
6365    Concepts: matrices^column ownership
6366 
6367 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6368 
6369 @*/
6370 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6371 {
6372   PetscErrorCode ierr;
6373 
6374   PetscFunctionBegin;
6375   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6376   PetscValidType(mat,1);
6377   MatCheckPreallocated(mat,1);
6378   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6379   PetscFunctionReturn(0);
6380 }
6381 
6382 #undef __FUNCT__
6383 #define __FUNCT__ "MatGetOwnershipIS"
6384 /*@C
6385    MatGetOwnershipIS - Get row and column ownership as index sets
6386 
6387    Not Collective
6388 
6389    Input Arguments:
6390 .  A - matrix of type Elemental
6391 
6392    Output Arguments:
6393 +  rows - rows in which this process owns elements
6394 .  cols - columns in which this process owns elements
6395 
6396    Level: intermediate
6397 
6398 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6399 @*/
6400 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6401 {
6402   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6403 
6404   PetscFunctionBegin;
6405   MatCheckPreallocated(A,1);
6406   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr);
6407   if (f) {
6408     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6409   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6410     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6411     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6412   }
6413   PetscFunctionReturn(0);
6414 }
6415 
6416 #undef __FUNCT__
6417 #define __FUNCT__ "MatILUFactorSymbolic"
6418 /*@C
6419    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6420    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6421    to complete the factorization.
6422 
6423    Collective on Mat
6424 
6425    Input Parameters:
6426 +  mat - the matrix
6427 .  row - row permutation
6428 .  column - column permutation
6429 -  info - structure containing
6430 $      levels - number of levels of fill.
6431 $      expected fill - as ratio of original fill.
6432 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6433                 missing diagonal entries)
6434 
6435    Output Parameters:
6436 .  fact - new matrix that has been symbolically factored
6437 
6438    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6439 
6440    Most users should employ the simplified KSP interface for linear solvers
6441    instead of working directly with matrix algebra routines such as this.
6442    See, e.g., KSPCreate().
6443 
6444    Level: developer
6445 
6446   Concepts: matrices^symbolic LU factorization
6447   Concepts: matrices^factorization
6448   Concepts: LU^symbolic factorization
6449 
6450 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6451           MatGetOrdering(), MatFactorInfo
6452 
6453     Developer Note: fortran interface is not autogenerated as the f90
6454     interface defintion cannot be generated correctly [due to MatFactorInfo]
6455 
6456 @*/
6457 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6458 {
6459   PetscErrorCode ierr;
6460 
6461   PetscFunctionBegin;
6462   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6463   PetscValidType(mat,1);
6464   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6465   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6466   PetscValidPointer(info,4);
6467   PetscValidPointer(fact,5);
6468   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6469   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6470   if (!(fact)->ops->ilufactorsymbolic) {
6471     const MatSolverPackage spackage;
6472     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6473     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6474   }
6475   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6476   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6477   MatCheckPreallocated(mat,2);
6478 
6479   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6480   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6481   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6482   PetscFunctionReturn(0);
6483 }
6484 
6485 #undef __FUNCT__
6486 #define __FUNCT__ "MatICCFactorSymbolic"
6487 /*@C
6488    MatICCFactorSymbolic - Performs symbolic incomplete
6489    Cholesky factorization for a symmetric matrix.  Use
6490    MatCholeskyFactorNumeric() to complete the factorization.
6491 
6492    Collective on Mat
6493 
6494    Input Parameters:
6495 +  mat - the matrix
6496 .  perm - row and column permutation
6497 -  info - structure containing
6498 $      levels - number of levels of fill.
6499 $      expected fill - as ratio of original fill.
6500 
6501    Output Parameter:
6502 .  fact - the factored matrix
6503 
6504    Notes:
6505    Most users should employ the KSP interface for linear solvers
6506    instead of working directly with matrix algebra routines such as this.
6507    See, e.g., KSPCreate().
6508 
6509    Level: developer
6510 
6511   Concepts: matrices^symbolic incomplete Cholesky factorization
6512   Concepts: matrices^factorization
6513   Concepts: Cholsky^symbolic factorization
6514 
6515 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6516 
6517     Developer Note: fortran interface is not autogenerated as the f90
6518     interface defintion cannot be generated correctly [due to MatFactorInfo]
6519 
6520 @*/
6521 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6522 {
6523   PetscErrorCode ierr;
6524 
6525   PetscFunctionBegin;
6526   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6527   PetscValidType(mat,1);
6528   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6529   PetscValidPointer(info,3);
6530   PetscValidPointer(fact,4);
6531   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6532   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6533   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6534   if (!(fact)->ops->iccfactorsymbolic) {
6535     const MatSolverPackage spackage;
6536     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6537     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6538   }
6539   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6540   MatCheckPreallocated(mat,2);
6541 
6542   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6543   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6544   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6545   PetscFunctionReturn(0);
6546 }
6547 
6548 #undef __FUNCT__
6549 #define __FUNCT__ "MatGetSubMatrices"
6550 /*@C
6551    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6552    points to an array of valid matrices, they may be reused to store the new
6553    submatrices.
6554 
6555    Collective on Mat
6556 
6557    Input Parameters:
6558 +  mat - the matrix
6559 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6560 .  irow, icol - index sets of rows and columns to extract
6561 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6562 
6563    Output Parameter:
6564 .  submat - the array of submatrices
6565 
6566    Notes:
6567    MatGetSubMatrices() can extract ONLY sequential submatrices
6568    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6569    to extract a parallel submatrix.
6570 
6571    Some matrix types place restrictions on the row and column
6572    indices, such as that they be sorted or that they be equal to each other.
6573 
6574    The index sets may not have duplicate entries.
6575 
6576    When extracting submatrices from a parallel matrix, each processor can
6577    form a different submatrix by setting the rows and columns of its
6578    individual index sets according to the local submatrix desired.
6579 
6580    When finished using the submatrices, the user should destroy
6581    them with MatDestroyMatrices().
6582 
6583    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6584    original matrix has not changed from that last call to MatGetSubMatrices().
6585 
6586    This routine creates the matrices in submat; you should NOT create them before
6587    calling it. It also allocates the array of matrix pointers submat.
6588 
6589    For BAIJ matrices the index sets must respect the block structure, that is if they
6590    request one row/column in a block, they must request all rows/columns that are in
6591    that block. For example, if the block size is 2 you cannot request just row 0 and
6592    column 0.
6593 
6594    Fortran Note:
6595    The Fortran interface is slightly different from that given below; it
6596    requires one to pass in  as submat a Mat (integer) array of size at least m.
6597 
6598    Level: advanced
6599 
6600    Concepts: matrices^accessing submatrices
6601    Concepts: submatrices
6602 
6603 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6604 @*/
6605 PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6606 {
6607   PetscErrorCode ierr;
6608   PetscInt       i;
6609   PetscBool      eq;
6610 
6611   PetscFunctionBegin;
6612   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6613   PetscValidType(mat,1);
6614   if (n) {
6615     PetscValidPointer(irow,3);
6616     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6617     PetscValidPointer(icol,4);
6618     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6619   }
6620   PetscValidPointer(submat,6);
6621   if (n && scall == MAT_REUSE_MATRIX) {
6622     PetscValidPointer(*submat,6);
6623     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6624   }
6625   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6626   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6627   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6628   MatCheckPreallocated(mat,1);
6629 
6630   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6631   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6632   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6633   for (i=0; i<n; i++) {
6634     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
6635     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6636       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6637       if (eq) {
6638         if (mat->symmetric) {
6639           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6640         } else if (mat->hermitian) {
6641           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6642         } else if (mat->structurally_symmetric) {
6643           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6644         }
6645       }
6646     }
6647   }
6648   PetscFunctionReturn(0);
6649 }
6650 
6651 #undef __FUNCT__
6652 #define __FUNCT__ "MatGetSubMatricesMPI"
6653 PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6654 {
6655   PetscErrorCode ierr;
6656   PetscInt       i;
6657   PetscBool      eq;
6658 
6659   PetscFunctionBegin;
6660   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6661   PetscValidType(mat,1);
6662   if (n) {
6663     PetscValidPointer(irow,3);
6664     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6665     PetscValidPointer(icol,4);
6666     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6667   }
6668   PetscValidPointer(submat,6);
6669   if (n && scall == MAT_REUSE_MATRIX) {
6670     PetscValidPointer(*submat,6);
6671     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6672   }
6673   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6674   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6675   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6676   MatCheckPreallocated(mat,1);
6677 
6678   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6679   ierr = (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6680   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6681   for (i=0; i<n; i++) {
6682     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6683       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6684       if (eq) {
6685         if (mat->symmetric) {
6686           ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6687         } else if (mat->hermitian) {
6688           ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6689         } else if (mat->structurally_symmetric) {
6690           ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6691         }
6692       }
6693     }
6694   }
6695   PetscFunctionReturn(0);
6696 }
6697 
6698 #undef __FUNCT__
6699 #define __FUNCT__ "MatDestroyMatrices"
6700 /*@C
6701    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6702 
6703    Collective on Mat
6704 
6705    Input Parameters:
6706 +  n - the number of local matrices
6707 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6708                        sequence of MatGetSubMatrices())
6709 
6710    Level: advanced
6711 
6712     Notes: Frees not only the matrices, but also the array that contains the matrices
6713            In Fortran will not free the array.
6714 
6715 .seealso: MatGetSubMatrices()
6716 @*/
6717 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6718 {
6719   PetscErrorCode ierr;
6720   PetscInt       i;
6721 
6722   PetscFunctionBegin;
6723   if (!*mat) PetscFunctionReturn(0);
6724   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6725   PetscValidPointer(mat,2);
6726   for (i=0; i<n; i++) {
6727     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6728   }
6729   /* memory is allocated even if n = 0 */
6730   ierr = PetscFree(*mat);CHKERRQ(ierr);
6731   *mat = NULL;
6732   PetscFunctionReturn(0);
6733 }
6734 
6735 #undef __FUNCT__
6736 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6737 /*@C
6738    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6739 
6740    Collective on Mat
6741 
6742    Input Parameters:
6743 .  mat - the matrix
6744 
6745    Output Parameter:
6746 .  matstruct - the sequential matrix with the nonzero structure of mat
6747 
6748   Level: intermediate
6749 
6750 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6751 @*/
6752 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6753 {
6754   PetscErrorCode ierr;
6755 
6756   PetscFunctionBegin;
6757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6758   PetscValidPointer(matstruct,2);
6759 
6760   PetscValidType(mat,1);
6761   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6762   MatCheckPreallocated(mat,1);
6763 
6764   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6765   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6766   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6767   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6768   PetscFunctionReturn(0);
6769 }
6770 
6771 #undef __FUNCT__
6772 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6773 /*@C
6774    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6775 
6776    Collective on Mat
6777 
6778    Input Parameters:
6779 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6780                        sequence of MatGetSequentialNonzeroStructure())
6781 
6782    Level: advanced
6783 
6784     Notes: Frees not only the matrices, but also the array that contains the matrices
6785 
6786 .seealso: MatGetSeqNonzeroStructure()
6787 @*/
6788 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6789 {
6790   PetscErrorCode ierr;
6791 
6792   PetscFunctionBegin;
6793   PetscValidPointer(mat,1);
6794   ierr = MatDestroy(mat);CHKERRQ(ierr);
6795   PetscFunctionReturn(0);
6796 }
6797 
6798 #undef __FUNCT__
6799 #define __FUNCT__ "MatIncreaseOverlap"
6800 /*@
6801    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6802    replaces the index sets by larger ones that represent submatrices with
6803    additional overlap.
6804 
6805    Collective on Mat
6806 
6807    Input Parameters:
6808 +  mat - the matrix
6809 .  n   - the number of index sets
6810 .  is  - the array of index sets (these index sets will changed during the call)
6811 -  ov  - the additional overlap requested
6812 
6813    Options Database:
6814 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6815 
6816    Level: developer
6817 
6818    Concepts: overlap
6819    Concepts: ASM^computing overlap
6820 
6821 .seealso: MatGetSubMatrices()
6822 @*/
6823 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6824 {
6825   PetscErrorCode ierr;
6826 
6827   PetscFunctionBegin;
6828   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6829   PetscValidType(mat,1);
6830   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6831   if (n) {
6832     PetscValidPointer(is,3);
6833     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6834   }
6835   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6836   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6837   MatCheckPreallocated(mat,1);
6838 
6839   if (!ov) PetscFunctionReturn(0);
6840   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6841   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6842   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6843   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6844   PetscFunctionReturn(0);
6845 }
6846 
6847 
6848 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6849 
6850 #undef __FUNCT__
6851 #define __FUNCT__ "MatIncreaseOverlapSplit"
6852 /*@
6853    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6854    a sub communicator, replaces the index sets by larger ones that represent submatrices with
6855    additional overlap.
6856 
6857    Collective on Mat
6858 
6859    Input Parameters:
6860 +  mat - the matrix
6861 .  n   - the number of index sets
6862 .  is  - the array of index sets (these index sets will changed during the call)
6863 -  ov  - the additional overlap requested
6864 
6865    Options Database:
6866 .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6867 
6868    Level: developer
6869 
6870    Concepts: overlap
6871    Concepts: ASM^computing overlap
6872 
6873 .seealso: MatGetSubMatrices()
6874 @*/
6875 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6876 {
6877   PetscInt       i;
6878   PetscErrorCode ierr;
6879 
6880   PetscFunctionBegin;
6881   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6882   PetscValidType(mat,1);
6883   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6884   if (n) {
6885     PetscValidPointer(is,3);
6886     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6887   }
6888   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6889   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6890   MatCheckPreallocated(mat,1);
6891   if (!ov) PetscFunctionReturn(0);
6892   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6893   for(i=0; i<n; i++){
6894 	ierr =  MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr);
6895   }
6896   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6897   PetscFunctionReturn(0);
6898 }
6899 
6900 
6901 
6902 
6903 #undef __FUNCT__
6904 #define __FUNCT__ "MatGetBlockSize"
6905 /*@
6906    MatGetBlockSize - Returns the matrix block size.
6907 
6908    Not Collective
6909 
6910    Input Parameter:
6911 .  mat - the matrix
6912 
6913    Output Parameter:
6914 .  bs - block size
6915 
6916    Notes:
6917     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6918 
6919    If the block size has not been set yet this routine returns 1.
6920 
6921    Level: intermediate
6922 
6923    Concepts: matrices^block size
6924 
6925 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6926 @*/
6927 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6928 {
6929   PetscFunctionBegin;
6930   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6931   PetscValidIntPointer(bs,2);
6932   *bs = PetscAbs(mat->rmap->bs);
6933   PetscFunctionReturn(0);
6934 }
6935 
6936 #undef __FUNCT__
6937 #define __FUNCT__ "MatGetBlockSizes"
6938 /*@
6939    MatGetBlockSizes - Returns the matrix block row and column sizes.
6940 
6941    Not Collective
6942 
6943    Input Parameter:
6944 .  mat - the matrix
6945 
6946    Output Parameter:
6947 .  rbs - row block size
6948 .  cbs - coumn block size
6949 
6950    Notes:
6951     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6952     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
6953 
6954    If a block size has not been set yet this routine returns 1.
6955 
6956    Level: intermediate
6957 
6958    Concepts: matrices^block size
6959 
6960 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
6961 @*/
6962 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6963 {
6964   PetscFunctionBegin;
6965   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6966   if (rbs) PetscValidIntPointer(rbs,2);
6967   if (cbs) PetscValidIntPointer(cbs,3);
6968   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6969   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6970   PetscFunctionReturn(0);
6971 }
6972 
6973 #undef __FUNCT__
6974 #define __FUNCT__ "MatSetBlockSize"
6975 /*@
6976    MatSetBlockSize - Sets the matrix block size.
6977 
6978    Logically Collective on Mat
6979 
6980    Input Parameters:
6981 +  mat - the matrix
6982 -  bs - block size
6983 
6984    Notes:
6985     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6986 
6987      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6988 
6989    Level: intermediate
6990 
6991    Concepts: matrices^block size
6992 
6993 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
6994 @*/
6995 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6996 {
6997   PetscErrorCode ierr;
6998 
6999   PetscFunctionBegin;
7000   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7001   PetscValidLogicalCollectiveInt(mat,bs,2);
7002   ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
7003   ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
7004   PetscFunctionReturn(0);
7005 }
7006 
7007 #undef __FUNCT__
7008 #define __FUNCT__ "MatSetBlockSizes"
7009 /*@
7010    MatSetBlockSizes - Sets the matrix block row and column sizes.
7011 
7012    Logically Collective on Mat
7013 
7014    Input Parameters:
7015 +  mat - the matrix
7016 -  rbs - row block size
7017 -  cbs - column block size
7018 
7019    Notes:
7020     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7021     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7022 
7023     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7024 
7025     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7026 
7027    Level: intermediate
7028 
7029    Concepts: matrices^block size
7030 
7031 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7032 @*/
7033 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7034 {
7035   PetscErrorCode ierr;
7036 
7037   PetscFunctionBegin;
7038   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7039   PetscValidLogicalCollectiveInt(mat,rbs,2);
7040   PetscValidLogicalCollectiveInt(mat,cbs,3);
7041   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
7042   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
7043   PetscFunctionReturn(0);
7044 }
7045 
7046 #undef __FUNCT__
7047 #define __FUNCT__ "MatSetBlockSizesFromMats"
7048 /*@
7049    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7050 
7051    Logically Collective on Mat
7052 
7053    Input Parameters:
7054 +  mat - the matrix
7055 .  fromRow - matrix from which to copy row block size
7056 -  fromCol - matrix from which to copy column block size (can be same as fromRow)
7057 
7058    Level: developer
7059 
7060    Concepts: matrices^block size
7061 
7062 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7063 @*/
7064 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7065 {
7066   PetscErrorCode ierr;
7067 
7068   PetscFunctionBegin;
7069   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7070   PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2);
7071   PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3);
7072   if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);}
7073   if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);}
7074   PetscFunctionReturn(0);
7075 }
7076 
7077 #undef __FUNCT__
7078 #define __FUNCT__ "MatResidual"
7079 /*@
7080    MatResidual - Default routine to calculate the residual.
7081 
7082    Collective on Mat and Vec
7083 
7084    Input Parameters:
7085 +  mat - the matrix
7086 .  b   - the right-hand-side
7087 -  x   - the approximate solution
7088 
7089    Output Parameter:
7090 .  r - location to store the residual
7091 
7092    Level: developer
7093 
7094 .keywords: MG, default, multigrid, residual
7095 
7096 .seealso: PCMGSetResidual()
7097 @*/
7098 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7099 {
7100   PetscErrorCode ierr;
7101 
7102   PetscFunctionBegin;
7103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7104   PetscValidHeaderSpecific(b,VEC_CLASSID,2);
7105   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
7106   PetscValidHeaderSpecific(r,VEC_CLASSID,4);
7107   PetscValidType(mat,1);
7108   MatCheckPreallocated(mat,1);
7109   ierr  = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7110   if (!mat->ops->residual) {
7111     ierr = MatMult(mat,x,r);CHKERRQ(ierr);
7112     ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
7113   } else {
7114     ierr  = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr);
7115   }
7116   ierr  = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr);
7117   PetscFunctionReturn(0);
7118 }
7119 
7120 #undef __FUNCT__
7121 #define __FUNCT__ "MatGetRowIJ"
7122 /*@C
7123     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7124 
7125    Collective on Mat
7126 
7127     Input Parameters:
7128 +   mat - the matrix
7129 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
7130 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
7131 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
7132                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7133                  always used.
7134 
7135     Output Parameters:
7136 +   n - number of rows in the (possibly compressed) matrix
7137 .   ia - the row pointers [of length n+1]
7138 .   ja - the column indices
7139 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7140            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7141 
7142     Level: developer
7143 
7144     Notes: You CANNOT change any of the ia[] or ja[] values.
7145 
7146            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7147 
7148     Fortran Node
7149 
7150            In Fortran use
7151 $           PetscInt ia(1), ja(1)
7152 $           PetscOffset iia, jja
7153 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7154 $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7155 $
7156 $          or
7157 $
7158 $           PetscInt, pointer :: ia(:),ja(:)
7159 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7160 $      Acess the ith and jth entries via ia(i) and ja(j)
7161 
7162 
7163 
7164 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7165 @*/
7166 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7167 {
7168   PetscErrorCode ierr;
7169 
7170   PetscFunctionBegin;
7171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7172   PetscValidType(mat,1);
7173   PetscValidIntPointer(n,4);
7174   if (ia) PetscValidIntPointer(ia,5);
7175   if (ja) PetscValidIntPointer(ja,6);
7176   PetscValidIntPointer(done,7);
7177   MatCheckPreallocated(mat,1);
7178   if (!mat->ops->getrowij) *done = PETSC_FALSE;
7179   else {
7180     *done = PETSC_TRUE;
7181     ierr  = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7182     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7183     ierr  = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
7184   }
7185   PetscFunctionReturn(0);
7186 }
7187 
7188 #undef __FUNCT__
7189 #define __FUNCT__ "MatGetColumnIJ"
7190 /*@C
7191     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7192 
7193     Collective on Mat
7194 
7195     Input Parameters:
7196 +   mat - the matrix
7197 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7198 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7199                 symmetrized
7200 .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7201                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7202                  always used.
7203 .   n - number of columns in the (possibly compressed) matrix
7204 .   ia - the column pointers
7205 -   ja - the row indices
7206 
7207     Output Parameters:
7208 .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7209 
7210     Note:
7211     This routine zeros out n, ia, and ja. This is to prevent accidental
7212     us of the array after it has been restored. If you pass NULL, it will
7213     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.
7214 
7215     Level: developer
7216 
7217 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7218 @*/
7219 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7220 {
7221   PetscErrorCode ierr;
7222 
7223   PetscFunctionBegin;
7224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7225   PetscValidType(mat,1);
7226   PetscValidIntPointer(n,4);
7227   if (ia) PetscValidIntPointer(ia,5);
7228   if (ja) PetscValidIntPointer(ja,6);
7229   PetscValidIntPointer(done,7);
7230   MatCheckPreallocated(mat,1);
7231   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7232   else {
7233     *done = PETSC_TRUE;
7234     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7235   }
7236   PetscFunctionReturn(0);
7237 }
7238 
7239 #undef __FUNCT__
7240 #define __FUNCT__ "MatRestoreRowIJ"
7241 /*@C
7242     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7243     MatGetRowIJ().
7244 
7245     Collective on Mat
7246 
7247     Input Parameters:
7248 +   mat - the matrix
7249 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7250 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7251                 symmetrized
7252 .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7253                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7254                  always used.
7255 .   n - size of (possibly compressed) matrix
7256 .   ia - the row pointers
7257 -   ja - the column indices
7258 
7259     Output Parameters:
7260 .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7261 
7262     Note:
7263     This routine zeros out n, ia, and ja. This is to prevent accidental
7264     us of the array after it has been restored. If you pass NULL, it will
7265     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.
7266 
7267     Level: developer
7268 
7269 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7270 @*/
7271 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7272 {
7273   PetscErrorCode ierr;
7274 
7275   PetscFunctionBegin;
7276   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7277   PetscValidType(mat,1);
7278   if (ia) PetscValidIntPointer(ia,5);
7279   if (ja) PetscValidIntPointer(ja,6);
7280   PetscValidIntPointer(done,7);
7281   MatCheckPreallocated(mat,1);
7282 
7283   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7284   else {
7285     *done = PETSC_TRUE;
7286     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7287     if (n)  *n = 0;
7288     if (ia) *ia = NULL;
7289     if (ja) *ja = NULL;
7290   }
7291   PetscFunctionReturn(0);
7292 }
7293 
7294 #undef __FUNCT__
7295 #define __FUNCT__ "MatRestoreColumnIJ"
7296 /*@C
7297     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7298     MatGetColumnIJ().
7299 
7300     Collective on Mat
7301 
7302     Input Parameters:
7303 +   mat - the matrix
7304 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
7305 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7306                 symmetrized
7307 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7308                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7309                  always used.
7310 
7311     Output Parameters:
7312 +   n - size of (possibly compressed) matrix
7313 .   ia - the column pointers
7314 .   ja - the row indices
7315 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7316 
7317     Level: developer
7318 
7319 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7320 @*/
7321 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
7322 {
7323   PetscErrorCode ierr;
7324 
7325   PetscFunctionBegin;
7326   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7327   PetscValidType(mat,1);
7328   if (ia) PetscValidIntPointer(ia,5);
7329   if (ja) PetscValidIntPointer(ja,6);
7330   PetscValidIntPointer(done,7);
7331   MatCheckPreallocated(mat,1);
7332 
7333   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7334   else {
7335     *done = PETSC_TRUE;
7336     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
7337     if (n)  *n = 0;
7338     if (ia) *ia = NULL;
7339     if (ja) *ja = NULL;
7340   }
7341   PetscFunctionReturn(0);
7342 }
7343 
7344 #undef __FUNCT__
7345 #define __FUNCT__ "MatColoringPatch"
7346 /*@C
7347     MatColoringPatch -Used inside matrix coloring routines that
7348     use MatGetRowIJ() and/or MatGetColumnIJ().
7349 
7350     Collective on Mat
7351 
7352     Input Parameters:
7353 +   mat - the matrix
7354 .   ncolors - max color value
7355 .   n   - number of entries in colorarray
7356 -   colorarray - array indicating color for each column
7357 
7358     Output Parameters:
7359 .   iscoloring - coloring generated using colorarray information
7360 
7361     Level: developer
7362 
7363 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7364 
7365 @*/
7366 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7367 {
7368   PetscErrorCode ierr;
7369 
7370   PetscFunctionBegin;
7371   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7372   PetscValidType(mat,1);
7373   PetscValidIntPointer(colorarray,4);
7374   PetscValidPointer(iscoloring,5);
7375   MatCheckPreallocated(mat,1);
7376 
7377   if (!mat->ops->coloringpatch) {
7378     ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr);
7379   } else {
7380     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7381   }
7382   PetscFunctionReturn(0);
7383 }
7384 
7385 
7386 #undef __FUNCT__
7387 #define __FUNCT__ "MatSetUnfactored"
7388 /*@
7389    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7390 
7391    Logically Collective on Mat
7392 
7393    Input Parameter:
7394 .  mat - the factored matrix to be reset
7395 
7396    Notes:
7397    This routine should be used only with factored matrices formed by in-place
7398    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7399    format).  This option can save memory, for example, when solving nonlinear
7400    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7401    ILU(0) preconditioner.
7402 
7403    Note that one can specify in-place ILU(0) factorization by calling
7404 .vb
7405      PCType(pc,PCILU);
7406      PCFactorSeUseInPlace(pc);
7407 .ve
7408    or by using the options -pc_type ilu -pc_factor_in_place
7409 
7410    In-place factorization ILU(0) can also be used as a local
7411    solver for the blocks within the block Jacobi or additive Schwarz
7412    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
7413    for details on setting local solver options.
7414 
7415    Most users should employ the simplified KSP interface for linear solvers
7416    instead of working directly with matrix algebra routines such as this.
7417    See, e.g., KSPCreate().
7418 
7419    Level: developer
7420 
7421 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7422 
7423    Concepts: matrices^unfactored
7424 
7425 @*/
7426 PetscErrorCode MatSetUnfactored(Mat mat)
7427 {
7428   PetscErrorCode ierr;
7429 
7430   PetscFunctionBegin;
7431   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7432   PetscValidType(mat,1);
7433   MatCheckPreallocated(mat,1);
7434   mat->factortype = MAT_FACTOR_NONE;
7435   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7436   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7437   PetscFunctionReturn(0);
7438 }
7439 
7440 /*MC
7441     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7442 
7443     Synopsis:
7444     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7445 
7446     Not collective
7447 
7448     Input Parameter:
7449 .   x - matrix
7450 
7451     Output Parameters:
7452 +   xx_v - the Fortran90 pointer to the array
7453 -   ierr - error code
7454 
7455     Example of Usage:
7456 .vb
7457       PetscScalar, pointer xx_v(:,:)
7458       ....
7459       call MatDenseGetArrayF90(x,xx_v,ierr)
7460       a = xx_v(3)
7461       call MatDenseRestoreArrayF90(x,xx_v,ierr)
7462 .ve
7463 
7464     Level: advanced
7465 
7466 .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7467 
7468     Concepts: matrices^accessing array
7469 
7470 M*/
7471 
7472 /*MC
7473     MatDenseRestoreArrayF90 - Restores a matrix array that has been
7474     accessed with MatDenseGetArrayF90().
7475 
7476     Synopsis:
7477     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7478 
7479     Not collective
7480 
7481     Input Parameters:
7482 +   x - matrix
7483 -   xx_v - the Fortran90 pointer to the array
7484 
7485     Output Parameter:
7486 .   ierr - error code
7487 
7488     Example of Usage:
7489 .vb
7490        PetscScalar, pointer xx_v(:,:)
7491        ....
7492        call MatDenseGetArrayF90(x,xx_v,ierr)
7493        a = xx_v(3)
7494        call MatDenseRestoreArrayF90(x,xx_v,ierr)
7495 .ve
7496 
7497     Level: advanced
7498 
7499 .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7500 
7501 M*/
7502 
7503 
7504 /*MC
7505     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7506 
7507     Synopsis:
7508     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7509 
7510     Not collective
7511 
7512     Input Parameter:
7513 .   x - matrix
7514 
7515     Output Parameters:
7516 +   xx_v - the Fortran90 pointer to the array
7517 -   ierr - error code
7518 
7519     Example of Usage:
7520 .vb
7521       PetscScalar, pointer xx_v(:)
7522       ....
7523       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7524       a = xx_v(3)
7525       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7526 .ve
7527 
7528     Level: advanced
7529 
7530 .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7531 
7532     Concepts: matrices^accessing array
7533 
7534 M*/
7535 
7536 /*MC
7537     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7538     accessed with MatSeqAIJGetArrayF90().
7539 
7540     Synopsis:
7541     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7542 
7543     Not collective
7544 
7545     Input Parameters:
7546 +   x - matrix
7547 -   xx_v - the Fortran90 pointer to the array
7548 
7549     Output Parameter:
7550 .   ierr - error code
7551 
7552     Example of Usage:
7553 .vb
7554        PetscScalar, pointer xx_v(:)
7555        ....
7556        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7557        a = xx_v(3)
7558        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7559 .ve
7560 
7561     Level: advanced
7562 
7563 .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7564 
7565 M*/
7566 
7567 
7568 #undef __FUNCT__
7569 #define __FUNCT__ "MatGetSubMatrix"
7570 /*@
7571     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7572                       as the original matrix.
7573 
7574     Collective on Mat
7575 
7576     Input Parameters:
7577 +   mat - the original matrix
7578 .   isrow - parallel IS containing the rows this processor should obtain
7579 .   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.
7580 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7581 
7582     Output Parameter:
7583 .   newmat - the new submatrix, of the same type as the old
7584 
7585     Level: advanced
7586 
7587     Notes:
7588     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7589 
7590     Some matrix types place restrictions on the row and column indices, such
7591     as that they be sorted or that they be equal to each other.
7592 
7593     The index sets may not have duplicate entries.
7594 
7595       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7596    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7597    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7598    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7599    you are finished using it.
7600 
7601     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7602     the input matrix.
7603 
7604     If iscol is NULL then all columns are obtained (not supported in Fortran).
7605 
7606    Example usage:
7607    Consider the following 8x8 matrix with 34 non-zero values, that is
7608    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7609    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7610    as follows:
7611 
7612 .vb
7613             1  2  0  |  0  3  0  |  0  4
7614     Proc0   0  5  6  |  7  0  0  |  8  0
7615             9  0 10  | 11  0  0  | 12  0
7616     -------------------------------------
7617            13  0 14  | 15 16 17  |  0  0
7618     Proc1   0 18  0  | 19 20 21  |  0  0
7619             0  0  0  | 22 23  0  | 24  0
7620     -------------------------------------
7621     Proc2  25 26 27  |  0  0 28  | 29  0
7622            30  0  0  | 31 32 33  |  0 34
7623 .ve
7624 
7625     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7626 
7627 .vb
7628             2  0  |  0  3  0  |  0
7629     Proc0   5  6  |  7  0  0  |  8
7630     -------------------------------
7631     Proc1  18  0  | 19 20 21  |  0
7632     -------------------------------
7633     Proc2  26 27  |  0  0 28  | 29
7634             0  0  | 31 32 33  |  0
7635 .ve
7636 
7637 
7638     Concepts: matrices^submatrices
7639 
7640 .seealso: MatGetSubMatrices()
7641 @*/
7642 PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7643 {
7644   PetscErrorCode ierr;
7645   PetscMPIInt    size;
7646   Mat            *local;
7647   IS             iscoltmp;
7648 
7649   PetscFunctionBegin;
7650   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7651   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7652   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7653   PetscValidPointer(newmat,5);
7654   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7655   PetscValidType(mat,1);
7656   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7657   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7658 
7659   MatCheckPreallocated(mat,1);
7660   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
7661 
7662   if (!iscol || isrow == iscol) {
7663     PetscBool   stride;
7664     PetscMPIInt grabentirematrix = 0,grab;
7665     ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr);
7666     if (stride) {
7667       PetscInt first,step,n,rstart,rend;
7668       ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr);
7669       if (step == 1) {
7670         ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
7671         if (rstart == first) {
7672           ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr);
7673           if (n == rend-rstart) {
7674             grabentirematrix = 1;
7675           }
7676         }
7677       }
7678     }
7679     ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr);
7680     if (grab) {
7681       ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr);
7682       if (cll == MAT_INITIAL_MATRIX) {
7683         *newmat = mat;
7684         ierr    = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
7685       }
7686       PetscFunctionReturn(0);
7687     }
7688   }
7689 
7690   if (!iscol) {
7691     ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7692   } else {
7693     iscoltmp = iscol;
7694   }
7695 
7696   /* if original matrix is on just one processor then use submatrix generated */
7697   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7698     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7699     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7700     PetscFunctionReturn(0);
7701   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7702     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7703     *newmat = *local;
7704     ierr    = PetscFree(local);CHKERRQ(ierr);
7705     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7706     PetscFunctionReturn(0);
7707   } else if (!mat->ops->getsubmatrix) {
7708     /* Create a new matrix type that implements the operation using the full matrix */
7709     ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7710     switch (cll) {
7711     case MAT_INITIAL_MATRIX:
7712       ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7713       break;
7714     case MAT_REUSE_MATRIX:
7715       ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7716       break;
7717     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7718     }
7719     ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7720     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7721     PetscFunctionReturn(0);
7722   }
7723 
7724   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7725   ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7726   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7727   ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr);
7728   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7729   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7730   PetscFunctionReturn(0);
7731 }
7732 
7733 #undef __FUNCT__
7734 #define __FUNCT__ "MatStashSetInitialSize"
7735 /*@
7736    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7737    used during the assembly process to store values that belong to
7738    other processors.
7739 
7740    Not Collective
7741 
7742    Input Parameters:
7743 +  mat   - the matrix
7744 .  size  - the initial size of the stash.
7745 -  bsize - the initial size of the block-stash(if used).
7746 
7747    Options Database Keys:
7748 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7749 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7750 
7751    Level: intermediate
7752 
7753    Notes:
7754      The block-stash is used for values set with MatSetValuesBlocked() while
7755      the stash is used for values set with MatSetValues()
7756 
7757      Run with the option -info and look for output of the form
7758      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7759      to determine the appropriate value, MM, to use for size and
7760      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7761      to determine the value, BMM to use for bsize
7762 
7763    Concepts: stash^setting matrix size
7764    Concepts: matrices^stash
7765 
7766 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7767 
7768 @*/
7769 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7770 {
7771   PetscErrorCode ierr;
7772 
7773   PetscFunctionBegin;
7774   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7775   PetscValidType(mat,1);
7776   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7777   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7778   PetscFunctionReturn(0);
7779 }
7780 
7781 #undef __FUNCT__
7782 #define __FUNCT__ "MatInterpolateAdd"
7783 /*@
7784    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7785      the matrix
7786 
7787    Neighbor-wise Collective on Mat
7788 
7789    Input Parameters:
7790 +  mat   - the matrix
7791 .  x,y - the vectors
7792 -  w - where the result is stored
7793 
7794    Level: intermediate
7795 
7796    Notes:
7797     w may be the same vector as y.
7798 
7799     This allows one to use either the restriction or interpolation (its transpose)
7800     matrix to do the interpolation
7801 
7802     Concepts: interpolation
7803 
7804 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7805 
7806 @*/
7807 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7808 {
7809   PetscErrorCode ierr;
7810   PetscInt       M,N,Ny;
7811 
7812   PetscFunctionBegin;
7813   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7814   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7815   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7816   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7817   PetscValidType(A,1);
7818   MatCheckPreallocated(A,1);
7819   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7820   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7821   if (M == Ny) {
7822     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7823   } else {
7824     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7825   }
7826   PetscFunctionReturn(0);
7827 }
7828 
7829 #undef __FUNCT__
7830 #define __FUNCT__ "MatInterpolate"
7831 /*@
7832    MatInterpolate - y = A*x or A'*x depending on the shape of
7833      the matrix
7834 
7835    Neighbor-wise Collective on Mat
7836 
7837    Input Parameters:
7838 +  mat   - the matrix
7839 -  x,y - the vectors
7840 
7841    Level: intermediate
7842 
7843    Notes:
7844     This allows one to use either the restriction or interpolation (its transpose)
7845     matrix to do the interpolation
7846 
7847    Concepts: matrices^interpolation
7848 
7849 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7850 
7851 @*/
7852 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7853 {
7854   PetscErrorCode ierr;
7855   PetscInt       M,N,Ny;
7856 
7857   PetscFunctionBegin;
7858   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7859   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7860   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7861   PetscValidType(A,1);
7862   MatCheckPreallocated(A,1);
7863   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7864   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7865   if (M == Ny) {
7866     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7867   } else {
7868     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7869   }
7870   PetscFunctionReturn(0);
7871 }
7872 
7873 #undef __FUNCT__
7874 #define __FUNCT__ "MatRestrict"
7875 /*@
7876    MatRestrict - y = A*x or A'*x
7877 
7878    Neighbor-wise Collective on Mat
7879 
7880    Input Parameters:
7881 +  mat   - the matrix
7882 -  x,y - the vectors
7883 
7884    Level: intermediate
7885 
7886    Notes:
7887     This allows one to use either the restriction or interpolation (its transpose)
7888     matrix to do the restriction
7889 
7890    Concepts: matrices^restriction
7891 
7892 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7893 
7894 @*/
7895 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7896 {
7897   PetscErrorCode ierr;
7898   PetscInt       M,N,Ny;
7899 
7900   PetscFunctionBegin;
7901   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7902   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7903   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7904   PetscValidType(A,1);
7905   MatCheckPreallocated(A,1);
7906 
7907   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7908   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7909   if (M == Ny) {
7910     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7911   } else {
7912     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7913   }
7914   PetscFunctionReturn(0);
7915 }
7916 
7917 #undef __FUNCT__
7918 #define __FUNCT__ "MatGetNullSpace"
7919 /*@
7920    MatGetNullSpace - retrieves the null space to a matrix.
7921 
7922    Logically Collective on Mat and MatNullSpace
7923 
7924    Input Parameters:
7925 +  mat - the matrix
7926 -  nullsp - the null space object
7927 
7928    Level: developer
7929 
7930    Concepts: null space^attaching to matrix
7931 
7932 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
7933 @*/
7934 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7935 {
7936   PetscFunctionBegin;
7937   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7938   PetscValidType(mat,1);
7939   PetscValidPointer(nullsp,2);
7940   *nullsp = mat->nullsp;
7941   PetscFunctionReturn(0);
7942 }
7943 
7944 #undef __FUNCT__
7945 #define __FUNCT__ "MatSetNullSpace"
7946 /*@
7947    MatSetNullSpace - attaches a null space to a matrix.
7948 
7949    Logically Collective on Mat and MatNullSpace
7950 
7951    Input Parameters:
7952 +  mat - the matrix
7953 -  nullsp - the null space object
7954 
7955    Level: advanced
7956 
7957    Notes:
7958       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
7959 
7960       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
7961       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
7962 
7963       You can remove the null space by calling this routine with an nullsp of NULL
7964 
7965 
7966       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
7967    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).
7968    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
7969    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
7970    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).
7971 
7972       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
7973 
7974    Concepts: null space^attaching to matrix
7975 
7976 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
7977 @*/
7978 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7979 {
7980   PetscErrorCode ierr;
7981 
7982   PetscFunctionBegin;
7983   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7984   PetscValidType(mat,1);
7985   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7986   MatCheckPreallocated(mat,1);
7987   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
7988   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
7989   mat->nullsp = nullsp;
7990   PetscFunctionReturn(0);
7991 }
7992 
7993 #undef __FUNCT__
7994 #define __FUNCT__ "MatGetTransposeNullSpace"
7995 /*@
7996    MatGetTransposeNullSpace - retrieves the null space to a matrix.
7997 
7998    Logically Collective on Mat and MatNullSpace
7999 
8000    Input Parameters:
8001 +  mat - the matrix
8002 -  nullsp - the null space object
8003 
8004    Level: developer
8005 
8006    Notes:
8007       This null space is used by solvers. Overwrites any previous null space that may have been attached
8008 
8009    Concepts: null space^attaching to matrix
8010 
8011 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
8012 @*/
8013 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8014 {
8015   PetscFunctionBegin;
8016   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8017   PetscValidType(mat,1);
8018   PetscValidPointer(nullsp,2);
8019   *nullsp = mat->transnullsp;
8020   PetscFunctionReturn(0);
8021 }
8022 
8023 #undef __FUNCT__
8024 #define __FUNCT__ "MatSetTransposeNullSpace"
8025 /*@
8026    MatSetTransposeNullSpace - attaches a null space to a matrix.
8027 
8028    Logically Collective on Mat and MatNullSpace
8029 
8030    Input Parameters:
8031 +  mat - the matrix
8032 -  nullsp - the null space object
8033 
8034    Level: advanced
8035 
8036    Notes:
8037       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.
8038       You must also call MatSetNullSpace()
8039 
8040 
8041       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8042    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).
8043    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
8044    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
8045    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).
8046 
8047       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8048 
8049    Concepts: null space^attaching to matrix
8050 
8051 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetNullSpace(), MatNullSpaceRemove()
8052 @*/
8053 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8054 {
8055   PetscErrorCode ierr;
8056 
8057   PetscFunctionBegin;
8058   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8059   PetscValidType(mat,1);
8060   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8061   MatCheckPreallocated(mat,1);
8062   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
8063   ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr);
8064   mat->transnullsp = nullsp;
8065   PetscFunctionReturn(0);
8066 }
8067 
8068 #undef __FUNCT__
8069 #define __FUNCT__ "MatSetNearNullSpace"
8070 /*@
8071    MatSetNearNullSpace - attaches a null space to a matrix.
8072         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8073 
8074    Logically Collective on Mat and MatNullSpace
8075 
8076    Input Parameters:
8077 +  mat - the matrix
8078 -  nullsp - the null space object
8079 
8080    Level: advanced
8081 
8082    Notes:
8083       Overwrites any previous near null space that may have been attached
8084 
8085       You can remove the null space by calling this routine with an nullsp of NULL
8086 
8087    Concepts: null space^attaching to matrix
8088 
8089 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
8090 @*/
8091 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8092 {
8093   PetscErrorCode ierr;
8094 
8095   PetscFunctionBegin;
8096   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8097   PetscValidType(mat,1);
8098   if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
8099   MatCheckPreallocated(mat,1);
8100   if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);}
8101   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
8102   mat->nearnullsp = nullsp;
8103   PetscFunctionReturn(0);
8104 }
8105 
8106 #undef __FUNCT__
8107 #define __FUNCT__ "MatGetNearNullSpace"
8108 /*@
8109    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8110 
8111    Not Collective
8112 
8113    Input Parameters:
8114 .  mat - the matrix
8115 
8116    Output Parameters:
8117 .  nullsp - the null space object, NULL if not set
8118 
8119    Level: developer
8120 
8121    Concepts: null space^attaching to matrix
8122 
8123 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
8124 @*/
8125 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8126 {
8127   PetscFunctionBegin;
8128   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8129   PetscValidType(mat,1);
8130   PetscValidPointer(nullsp,2);
8131   MatCheckPreallocated(mat,1);
8132   *nullsp = mat->nearnullsp;
8133   PetscFunctionReturn(0);
8134 }
8135 
8136 #undef __FUNCT__
8137 #define __FUNCT__ "MatICCFactor"
8138 /*@C
8139    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8140 
8141    Collective on Mat
8142 
8143    Input Parameters:
8144 +  mat - the matrix
8145 .  row - row/column permutation
8146 .  fill - expected fill factor >= 1.0
8147 -  level - level of fill, for ICC(k)
8148 
8149    Notes:
8150    Probably really in-place only when level of fill is zero, otherwise allocates
8151    new space to store factored matrix and deletes previous memory.
8152 
8153    Most users should employ the simplified KSP interface for linear solvers
8154    instead of working directly with matrix algebra routines such as this.
8155    See, e.g., KSPCreate().
8156 
8157    Level: developer
8158 
8159    Concepts: matrices^incomplete Cholesky factorization
8160    Concepts: Cholesky factorization
8161 
8162 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8163 
8164     Developer Note: fortran interface is not autogenerated as the f90
8165     interface defintion cannot be generated correctly [due to MatFactorInfo]
8166 
8167 @*/
8168 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8169 {
8170   PetscErrorCode ierr;
8171 
8172   PetscFunctionBegin;
8173   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8174   PetscValidType(mat,1);
8175   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
8176   PetscValidPointer(info,3);
8177   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8178   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8179   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8180   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8181   MatCheckPreallocated(mat,1);
8182   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
8183   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8184   PetscFunctionReturn(0);
8185 }
8186 
8187 #undef __FUNCT__
8188 #define __FUNCT__ "MatSetValuesAdifor"
8189 /*@
8190    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
8191 
8192    Not Collective
8193 
8194    Input Parameters:
8195 +  mat - the matrix
8196 .  nl - leading dimension of v
8197 -  v - the values compute with ADIFOR
8198 
8199    Level: developer
8200 
8201    Notes:
8202      Must call MatSetColoring() before using this routine. Also this matrix must already
8203      have its nonzero pattern determined.
8204 
8205 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8206           MatSetValues(), MatSetColoring()
8207 @*/
8208 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8209 {
8210   PetscErrorCode ierr;
8211 
8212   PetscFunctionBegin;
8213   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8214   PetscValidType(mat,1);
8215   PetscValidPointer(v,3);
8216 
8217   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8218   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
8219   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8220   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
8221   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
8222   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8223   PetscFunctionReturn(0);
8224 }
8225 
8226 #undef __FUNCT__
8227 #define __FUNCT__ "MatDiagonalScaleLocal"
8228 /*@
8229    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8230          ghosted ones.
8231 
8232    Not Collective
8233 
8234    Input Parameters:
8235 +  mat - the matrix
8236 -  diag = the diagonal values, including ghost ones
8237 
8238    Level: developer
8239 
8240    Notes: Works only for MPIAIJ and MPIBAIJ matrices
8241 
8242 .seealso: MatDiagonalScale()
8243 @*/
8244 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8245 {
8246   PetscErrorCode ierr;
8247   PetscMPIInt    size;
8248 
8249   PetscFunctionBegin;
8250   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8251   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
8252   PetscValidType(mat,1);
8253 
8254   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8255   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8256   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
8257   if (size == 1) {
8258     PetscInt n,m;
8259     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
8260     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
8261     if (m == n) {
8262       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
8263     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8264   } else {
8265     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
8266   }
8267   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
8268   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
8269   PetscFunctionReturn(0);
8270 }
8271 
8272 #undef __FUNCT__
8273 #define __FUNCT__ "MatGetInertia"
8274 /*@
8275    MatGetInertia - Gets the inertia from a factored matrix
8276 
8277    Collective on Mat
8278 
8279    Input Parameter:
8280 .  mat - the matrix
8281 
8282    Output Parameters:
8283 +   nneg - number of negative eigenvalues
8284 .   nzero - number of zero eigenvalues
8285 -   npos - number of positive eigenvalues
8286 
8287    Level: advanced
8288 
8289    Notes: Matrix must have been factored by MatCholeskyFactor()
8290 
8291 
8292 @*/
8293 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8294 {
8295   PetscErrorCode ierr;
8296 
8297   PetscFunctionBegin;
8298   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8299   PetscValidType(mat,1);
8300   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8301   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8302   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8303   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
8304   PetscFunctionReturn(0);
8305 }
8306 
8307 /* ----------------------------------------------------------------*/
8308 #undef __FUNCT__
8309 #define __FUNCT__ "MatSolves"
8310 /*@C
8311    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8312 
8313    Neighbor-wise Collective on Mat and Vecs
8314 
8315    Input Parameters:
8316 +  mat - the factored matrix
8317 -  b - the right-hand-side vectors
8318 
8319    Output Parameter:
8320 .  x - the result vectors
8321 
8322    Notes:
8323    The vectors b and x cannot be the same.  I.e., one cannot
8324    call MatSolves(A,x,x).
8325 
8326    Notes:
8327    Most users should employ the simplified KSP interface for linear solvers
8328    instead of working directly with matrix algebra routines such as this.
8329    See, e.g., KSPCreate().
8330 
8331    Level: developer
8332 
8333    Concepts: matrices^triangular solves
8334 
8335 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8336 @*/
8337 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8338 {
8339   PetscErrorCode ierr;
8340 
8341   PetscFunctionBegin;
8342   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8343   PetscValidType(mat,1);
8344   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8345   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8346   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
8347 
8348   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8349   MatCheckPreallocated(mat,1);
8350   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8351   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
8352   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
8353   PetscFunctionReturn(0);
8354 }
8355 
8356 #undef __FUNCT__
8357 #define __FUNCT__ "MatIsSymmetric"
8358 /*@
8359    MatIsSymmetric - Test whether a matrix is symmetric
8360 
8361    Collective on Mat
8362 
8363    Input Parameter:
8364 +  A - the matrix to test
8365 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8366 
8367    Output Parameters:
8368 .  flg - the result
8369 
8370    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8371 
8372    Level: intermediate
8373 
8374    Concepts: matrix^symmetry
8375 
8376 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8377 @*/
8378 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
8379 {
8380   PetscErrorCode ierr;
8381 
8382   PetscFunctionBegin;
8383   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8384   PetscValidPointer(flg,2);
8385 
8386   if (!A->symmetric_set) {
8387     if (!A->ops->issymmetric) {
8388       MatType mattype;
8389       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8390       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8391     }
8392     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
8393     if (!tol) {
8394       A->symmetric_set = PETSC_TRUE;
8395       A->symmetric     = *flg;
8396       if (A->symmetric) {
8397         A->structurally_symmetric_set = PETSC_TRUE;
8398         A->structurally_symmetric     = PETSC_TRUE;
8399       }
8400     }
8401   } else if (A->symmetric) {
8402     *flg = PETSC_TRUE;
8403   } else if (!tol) {
8404     *flg = PETSC_FALSE;
8405   } else {
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   }
8413   PetscFunctionReturn(0);
8414 }
8415 
8416 #undef __FUNCT__
8417 #define __FUNCT__ "MatIsHermitian"
8418 /*@
8419    MatIsHermitian - Test whether a matrix is Hermitian
8420 
8421    Collective on Mat
8422 
8423    Input Parameter:
8424 +  A - the matrix to test
8425 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8426 
8427    Output Parameters:
8428 .  flg - the result
8429 
8430    Level: intermediate
8431 
8432    Concepts: matrix^symmetry
8433 
8434 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8435           MatIsSymmetricKnown(), MatIsSymmetric()
8436 @*/
8437 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
8438 {
8439   PetscErrorCode ierr;
8440 
8441   PetscFunctionBegin;
8442   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8443   PetscValidPointer(flg,2);
8444 
8445   if (!A->hermitian_set) {
8446     if (!A->ops->ishermitian) {
8447       MatType mattype;
8448       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8449       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8450     }
8451     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8452     if (!tol) {
8453       A->hermitian_set = PETSC_TRUE;
8454       A->hermitian     = *flg;
8455       if (A->hermitian) {
8456         A->structurally_symmetric_set = PETSC_TRUE;
8457         A->structurally_symmetric     = PETSC_TRUE;
8458       }
8459     }
8460   } else if (A->hermitian) {
8461     *flg = PETSC_TRUE;
8462   } else if (!tol) {
8463     *flg = PETSC_FALSE;
8464   } else {
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   }
8472   PetscFunctionReturn(0);
8473 }
8474 
8475 #undef __FUNCT__
8476 #define __FUNCT__ "MatIsSymmetricKnown"
8477 /*@
8478    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8479 
8480    Not Collective
8481 
8482    Input Parameter:
8483 .  A - the matrix to check
8484 
8485    Output Parameters:
8486 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8487 -  flg - the result
8488 
8489    Level: advanced
8490 
8491    Concepts: matrix^symmetry
8492 
8493    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8494          if you want it explicitly checked
8495 
8496 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8497 @*/
8498 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8499 {
8500   PetscFunctionBegin;
8501   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8502   PetscValidPointer(set,2);
8503   PetscValidPointer(flg,3);
8504   if (A->symmetric_set) {
8505     *set = PETSC_TRUE;
8506     *flg = A->symmetric;
8507   } else {
8508     *set = PETSC_FALSE;
8509   }
8510   PetscFunctionReturn(0);
8511 }
8512 
8513 #undef __FUNCT__
8514 #define __FUNCT__ "MatIsHermitianKnown"
8515 /*@
8516    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8517 
8518    Not Collective
8519 
8520    Input Parameter:
8521 .  A - the matrix to check
8522 
8523    Output Parameters:
8524 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8525 -  flg - the result
8526 
8527    Level: advanced
8528 
8529    Concepts: matrix^symmetry
8530 
8531    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8532          if you want it explicitly checked
8533 
8534 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8535 @*/
8536 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8537 {
8538   PetscFunctionBegin;
8539   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8540   PetscValidPointer(set,2);
8541   PetscValidPointer(flg,3);
8542   if (A->hermitian_set) {
8543     *set = PETSC_TRUE;
8544     *flg = A->hermitian;
8545   } else {
8546     *set = PETSC_FALSE;
8547   }
8548   PetscFunctionReturn(0);
8549 }
8550 
8551 #undef __FUNCT__
8552 #define __FUNCT__ "MatIsStructurallySymmetric"
8553 /*@
8554    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8555 
8556    Collective on Mat
8557 
8558    Input Parameter:
8559 .  A - the matrix to test
8560 
8561    Output Parameters:
8562 .  flg - the result
8563 
8564    Level: intermediate
8565 
8566    Concepts: matrix^symmetry
8567 
8568 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8569 @*/
8570 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8571 {
8572   PetscErrorCode ierr;
8573 
8574   PetscFunctionBegin;
8575   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8576   PetscValidPointer(flg,2);
8577   if (!A->structurally_symmetric_set) {
8578     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8579     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8580 
8581     A->structurally_symmetric_set = PETSC_TRUE;
8582   }
8583   *flg = A->structurally_symmetric;
8584   PetscFunctionReturn(0);
8585 }
8586 
8587 #undef __FUNCT__
8588 #define __FUNCT__ "MatStashGetInfo"
8589 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8590 /*@
8591    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8592        to be communicated to other processors during the MatAssemblyBegin/End() process
8593 
8594     Not collective
8595 
8596    Input Parameter:
8597 .   vec - the vector
8598 
8599    Output Parameters:
8600 +   nstash   - the size of the stash
8601 .   reallocs - the number of additional mallocs incurred.
8602 .   bnstash   - the size of the block stash
8603 -   breallocs - the number of additional mallocs incurred.in the block stash
8604 
8605    Level: advanced
8606 
8607 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8608 
8609 @*/
8610 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8611 {
8612   PetscErrorCode ierr;
8613 
8614   PetscFunctionBegin;
8615   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8616   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8617   PetscFunctionReturn(0);
8618 }
8619 
8620 #undef __FUNCT__
8621 #define __FUNCT__ "MatCreateVecs"
8622 /*@C
8623    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8624      parallel layout
8625 
8626    Collective on Mat
8627 
8628    Input Parameter:
8629 .  mat - the matrix
8630 
8631    Output Parameter:
8632 +   right - (optional) vector that the matrix can be multiplied against
8633 -   left - (optional) vector that the matrix vector product can be stored in
8634 
8635    Notes:
8636     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().
8637 
8638   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8639 
8640   Level: advanced
8641 
8642 .seealso: MatCreate(), VecDestroy()
8643 @*/
8644 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8645 {
8646   PetscErrorCode ierr;
8647 
8648   PetscFunctionBegin;
8649   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8650   PetscValidType(mat,1);
8651   if (mat->ops->getvecs) {
8652     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8653   } else {
8654     PetscInt rbs,cbs;
8655     ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr);
8656     if (right) {
8657       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8658       ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr);
8659       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8660       ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr);
8661       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8662       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8663     }
8664     if (left) {
8665       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8666       ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr);
8667       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8668       ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr);
8669       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8670       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8671     }
8672   }
8673   PetscFunctionReturn(0);
8674 }
8675 
8676 #undef __FUNCT__
8677 #define __FUNCT__ "MatFactorInfoInitialize"
8678 /*@C
8679    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8680      with default values.
8681 
8682    Not Collective
8683 
8684    Input Parameters:
8685 .    info - the MatFactorInfo data structure
8686 
8687 
8688    Notes: The solvers are generally used through the KSP and PC objects, for example
8689           PCLU, PCILU, PCCHOLESKY, PCICC
8690 
8691    Level: developer
8692 
8693 .seealso: MatFactorInfo
8694 
8695     Developer Note: fortran interface is not autogenerated as the f90
8696     interface defintion cannot be generated correctly [due to MatFactorInfo]
8697 
8698 @*/
8699 
8700 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8701 {
8702   PetscErrorCode ierr;
8703 
8704   PetscFunctionBegin;
8705   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8706   PetscFunctionReturn(0);
8707 }
8708 
8709 #undef __FUNCT__
8710 #define __FUNCT__ "MatFactorSetSchurIS"
8711 /*@
8712    MatFactorSetSchurIS - Set indices corresponding to the Schur complement
8713 
8714    Collective on Mat
8715 
8716    Input Parameters:
8717 +  mat - the factored matrix
8718 -  is - the index set defining the Schur indices (0-based)
8719 
8720    Notes:
8721 
8722    Level: developer
8723 
8724    Concepts:
8725 
8726 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8727 
8728 @*/
8729 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8730 {
8731   PetscErrorCode ierr,(*f)(Mat,IS);
8732 
8733   PetscFunctionBegin;
8734   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8735   PetscValidType(mat,1);
8736   PetscValidHeaderSpecific(is,IS_CLASSID,2);
8737   PetscValidType(is,2);
8738   PetscCheckSameComm(mat,1,is,2);
8739   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8740   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr);
8741   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");
8742   ierr = (*f)(mat,is);CHKERRQ(ierr);
8743   PetscFunctionReturn(0);
8744 }
8745 
8746 #undef __FUNCT__
8747 #define __FUNCT__ "MatFactorCreateSchurComplement"
8748 /*@
8749   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8750 
8751    Logically Collective on Mat
8752 
8753    Input Parameters:
8754 +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8755 .  *S - location where to return the Schur complement (MATDENSE)
8756 
8757    Notes:
8758    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.
8759    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse
8760 
8761    Level: advanced
8762 
8763    References:
8764 
8765 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8766 @*/
8767 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8768 {
8769   PetscErrorCode ierr;
8770 
8771   PetscFunctionBegin;
8772   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8773   ierr = PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr);
8774   PetscFunctionReturn(0);
8775 }
8776 
8777 #undef __FUNCT__
8778 #define __FUNCT__ "MatFactorGetSchurComplement"
8779 /*@
8780   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data
8781 
8782    Logically Collective on Mat
8783 
8784    Input Parameters:
8785 +  F - the factored matrix obtained by calling MatGetFactor()
8786 .  *S - location where to return the Schur complement (in MATDENSE format)
8787 
8788    Notes:
8789    Schur complement mode is currently implemented for sequential matrices.
8790    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.
8791    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.
8792 
8793    Level: advanced
8794 
8795    References:
8796 
8797 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8798 @*/
8799 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8800 {
8801   PetscErrorCode ierr;
8802 
8803   PetscFunctionBegin;
8804   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8805   ierr = PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr);
8806   PetscFunctionReturn(0);
8807 }
8808 
8809 #undef __FUNCT__
8810 #define __FUNCT__ "MatFactorRestoreSchurComplement"
8811 /*@
8812   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8813 
8814    Logically Collective on Mat
8815 
8816    Input Parameters:
8817 +  F - the factored matrix obtained by calling MatGetFactor()
8818 .  *S - location where the Schur complement is stored
8819 
8820    Notes:
8821 
8822    Level: advanced
8823 
8824    References:
8825 
8826 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8827 @*/
8828 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8829 {
8830   PetscErrorCode ierr;
8831 
8832   PetscFunctionBegin;
8833   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8834   PetscValidHeaderSpecific(*S,MAT_CLASSID,1);
8835   ierr = MatDestroy(S);CHKERRQ(ierr);
8836   PetscFunctionReturn(0);
8837 }
8838 
8839 #undef __FUNCT__
8840 #define __FUNCT__ "MatFactorSolveSchurComplementTranspose"
8841 /*@
8842   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8843 
8844    Logically Collective on Mat
8845 
8846    Input Parameters:
8847 +  F - the factored matrix obtained by calling MatGetFactor()
8848 .  rhs - location where the right hand side of the Schur complement system is stored
8849 -  sol - location where the solution of the Schur complement system has to be returned
8850 
8851    Notes:
8852    The sizes of the vectors should match the size of the Schur complement
8853 
8854    Level: advanced
8855 
8856    References:
8857 
8858 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8859 @*/
8860 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8861 {
8862   PetscErrorCode ierr;
8863 
8864   PetscFunctionBegin;
8865   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8866   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8867   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
8868   PetscCheckSameComm(F,1,rhs,2);
8869   PetscCheckSameComm(F,1,sol,3);
8870   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
8871   PetscFunctionReturn(0);
8872 }
8873 
8874 #undef __FUNCT__
8875 #define __FUNCT__ "MatFactorSolveSchurComplement"
8876 /*@
8877   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8878 
8879    Logically Collective on Mat
8880 
8881    Input Parameters:
8882 +  F - the factored matrix obtained by calling MatGetFactor()
8883 .  rhs - location where the right hand side of the Schur complement system is stored
8884 -  sol - location where the solution of the Schur complement system has to be returned
8885 
8886    Notes:
8887    The sizes of the vectors should match the size of the Schur complement
8888 
8889    Level: advanced
8890 
8891    References:
8892 
8893 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8894 @*/
8895 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8896 {
8897   PetscErrorCode ierr;
8898 
8899   PetscFunctionBegin;
8900   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8901   PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
8902   PetscValidHeaderSpecific(sol,VEC_CLASSID,2);
8903   PetscCheckSameComm(F,1,rhs,2);
8904   PetscCheckSameComm(F,1,sol,3);
8905   ierr = PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr);
8906   PetscFunctionReturn(0);
8907 }
8908 
8909 #undef __FUNCT__
8910 #define __FUNCT__ "MatFactorInvertSchurComplement"
8911 /*@
8912   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step
8913 
8914    Logically Collective on Mat
8915 
8916    Input Parameters:
8917 +  F - the factored matrix obtained by calling MatGetFactor()
8918 
8919    Notes:
8920 
8921    Level: advanced
8922 
8923    References:
8924 
8925 .seealso: MatGetFactor(), MatFactorSetSchurIS()
8926 @*/
8927 PetscErrorCode MatFactorInvertSchurComplement(Mat F)
8928 {
8929   PetscErrorCode ierr;
8930 
8931   PetscFunctionBegin;
8932   PetscValidHeaderSpecific(F,MAT_CLASSID,1);
8933   ierr = PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));CHKERRQ(ierr);
8934   PetscFunctionReturn(0);
8935 }
8936 
8937 
8938 #undef __FUNCT__
8939 #define __FUNCT__ "MatPtAP"
8940 /*@
8941    MatPtAP - Creates the matrix product C = P^T * A * P
8942 
8943    Neighbor-wise Collective on Mat
8944 
8945    Input Parameters:
8946 +  A - the matrix
8947 .  P - the projection matrix
8948 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8949 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8950 
8951    Output Parameters:
8952 .  C - the product matrix
8953 
8954    Notes:
8955    C will be created and must be destroyed by the user with MatDestroy().
8956 
8957    This routine is currently only implemented for pairs of AIJ matrices and classes
8958    which inherit from AIJ.
8959 
8960    Level: intermediate
8961 
8962 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8963 @*/
8964 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8965 {
8966   PetscErrorCode ierr;
8967   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8968   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8969   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8970   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8971 
8972   PetscFunctionBegin;
8973   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr);
8974   ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr);
8975 
8976   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8977   PetscValidType(A,1);
8978   MatCheckPreallocated(A,1);
8979   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8980   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8981   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8982   PetscValidType(P,2);
8983   MatCheckPreallocated(P,2);
8984   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8985   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8986 
8987   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);
8988   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8989 
8990   if (scall == MAT_REUSE_MATRIX) {
8991     PetscValidPointer(*C,5);
8992     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8993     if (viatranspose || viamatmatmatmult) {
8994       Mat Pt;
8995       ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
8996       if (viamatmatmatmult) {
8997         ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
8998       } else {
8999         Mat AP;
9000         ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9001         ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9002         ierr = MatDestroy(&AP);CHKERRQ(ierr);
9003       }
9004       ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9005     } else {
9006       ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9007       ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9008       ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
9009       ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9010       ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9011     }
9012     PetscFunctionReturn(0);
9013   }
9014 
9015   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9016   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9017 
9018   fA = A->ops->ptap;
9019   fP = P->ops->ptap;
9020   if (fP == fA) {
9021     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9022     ptap = fA;
9023   } else {
9024     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9025     char ptapname[256];
9026     ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr);
9027     ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9028     ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr);
9029     ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr);
9030     ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9031     ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr);
9032     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);
9033   }
9034 
9035   if (viatranspose || viamatmatmatmult) {
9036     Mat Pt;
9037     ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr);
9038     if (viamatmatmatmult) {
9039       ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr);
9040       ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr);
9041     } else {
9042       Mat AP;
9043       ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr);
9044       ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr);
9045       ierr = MatDestroy(&AP);CHKERRQ(ierr);
9046       ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr);
9047     }
9048     ierr = MatDestroy(&Pt);CHKERRQ(ierr);
9049   } else {
9050     ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9051     ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
9052     ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
9053   }
9054   PetscFunctionReturn(0);
9055 }
9056 
9057 #undef __FUNCT__
9058 #define __FUNCT__ "MatPtAPNumeric"
9059 /*@
9060    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9061 
9062    Neighbor-wise Collective on Mat
9063 
9064    Input Parameters:
9065 +  A - the matrix
9066 -  P - the projection matrix
9067 
9068    Output Parameters:
9069 .  C - the product matrix
9070 
9071    Notes:
9072    C must have been created by calling MatPtAPSymbolic and must be destroyed by
9073    the user using MatDeatroy().
9074 
9075    This routine is currently only implemented for pairs of AIJ matrices and classes
9076    which inherit from AIJ.  C will be of type MATAIJ.
9077 
9078    Level: intermediate
9079 
9080 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9081 @*/
9082 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9083 {
9084   PetscErrorCode ierr;
9085 
9086   PetscFunctionBegin;
9087   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9088   PetscValidType(A,1);
9089   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9090   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9091   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9092   PetscValidType(P,2);
9093   MatCheckPreallocated(P,2);
9094   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9095   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9096   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9097   PetscValidType(C,3);
9098   MatCheckPreallocated(C,3);
9099   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9100   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);
9101   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);
9102   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);
9103   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);
9104   MatCheckPreallocated(A,1);
9105 
9106   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9107   ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
9108   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
9109   PetscFunctionReturn(0);
9110 }
9111 
9112 #undef __FUNCT__
9113 #define __FUNCT__ "MatPtAPSymbolic"
9114 /*@
9115    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9116 
9117    Neighbor-wise Collective on Mat
9118 
9119    Input Parameters:
9120 +  A - the matrix
9121 -  P - the projection matrix
9122 
9123    Output Parameters:
9124 .  C - the (i,j) structure of the product matrix
9125 
9126    Notes:
9127    C will be created and must be destroyed by the user with MatDestroy().
9128 
9129    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9130    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9131    this (i,j) structure by calling MatPtAPNumeric().
9132 
9133    Level: intermediate
9134 
9135 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9136 @*/
9137 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9138 {
9139   PetscErrorCode ierr;
9140 
9141   PetscFunctionBegin;
9142   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9143   PetscValidType(A,1);
9144   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9145   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9146   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9147   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
9148   PetscValidType(P,2);
9149   MatCheckPreallocated(P,2);
9150   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9151   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9152   PetscValidPointer(C,3);
9153 
9154   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);
9155   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);
9156   MatCheckPreallocated(A,1);
9157   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9158   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
9159   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
9160 
9161   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
9162   PetscFunctionReturn(0);
9163 }
9164 
9165 #undef __FUNCT__
9166 #define __FUNCT__ "MatRARt"
9167 /*@
9168    MatRARt - Creates the matrix product C = R * A * R^T
9169 
9170    Neighbor-wise Collective on Mat
9171 
9172    Input Parameters:
9173 +  A - the matrix
9174 .  R - the projection matrix
9175 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9176 -  fill - expected fill as ratio of nnz(C)/nnz(A)
9177 
9178    Output Parameters:
9179 .  C - the product matrix
9180 
9181    Notes:
9182    C will be created and must be destroyed by the user with MatDestroy().
9183 
9184    This routine is currently only implemented for pairs of AIJ matrices and classes
9185    which inherit from AIJ.
9186 
9187    Level: intermediate
9188 
9189 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9190 @*/
9191 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9192 {
9193   PetscErrorCode ierr;
9194 
9195   PetscFunctionBegin;
9196   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9197   PetscValidType(A,1);
9198   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9199   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9200   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9201   PetscValidType(R,2);
9202   MatCheckPreallocated(R,2);
9203   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9204   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9205   PetscValidPointer(C,3);
9206   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);
9207   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9208   MatCheckPreallocated(A,1);
9209 
9210   if (!A->ops->rart) {
9211     MatType mattype;
9212     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
9213     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9214   }
9215   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9216   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
9217   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
9218   PetscFunctionReturn(0);
9219 }
9220 
9221 #undef __FUNCT__
9222 #define __FUNCT__ "MatRARtNumeric"
9223 /*@
9224    MatRARtNumeric - Computes the matrix product C = R * A * R^T
9225 
9226    Neighbor-wise Collective on Mat
9227 
9228    Input Parameters:
9229 +  A - the matrix
9230 -  R - the projection matrix
9231 
9232    Output Parameters:
9233 .  C - the product matrix
9234 
9235    Notes:
9236    C must have been created by calling MatRARtSymbolic and must be destroyed by
9237    the user using MatDestroy().
9238 
9239    This routine is currently only implemented for pairs of AIJ matrices and classes
9240    which inherit from AIJ.  C will be of type MATAIJ.
9241 
9242    Level: intermediate
9243 
9244 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9245 @*/
9246 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9247 {
9248   PetscErrorCode ierr;
9249 
9250   PetscFunctionBegin;
9251   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9252   PetscValidType(A,1);
9253   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9254   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9255   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9256   PetscValidType(R,2);
9257   MatCheckPreallocated(R,2);
9258   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9259   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9260   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9261   PetscValidType(C,3);
9262   MatCheckPreallocated(C,3);
9263   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9264   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);
9265   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);
9266   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);
9267   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);
9268   MatCheckPreallocated(A,1);
9269 
9270   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9271   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
9272   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
9273   PetscFunctionReturn(0);
9274 }
9275 
9276 #undef __FUNCT__
9277 #define __FUNCT__ "MatRARtSymbolic"
9278 /*@
9279    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9280 
9281    Neighbor-wise Collective on Mat
9282 
9283    Input Parameters:
9284 +  A - the matrix
9285 -  R - the projection matrix
9286 
9287    Output Parameters:
9288 .  C - the (i,j) structure of the product matrix
9289 
9290    Notes:
9291    C will be created and must be destroyed by the user with MatDestroy().
9292 
9293    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9294    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
9295    this (i,j) structure by calling MatRARtNumeric().
9296 
9297    Level: intermediate
9298 
9299 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9300 @*/
9301 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9302 {
9303   PetscErrorCode ierr;
9304 
9305   PetscFunctionBegin;
9306   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9307   PetscValidType(A,1);
9308   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9309   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9310   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9311   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
9312   PetscValidType(R,2);
9313   MatCheckPreallocated(R,2);
9314   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9315   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9316   PetscValidPointer(C,3);
9317 
9318   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);
9319   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);
9320   MatCheckPreallocated(A,1);
9321   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9322   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
9323   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
9324 
9325   ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr);
9326   PetscFunctionReturn(0);
9327 }
9328 
9329 #undef __FUNCT__
9330 #define __FUNCT__ "MatMatMult"
9331 /*@
9332    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9333 
9334    Neighbor-wise Collective on Mat
9335 
9336    Input Parameters:
9337 +  A - the left matrix
9338 .  B - the right matrix
9339 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9340 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9341           if the result is a dense matrix this is irrelevent
9342 
9343    Output Parameters:
9344 .  C - the product matrix
9345 
9346    Notes:
9347    Unless scall is MAT_REUSE_MATRIX C will be created.
9348 
9349    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9350 
9351    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9352    actually needed.
9353 
9354    If you have many matrices with the same non-zero structure to multiply, you
9355    should either
9356 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9357 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9358    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
9359    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9360 
9361    Level: intermediate
9362 
9363 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
9364 @*/
9365 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9366 {
9367   PetscErrorCode ierr;
9368   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9369   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9370   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9371 
9372   PetscFunctionBegin;
9373   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9374   PetscValidType(A,1);
9375   MatCheckPreallocated(A,1);
9376   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9377   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9378   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9379   PetscValidType(B,2);
9380   MatCheckPreallocated(B,2);
9381   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9382   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9383   PetscValidPointer(C,3);
9384   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);
9385   if (scall == MAT_REUSE_MATRIX) {
9386     PetscValidPointer(*C,5);
9387     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
9388     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9389     ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9390     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
9391     ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
9392     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9393     PetscFunctionReturn(0);
9394   }
9395   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9396   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9397 
9398   fA = A->ops->matmult;
9399   fB = B->ops->matmult;
9400   if (fB == fA) {
9401     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9402     mult = fB;
9403   } else {
9404     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9405     char multname[256];
9406     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
9407     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9408     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9409     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9410     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9411     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9412     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);
9413   }
9414   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9415   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
9416   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
9417   PetscFunctionReturn(0);
9418 }
9419 
9420 #undef __FUNCT__
9421 #define __FUNCT__ "MatMatMultSymbolic"
9422 /*@
9423    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9424    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
9425 
9426    Neighbor-wise Collective on Mat
9427 
9428    Input Parameters:
9429 +  A - the left matrix
9430 .  B - the right matrix
9431 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9432       if C is a dense matrix this is irrelevent
9433 
9434    Output Parameters:
9435 .  C - the product matrix
9436 
9437    Notes:
9438    Unless scall is MAT_REUSE_MATRIX C will be created.
9439 
9440    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9441    actually needed.
9442 
9443    This routine is currently implemented for
9444     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9445     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9446     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9447 
9448    Level: intermediate
9449 
9450    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9451      We should incorporate them into PETSc.
9452 
9453 .seealso: MatMatMult(), MatMatMultNumeric()
9454 @*/
9455 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9456 {
9457   PetscErrorCode ierr;
9458   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9459   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9460   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9461 
9462   PetscFunctionBegin;
9463   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9464   PetscValidType(A,1);
9465   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9466   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9467 
9468   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9469   PetscValidType(B,2);
9470   MatCheckPreallocated(B,2);
9471   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9472   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9473   PetscValidPointer(C,3);
9474 
9475   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);
9476   if (fill == PETSC_DEFAULT) fill = 2.0;
9477   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9478   MatCheckPreallocated(A,1);
9479 
9480   Asymbolic = A->ops->matmultsymbolic;
9481   Bsymbolic = B->ops->matmultsymbolic;
9482   if (Asymbolic == Bsymbolic) {
9483     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9484     symbolic = Bsymbolic;
9485   } else { /* dispatch based on the type of A and B */
9486     char symbolicname[256];
9487     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
9488     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9489     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
9490     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9491     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
9492     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr);
9493     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);
9494   }
9495   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9496   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
9497   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9498   PetscFunctionReturn(0);
9499 }
9500 
9501 #undef __FUNCT__
9502 #define __FUNCT__ "MatMatMultNumeric"
9503 /*@
9504    MatMatMultNumeric - Performs the numeric matrix-matrix product.
9505    Call this routine after first calling MatMatMultSymbolic().
9506 
9507    Neighbor-wise Collective on Mat
9508 
9509    Input Parameters:
9510 +  A - the left matrix
9511 -  B - the right matrix
9512 
9513    Output Parameters:
9514 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9515 
9516    Notes:
9517    C must have been created with MatMatMultSymbolic().
9518 
9519    This routine is currently implemented for
9520     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9521     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9522     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9523 
9524    Level: intermediate
9525 
9526 .seealso: MatMatMult(), MatMatMultSymbolic()
9527 @*/
9528 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9529 {
9530   PetscErrorCode ierr;
9531 
9532   PetscFunctionBegin;
9533   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr);
9534   PetscFunctionReturn(0);
9535 }
9536 
9537 #undef __FUNCT__
9538 #define __FUNCT__ "MatMatTransposeMult"
9539 /*@
9540    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9541 
9542    Neighbor-wise Collective on Mat
9543 
9544    Input Parameters:
9545 +  A - the left matrix
9546 .  B - the right matrix
9547 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9548 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9549 
9550    Output Parameters:
9551 .  C - the product matrix
9552 
9553    Notes:
9554    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9555 
9556    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9557 
9558   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9559    actually needed.
9560 
9561    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
9562 
9563    Level: intermediate
9564 
9565 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9566 @*/
9567 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9568 {
9569   PetscErrorCode ierr;
9570   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9571   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9572 
9573   PetscFunctionBegin;
9574   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9575   PetscValidType(A,1);
9576   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9577   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9578   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9579   PetscValidType(B,2);
9580   MatCheckPreallocated(B,2);
9581   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9582   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9583   PetscValidPointer(C,3);
9584   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);
9585   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9586   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9587   MatCheckPreallocated(A,1);
9588 
9589   fA = A->ops->mattransposemult;
9590   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9591   fB = B->ops->mattransposemult;
9592   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9593   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);
9594 
9595   ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9596   if (scall == MAT_INITIAL_MATRIX) {
9597     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9598     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
9599     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
9600   }
9601   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9602   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
9603   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
9604   ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);
9605   PetscFunctionReturn(0);
9606 }
9607 
9608 #undef __FUNCT__
9609 #define __FUNCT__ "MatTransposeMatMult"
9610 /*@
9611    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9612 
9613    Neighbor-wise Collective on Mat
9614 
9615    Input Parameters:
9616 +  A - the left matrix
9617 .  B - the right matrix
9618 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9619 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9620 
9621    Output Parameters:
9622 .  C - the product matrix
9623 
9624    Notes:
9625    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9626 
9627    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9628 
9629   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9630    actually needed.
9631 
9632    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9633    which inherit from SeqAIJ.  C will be of same type as the input matrices.
9634 
9635    Level: intermediate
9636 
9637 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9638 @*/
9639 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9640 {
9641   PetscErrorCode ierr;
9642   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9643   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9644   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9645 
9646   PetscFunctionBegin;
9647   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9648   PetscValidType(A,1);
9649   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9650   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9651   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9652   PetscValidType(B,2);
9653   MatCheckPreallocated(B,2);
9654   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9655   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9656   PetscValidPointer(C,3);
9657   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);
9658   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9659   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9660   MatCheckPreallocated(A,1);
9661 
9662   fA = A->ops->transposematmult;
9663   fB = B->ops->transposematmult;
9664   if (fB==fA) {
9665     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9666     transposematmult = fA;
9667   } else {
9668     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9669     char multname[256];
9670     ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);
9671     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9672     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9673     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9674     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9675     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);
9676     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);
9677   }
9678   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9679   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
9680   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
9681   PetscFunctionReturn(0);
9682 }
9683 
9684 #undef __FUNCT__
9685 #define __FUNCT__ "MatMatMatMult"
9686 /*@
9687    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9688 
9689    Neighbor-wise Collective on Mat
9690 
9691    Input Parameters:
9692 +  A - the left matrix
9693 .  B - the middle matrix
9694 .  C - the right matrix
9695 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9696 -  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
9697           if the result is a dense matrix this is irrelevent
9698 
9699    Output Parameters:
9700 .  D - the product matrix
9701 
9702    Notes:
9703    Unless scall is MAT_REUSE_MATRIX D will be created.
9704 
9705    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9706 
9707    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9708    actually needed.
9709 
9710    If you have many matrices with the same non-zero structure to multiply, you
9711    should either
9712 $   1) use MAT_REUSE_MATRIX in all calls but the first or
9713 $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
9714 
9715    Level: intermediate
9716 
9717 .seealso: MatMatMult, MatPtAP()
9718 @*/
9719 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9720 {
9721   PetscErrorCode ierr;
9722   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9723   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9724   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9725   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9726 
9727   PetscFunctionBegin;
9728   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
9729   PetscValidType(A,1);
9730   MatCheckPreallocated(A,1);
9731   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9732   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9733   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
9734   PetscValidType(B,2);
9735   MatCheckPreallocated(B,2);
9736   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9737   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9738   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
9739   PetscValidPointer(C,3);
9740   MatCheckPreallocated(C,3);
9741   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9742   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9743   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);
9744   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);
9745   if (scall == MAT_REUSE_MATRIX) {
9746     PetscValidPointer(*D,6);
9747     PetscValidHeaderSpecific(*D,MAT_CLASSID,6);
9748     ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9749     ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9750     ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9751     PetscFunctionReturn(0);
9752   }
9753   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9754   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9755 
9756   fA = A->ops->matmatmult;
9757   fB = B->ops->matmatmult;
9758   fC = C->ops->matmatmult;
9759   if (fA == fB && fA == fC) {
9760     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9761     mult = fA;
9762   } else {
9763     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9764     char multname[256];
9765     ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr);
9766     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
9767     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9768     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
9769     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
9770     ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr);
9771     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr);
9772     ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr);
9773     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);
9774   }
9775   ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9776   ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr);
9777   ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr);
9778   PetscFunctionReturn(0);
9779 }
9780 
9781 #undef __FUNCT__
9782 #define __FUNCT__ "MatCreateRedundantMatrix"
9783 /*@C
9784    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9785 
9786    Collective on Mat
9787 
9788    Input Parameters:
9789 +  mat - the matrix
9790 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9791 .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9792 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9793 
9794    Output Parameter:
9795 .  matredundant - redundant matrix
9796 
9797    Notes:
9798    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9799    original matrix has not changed from that last call to MatCreateRedundantMatrix().
9800 
9801    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9802    calling it.
9803 
9804    Level: advanced
9805 
9806    Concepts: subcommunicator
9807    Concepts: duplicate matrix
9808 
9809 .seealso: MatDestroy()
9810 @*/
9811 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9812 {
9813   PetscErrorCode ierr;
9814   MPI_Comm       comm;
9815   PetscMPIInt    size;
9816   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9817   Mat_Redundant  *redund=NULL;
9818   PetscSubcomm   psubcomm=NULL;
9819   MPI_Comm       subcomm_in=subcomm;
9820   Mat            *matseq;
9821   IS             isrow,iscol;
9822   PetscBool      newsubcomm=PETSC_FALSE;
9823 
9824   PetscFunctionBegin;
9825   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr);
9826   if (size == 1 || nsubcomm == 1) {
9827     if (reuse == MAT_INITIAL_MATRIX) {
9828       ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr);
9829     } else {
9830       ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
9831     }
9832     PetscFunctionReturn(0);
9833   }
9834 
9835   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9836   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9837     PetscValidPointer(*matredundant,5);
9838     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5);
9839   }
9840   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9841   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9842   MatCheckPreallocated(mat,1);
9843 
9844   ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9845   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9846     /* create psubcomm, then get subcomm */
9847     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9848     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
9849     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9850 
9851     ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr);
9852     ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr);
9853     ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr);
9854     ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr);
9855     ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr);
9856     newsubcomm = PETSC_TRUE;
9857     ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr);
9858   }
9859 
9860   /* get isrow, iscol and a local sequential matrix matseq[0] */
9861   if (reuse == MAT_INITIAL_MATRIX) {
9862     mloc_sub = PETSC_DECIDE;
9863     if (bs < 1) {
9864       ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr);
9865     } else {
9866       ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr);
9867     }
9868     ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr);
9869     rstart = rend - mloc_sub;
9870     ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr);
9871     ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr);
9872   } else { /* reuse == MAT_REUSE_MATRIX */
9873     /* retrieve subcomm */
9874     ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr);
9875     redund = (*matredundant)->redundant;
9876     isrow  = redund->isrow;
9877     iscol  = redund->iscol;
9878     matseq = redund->matseq;
9879   }
9880   ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr);
9881 
9882   /* get matredundant over subcomm */
9883   if (reuse == MAT_INITIAL_MATRIX) {
9884     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);CHKERRQ(ierr);
9885 
9886     /* create a supporting struct and attach it to C for reuse */
9887     ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr);
9888     (*matredundant)->redundant = redund;
9889     redund->isrow              = isrow;
9890     redund->iscol              = iscol;
9891     redund->matseq             = matseq;
9892     if (newsubcomm) {
9893       redund->subcomm          = subcomm;
9894     } else {
9895       redund->subcomm          = MPI_COMM_NULL;
9896     }
9897   } else {
9898     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr);
9899   }
9900   ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr);
9901   PetscFunctionReturn(0);
9902 }
9903 
9904 #undef __FUNCT__
9905 #define __FUNCT__ "MatGetMultiProcBlock"
9906 /*@C
9907    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9908    a given 'mat' object. Each submatrix can span multiple procs.
9909 
9910    Collective on Mat
9911 
9912    Input Parameters:
9913 +  mat - the matrix
9914 .  subcomm - the subcommunicator obtained by com_split(comm)
9915 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9916 
9917    Output Parameter:
9918 .  subMat - 'parallel submatrices each spans a given subcomm
9919 
9920   Notes:
9921   The submatrix partition across processors is dictated by 'subComm' a
9922   communicator obtained by com_split(comm). The comm_split
9923   is not restriced to be grouped with consecutive original ranks.
9924 
9925   Due the comm_split() usage, the parallel layout of the submatrices
9926   map directly to the layout of the original matrix [wrt the local
9927   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9928   into the 'DiagonalMat' of the subMat, hence it is used directly from
9929   the subMat. However the offDiagMat looses some columns - and this is
9930   reconstructed with MatSetValues()
9931 
9932   Level: advanced
9933 
9934   Concepts: subcommunicator
9935   Concepts: submatrices
9936 
9937 .seealso: MatGetSubMatrices()
9938 @*/
9939 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9940 {
9941   PetscErrorCode ierr;
9942   PetscMPIInt    commsize,subCommSize;
9943 
9944   PetscFunctionBegin;
9945   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr);
9946   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9947   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9948 
9949   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9950   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9951   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9952   PetscFunctionReturn(0);
9953 }
9954 
9955 #undef __FUNCT__
9956 #define __FUNCT__ "MatGetLocalSubMatrix"
9957 /*@
9958    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9959 
9960    Not Collective
9961 
9962    Input Arguments:
9963    mat - matrix to extract local submatrix from
9964    isrow - local row indices for submatrix
9965    iscol - local column indices for submatrix
9966 
9967    Output Arguments:
9968    submat - the submatrix
9969 
9970    Level: intermediate
9971 
9972    Notes:
9973    The submat should be returned with MatRestoreLocalSubMatrix().
9974 
9975    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9976    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9977 
9978    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9979    MatSetValuesBlockedLocal() will also be implemented.
9980 
9981 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9982 @*/
9983 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9984 {
9985   PetscErrorCode ierr;
9986 
9987   PetscFunctionBegin;
9988   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9989   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9990   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9991   PetscCheckSameComm(isrow,2,iscol,3);
9992   PetscValidPointer(submat,4);
9993 
9994   if (mat->ops->getlocalsubmatrix) {
9995     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9996   } else {
9997     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9998   }
9999   PetscFunctionReturn(0);
10000 }
10001 
10002 #undef __FUNCT__
10003 #define __FUNCT__ "MatRestoreLocalSubMatrix"
10004 /*@
10005    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10006 
10007    Not Collective
10008 
10009    Input Arguments:
10010    mat - matrix to extract local submatrix from
10011    isrow - local row indices for submatrix
10012    iscol - local column indices for submatrix
10013    submat - the submatrix
10014 
10015    Level: intermediate
10016 
10017 .seealso: MatGetLocalSubMatrix()
10018 @*/
10019 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10020 {
10021   PetscErrorCode ierr;
10022 
10023   PetscFunctionBegin;
10024   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10025   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
10026   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
10027   PetscCheckSameComm(isrow,2,iscol,3);
10028   PetscValidPointer(submat,4);
10029   if (*submat) {
10030     PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);
10031   }
10032 
10033   if (mat->ops->restorelocalsubmatrix) {
10034     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
10035   } else {
10036     ierr = MatDestroy(submat);CHKERRQ(ierr);
10037   }
10038   *submat = NULL;
10039   PetscFunctionReturn(0);
10040 }
10041 
10042 /* --------------------------------------------------------*/
10043 #undef __FUNCT__
10044 #define __FUNCT__ "MatFindZeroDiagonals"
10045 /*@
10046    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
10047 
10048    Collective on Mat
10049 
10050    Input Parameter:
10051 .  mat - the matrix
10052 
10053    Output Parameter:
10054 .  is - if any rows have zero diagonals this contains the list of them
10055 
10056    Level: developer
10057 
10058    Concepts: matrix-vector product
10059 
10060 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10061 @*/
10062 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10063 {
10064   PetscErrorCode ierr;
10065 
10066   PetscFunctionBegin;
10067   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10068   PetscValidType(mat,1);
10069   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10070   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10071 
10072   if (!mat->ops->findzerodiagonals) {
10073     Vec                diag;
10074     const PetscScalar *a;
10075     PetscInt          *rows;
10076     PetscInt           rStart, rEnd, r, nrow = 0;
10077 
10078     ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr);
10079     ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr);
10080     ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr);
10081     ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr);
10082     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10083     ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr);
10084     nrow = 0;
10085     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10086     ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr);
10087     ierr = VecDestroy(&diag);CHKERRQ(ierr);
10088     ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
10089   } else {
10090     ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr);
10091   }
10092   PetscFunctionReturn(0);
10093 }
10094 
10095 #undef __FUNCT__
10096 #define __FUNCT__ "MatFindOffBlockDiagonalEntries"
10097 /*@
10098    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10099 
10100    Collective on Mat
10101 
10102    Input Parameter:
10103 .  mat - the matrix
10104 
10105    Output Parameter:
10106 .  is - contains the list of rows with off block diagonal entries
10107 
10108    Level: developer
10109 
10110    Concepts: matrix-vector product
10111 
10112 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10113 @*/
10114 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10115 {
10116   PetscErrorCode ierr;
10117 
10118   PetscFunctionBegin;
10119   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10120   PetscValidType(mat,1);
10121   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10122   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10123 
10124   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10125   ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr);
10126   PetscFunctionReturn(0);
10127 }
10128 
10129 #undef __FUNCT__
10130 #define __FUNCT__ "MatInvertBlockDiagonal"
10131 /*@C
10132   MatInvertBlockDiagonal - Inverts the block diagonal entries.
10133 
10134   Collective on Mat
10135 
10136   Input Parameters:
10137 . mat - the matrix
10138 
10139   Output Parameters:
10140 . values - the block inverses in column major order (FORTRAN-like)
10141 
10142    Note:
10143    This routine is not available from Fortran.
10144 
10145   Level: advanced
10146 @*/
10147 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10148 {
10149   PetscErrorCode ierr;
10150 
10151   PetscFunctionBegin;
10152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10153   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10154   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10155   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10156   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
10157   PetscFunctionReturn(0);
10158 }
10159 
10160 #undef __FUNCT__
10161 #define __FUNCT__ "MatTransposeColoringDestroy"
10162 /*@C
10163     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10164     via MatTransposeColoringCreate().
10165 
10166     Collective on MatTransposeColoring
10167 
10168     Input Parameter:
10169 .   c - coloring context
10170 
10171     Level: intermediate
10172 
10173 .seealso: MatTransposeColoringCreate()
10174 @*/
10175 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10176 {
10177   PetscErrorCode       ierr;
10178   MatTransposeColoring matcolor=*c;
10179 
10180   PetscFunctionBegin;
10181   if (!matcolor) PetscFunctionReturn(0);
10182   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
10183 
10184   ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr);
10185   ierr = PetscFree(matcolor->rows);CHKERRQ(ierr);
10186   ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr);
10187   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
10188   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
10189   if (matcolor->brows>0) {
10190     ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr);
10191   }
10192   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
10193   PetscFunctionReturn(0);
10194 }
10195 
10196 #undef __FUNCT__
10197 #define __FUNCT__ "MatTransColoringApplySpToDen"
10198 /*@C
10199     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10200     a MatTransposeColoring context has been created, computes a dense B^T by Apply
10201     MatTransposeColoring to sparse B.
10202 
10203     Collective on MatTransposeColoring
10204 
10205     Input Parameters:
10206 +   B - sparse matrix B
10207 .   Btdense - symbolic dense matrix B^T
10208 -   coloring - coloring context created with MatTransposeColoringCreate()
10209 
10210     Output Parameter:
10211 .   Btdense - dense matrix B^T
10212 
10213     Options Database Keys:
10214 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
10215 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
10216 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
10217 
10218     Level: intermediate
10219 
10220 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
10221 
10222 .keywords: coloring
10223 @*/
10224 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10225 {
10226   PetscErrorCode ierr;
10227 
10228   PetscFunctionBegin;
10229   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
10230   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
10231   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
10232 
10233   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10234   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
10235   PetscFunctionReturn(0);
10236 }
10237 
10238 #undef __FUNCT__
10239 #define __FUNCT__ "MatTransColoringApplyDenToSp"
10240 /*@C
10241     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10242     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10243     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10244     Csp from Cden.
10245 
10246     Collective on MatTransposeColoring
10247 
10248     Input Parameters:
10249 +   coloring - coloring context created with MatTransposeColoringCreate()
10250 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
10251 
10252     Output Parameter:
10253 .   Csp - sparse matrix
10254 
10255     Options Database Keys:
10256 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
10257 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
10258 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
10259 
10260     Level: intermediate
10261 
10262 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10263 
10264 .keywords: coloring
10265 @*/
10266 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10267 {
10268   PetscErrorCode ierr;
10269 
10270   PetscFunctionBegin;
10271   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
10272   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
10273   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
10274 
10275   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10276   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
10277   PetscFunctionReturn(0);
10278 }
10279 
10280 #undef __FUNCT__
10281 #define __FUNCT__ "MatTransposeColoringCreate"
10282 /*@C
10283    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10284 
10285    Collective on Mat
10286 
10287    Input Parameters:
10288 +  mat - the matrix product C
10289 -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10290 
10291     Output Parameter:
10292 .   color - the new coloring context
10293 
10294     Level: intermediate
10295 
10296 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
10297            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
10298 @*/
10299 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10300 {
10301   MatTransposeColoring c;
10302   MPI_Comm             comm;
10303   PetscErrorCode       ierr;
10304 
10305   PetscFunctionBegin;
10306   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10307   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
10308   ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr);
10309 
10310   c->ctype = iscoloring->ctype;
10311   if (mat->ops->transposecoloringcreate) {
10312     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
10313   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10314 
10315   *color = c;
10316   ierr   = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
10317   PetscFunctionReturn(0);
10318 }
10319 
10320 #undef __FUNCT__
10321 #define __FUNCT__ "MatGetNonzeroState"
10322 /*@
10323       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10324         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10325         same, otherwise it will be larger
10326 
10327      Not Collective
10328 
10329   Input Parameter:
10330 .    A  - the matrix
10331 
10332   Output Parameter:
10333 .    state - the current state
10334 
10335   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10336          different matrices
10337 
10338   Level: intermediate
10339 
10340 @*/
10341 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10342 {
10343   PetscFunctionBegin;
10344   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
10345   *state = mat->nonzerostate;
10346   PetscFunctionReturn(0);
10347 }
10348 
10349 #undef __FUNCT__
10350 #define __FUNCT__ "MatCreateMPIMatConcatenateSeqMat"
10351 /*@
10352       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10353                  matrices from each processor
10354 
10355     Collective on MPI_Comm
10356 
10357    Input Parameters:
10358 +    comm - the communicators the parallel matrix will live on
10359 .    seqmat - the input sequential matrices
10360 .    n - number of local columns (or PETSC_DECIDE)
10361 -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10362 
10363    Output Parameter:
10364 .    mpimat - the parallel matrix generated
10365 
10366     Level: advanced
10367 
10368    Notes: The number of columns of the matrix in EACH processor MUST be the same.
10369 
10370 @*/
10371 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10372 {
10373   PetscErrorCode ierr;
10374   PetscMPIInt    size;
10375 
10376   PetscFunctionBegin;
10377   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10378   if (size == 1) {
10379     if (reuse == MAT_INITIAL_MATRIX) {
10380       ierr = MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);CHKERRQ(ierr);
10381     } else {
10382       ierr = MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
10383     }
10384     PetscFunctionReturn(0);
10385   }
10386 
10387   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10388   ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10389   ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr);
10390   ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr);
10391   PetscFunctionReturn(0);
10392 }
10393 
10394 #undef __FUNCT__
10395 #define __FUNCT__ "MatSubdomainsCreateCoalesce"
10396 /*@
10397      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10398                  ranks' ownership ranges.
10399 
10400     Collective on A
10401 
10402    Input Parameters:
10403 +    A   - the matrix to create subdomains from
10404 -    N   - requested number of subdomains
10405 
10406 
10407    Output Parameters:
10408 +    n   - number of subdomains resulting on this rank
10409 -    iss - IS list with indices of subdomains on this rank
10410 
10411     Level: advanced
10412 
10413     Notes: number of subdomains must be smaller than the communicator size
10414 @*/
10415 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10416 {
10417   MPI_Comm        comm,subcomm;
10418   PetscMPIInt     size,rank,color;
10419   PetscInt        rstart,rend,k;
10420   PetscErrorCode  ierr;
10421 
10422   PetscFunctionBegin;
10423   ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr);
10424   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
10425   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
10426   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);
10427   *n = 1;
10428   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10429   color = rank/k;
10430   ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr);
10431   ierr = PetscMalloc1(1,iss);CHKERRQ(ierr);
10432   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
10433   ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr);
10434   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
10435   PetscFunctionReturn(0);
10436 }
10437