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