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