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