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