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