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