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