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