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