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