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