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