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