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