xref: /petsc/src/mat/interface/matrix.c (revision 6bf464f92cc51e6fd6163850774a6badb2f63b6b)
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   PetscFunctionReturn(0);
3812 }
3813 
3814 #undef __FUNCT__
3815 #define __FUNCT__ "MatFactorGetSolverPackage"
3816 /*@C
3817    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3818 
3819    Not Collective
3820 
3821    Input Parameter:
3822 .  mat - the matrix, must be a factored matrix
3823 
3824    Output Parameter:
3825 .   type - the string name of the package (do not free this string)
3826 
3827    Notes:
3828       In Fortran you pass in a empty string and the package name will be copied into it.
3829     (Make sure the string is long enough)
3830 
3831    Level: intermediate
3832 
3833 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3834 @*/
3835 PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3836 {
3837   PetscErrorCode         ierr;
3838   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);
3839 
3840   PetscFunctionBegin;
3841   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3842   PetscValidType(mat,1);
3843   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3844   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);CHKERRQ(ierr);
3845   if (!conv) {
3846     *type = MATSOLVERPETSC;
3847   } else {
3848     ierr = (*conv)(mat,type);CHKERRQ(ierr);
3849   }
3850   PetscFunctionReturn(0);
3851 }
3852 
3853 #undef __FUNCT__
3854 #define __FUNCT__ "MatGetFactor"
3855 /*@C
3856    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3857 
3858    Collective on Mat
3859 
3860    Input Parameters:
3861 +  mat - the matrix
3862 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3863 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3864 
3865    Output Parameters:
3866 .  f - the factor matrix used with MatXXFactorSymbolic() calls
3867 
3868    Notes:
3869       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3870      such as pastix, superlu, mumps, spooles etc.
3871 
3872       PETSc must have been ./configure to use the external solver, using the option --download-package
3873 
3874    Level: intermediate
3875 
3876 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3877 @*/
3878 PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3879 {
3880   PetscErrorCode  ierr,(*conv)(Mat,MatFactorType,Mat*);
3881   char            convname[256];
3882 
3883   PetscFunctionBegin;
3884   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3885   PetscValidType(mat,1);
3886 
3887   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3888   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3889 
3890   ierr = PetscStrcpy(convname,"MatGetFactor_");CHKERRQ(ierr);
3891   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3892   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3893   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3894   if (!conv) {
3895     PetscBool  flag;
3896     MPI_Comm   comm;
3897 
3898     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
3899     ierr = PetscStrcasecmp(MATSOLVERPETSC,type,&flag);CHKERRQ(ierr);
3900     if (flag) {
3901       SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3902     } else {
3903       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);
3904     }
3905   }
3906   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
3907   PetscFunctionReturn(0);
3908 }
3909 
3910 #undef __FUNCT__
3911 #define __FUNCT__ "MatGetFactorAvailable"
3912 /*@C
3913    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3914 
3915    Not Collective
3916 
3917    Input Parameters:
3918 +  mat - the matrix
3919 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3920 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3921 
3922    Output Parameter:
3923 .    flg - PETSC_TRUE if the factorization is available
3924 
3925    Notes:
3926       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3927      such as pastix, superlu, mumps, spooles etc.
3928 
3929       PETSc must have been ./configure to use the external solver, using the option --download-package
3930 
3931    Level: intermediate
3932 
3933 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3934 @*/
3935 PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
3936 {
3937   PetscErrorCode         ierr;
3938   char                   convname[256];
3939   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscBool *);
3940 
3941   PetscFunctionBegin;
3942   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3943   PetscValidType(mat,1);
3944 
3945   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3946   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3947 
3948   ierr = PetscStrcpy(convname,"MatGetFactorAvailable_");CHKERRQ(ierr);
3949   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3950   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3951   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3952   if (!conv) {
3953     *flg = PETSC_FALSE;
3954   } else {
3955     ierr = (*conv)(mat,ftype,flg);CHKERRQ(ierr);
3956   }
3957   PetscFunctionReturn(0);
3958 }
3959 
3960 
3961 #undef __FUNCT__
3962 #define __FUNCT__ "MatDuplicate"
3963 /*@
3964    MatDuplicate - Duplicates a matrix including the non-zero structure.
3965 
3966    Collective on Mat
3967 
3968    Input Parameters:
3969 +  mat - the matrix
3970 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3971         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
3972 
3973    Output Parameter:
3974 .  M - pointer to place new matrix
3975 
3976    Level: intermediate
3977 
3978    Concepts: matrices^duplicating
3979 
3980     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
3981 
3982 .seealso: MatCopy(), MatConvert()
3983 @*/
3984 PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3985 {
3986   PetscErrorCode ierr;
3987   Mat            B;
3988   PetscInt       i;
3989 
3990   PetscFunctionBegin;
3991   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3992   PetscValidType(mat,1);
3993   PetscValidPointer(M,3);
3994   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3995   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3996   ierr = MatPreallocated(mat);CHKERRQ(ierr);
3997 
3998   *M  = 0;
3999   if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
4000   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4001   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4002   B = *M;
4003   if (mat->rmapping) {
4004     ierr = MatSetLocalToGlobalMapping(B,mat->rmapping,mat->cmapping);CHKERRQ(ierr);
4005   }
4006   if (mat->rbmapping) {
4007     ierr = MatSetLocalToGlobalMappingBlock(B,mat->rbmapping,mat->cbmapping);CHKERRQ(ierr);
4008   }
4009   ierr = PetscLayoutCopy(mat->rmap,&B->rmap);CHKERRQ(ierr);
4010   ierr = PetscLayoutCopy(mat->cmap,&B->cmap);CHKERRQ(ierr);
4011 
4012   B->stencil.dim = mat->stencil.dim;
4013   B->stencil.noc = mat->stencil.noc;
4014   for (i=0; i<=mat->stencil.dim; i++) {
4015     B->stencil.dims[i]   = mat->stencil.dims[i];
4016     B->stencil.starts[i] = mat->stencil.starts[i];
4017   }
4018 
4019   B->nooffproczerorows = mat->nooffproczerorows;
4020   B->nooffprocentries  = mat->nooffprocentries;
4021   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4022   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4023   PetscFunctionReturn(0);
4024 }
4025 
4026 #undef __FUNCT__
4027 #define __FUNCT__ "MatGetDiagonal"
4028 /*@
4029    MatGetDiagonal - Gets the diagonal of a matrix.
4030 
4031    Logically Collective on Mat and Vec
4032 
4033    Input Parameters:
4034 +  mat - the matrix
4035 -  v - the vector for storing the diagonal
4036 
4037    Output Parameter:
4038 .  v - the diagonal of the matrix
4039 
4040    Level: intermediate
4041 
4042    Concepts: matrices^accessing diagonals
4043 
4044 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4045 @*/
4046 PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4047 {
4048   PetscErrorCode ierr;
4049 
4050   PetscFunctionBegin;
4051   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4052   PetscValidType(mat,1);
4053   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4054   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4055   if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4056   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4057 
4058   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4059   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4060   PetscFunctionReturn(0);
4061 }
4062 
4063 #undef __FUNCT__
4064 #define __FUNCT__ "MatGetRowMin"
4065 /*@
4066    MatGetRowMin - Gets the minimum value (of the real part) of each
4067         row of the matrix
4068 
4069    Logically Collective on Mat and Vec
4070 
4071    Input Parameters:
4072 .  mat - the matrix
4073 
4074    Output Parameter:
4075 +  v - the vector for storing the maximums
4076 -  idx - the indices of the column found for each row (optional)
4077 
4078    Level: intermediate
4079 
4080    Notes: The result of this call are the same as if one converted the matrix to dense format
4081       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4082 
4083     This code is only implemented for a couple of matrix formats.
4084 
4085    Concepts: matrices^getting row maximums
4086 
4087 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4088           MatGetRowMax()
4089 @*/
4090 PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4091 {
4092   PetscErrorCode ierr;
4093 
4094   PetscFunctionBegin;
4095   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4096   PetscValidType(mat,1);
4097   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4098   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4099   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4100   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4101 
4102   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4103   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4104   PetscFunctionReturn(0);
4105 }
4106 
4107 #undef __FUNCT__
4108 #define __FUNCT__ "MatGetRowMinAbs"
4109 /*@
4110    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4111         row of the matrix
4112 
4113    Logically Collective on Mat and Vec
4114 
4115    Input Parameters:
4116 .  mat - the matrix
4117 
4118    Output Parameter:
4119 +  v - the vector for storing the minimums
4120 -  idx - the indices of the column found for each row (optional)
4121 
4122    Level: intermediate
4123 
4124    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4125     row is 0 (the first column).
4126 
4127     This code is only implemented for a couple of matrix formats.
4128 
4129    Concepts: matrices^getting row maximums
4130 
4131 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4132 @*/
4133 PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4134 {
4135   PetscErrorCode ierr;
4136 
4137   PetscFunctionBegin;
4138   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4139   PetscValidType(mat,1);
4140   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4141   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4142   if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4143   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4144   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4145 
4146   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4147   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4148   PetscFunctionReturn(0);
4149 }
4150 
4151 #undef __FUNCT__
4152 #define __FUNCT__ "MatGetRowMax"
4153 /*@
4154    MatGetRowMax - Gets the maximum value (of the real part) of each
4155         row of the matrix
4156 
4157    Logically Collective on Mat and Vec
4158 
4159    Input Parameters:
4160 .  mat - the matrix
4161 
4162    Output Parameter:
4163 +  v - the vector for storing the maximums
4164 -  idx - the indices of the column found for each row (optional)
4165 
4166    Level: intermediate
4167 
4168    Notes: The result of this call are the same as if one converted the matrix to dense format
4169       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4170 
4171     This code is only implemented for a couple of matrix formats.
4172 
4173    Concepts: matrices^getting row maximums
4174 
4175 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4176 @*/
4177 PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4178 {
4179   PetscErrorCode ierr;
4180 
4181   PetscFunctionBegin;
4182   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4183   PetscValidType(mat,1);
4184   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4185   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4186   if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4187   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4188 
4189   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4190   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4191   PetscFunctionReturn(0);
4192 }
4193 
4194 #undef __FUNCT__
4195 #define __FUNCT__ "MatGetRowMaxAbs"
4196 /*@
4197    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4198         row of the matrix
4199 
4200    Logically Collective on Mat and Vec
4201 
4202    Input Parameters:
4203 .  mat - the matrix
4204 
4205    Output Parameter:
4206 +  v - the vector for storing the maximums
4207 -  idx - the indices of the column found for each row (optional)
4208 
4209    Level: intermediate
4210 
4211    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4212     row is 0 (the first column).
4213 
4214     This code is only implemented for a couple of matrix formats.
4215 
4216    Concepts: matrices^getting row maximums
4217 
4218 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4219 @*/
4220 PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4221 {
4222   PetscErrorCode ierr;
4223 
4224   PetscFunctionBegin;
4225   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4226   PetscValidType(mat,1);
4227   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4228   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4229   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4230   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4231   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4232 
4233   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4234   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4235   PetscFunctionReturn(0);
4236 }
4237 
4238 #undef __FUNCT__
4239 #define __FUNCT__ "MatGetRowSum"
4240 /*@
4241    MatGetRowSum - Gets the sum of each row of the matrix
4242 
4243    Logically Collective on Mat and Vec
4244 
4245    Input Parameters:
4246 .  mat - the matrix
4247 
4248    Output Parameter:
4249 .  v - the vector for storing the sum of rows
4250 
4251    Level: intermediate
4252 
4253    Notes: This code is slow since it is not currently specialized for different formats
4254 
4255    Concepts: matrices^getting row sums
4256 
4257 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4258 @*/
4259 PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4260 {
4261   PetscInt       start = 0, end = 0, row;
4262   PetscScalar   *array;
4263   PetscErrorCode ierr;
4264 
4265   PetscFunctionBegin;
4266   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4267   PetscValidType(mat,1);
4268   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4269   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4270   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4271   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
4272   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
4273   for(row = start; row < end; ++row) {
4274     PetscInt           ncols, col;
4275     const PetscInt    *cols;
4276     const PetscScalar *vals;
4277 
4278     array[row - start] = 0.0;
4279     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4280     for(col = 0; col < ncols; col++) {
4281       array[row - start] += vals[col];
4282     }
4283     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4284   }
4285   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
4286   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
4287   PetscFunctionReturn(0);
4288 }
4289 
4290 #undef __FUNCT__
4291 #define __FUNCT__ "MatTranspose"
4292 /*@
4293    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4294 
4295    Collective on Mat
4296 
4297    Input Parameter:
4298 +  mat - the matrix to transpose
4299 -  reuse - store the transpose matrix in the provided B
4300 
4301    Output Parameters:
4302 .  B - the transpose
4303 
4304    Notes:
4305      If you  pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4306 
4307    Level: intermediate
4308 
4309    Concepts: matrices^transposing
4310 
4311 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4312 @*/
4313 PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4314 {
4315   PetscErrorCode ierr;
4316 
4317   PetscFunctionBegin;
4318   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4319   PetscValidType(mat,1);
4320   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4321   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4322   if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4323   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4324 
4325   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4326   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4327   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4328   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4329   PetscFunctionReturn(0);
4330 }
4331 
4332 #undef __FUNCT__
4333 #define __FUNCT__ "MatIsTranspose"
4334 /*@
4335    MatIsTranspose - Test whether a matrix is another one's transpose,
4336         or its own, in which case it tests symmetry.
4337 
4338    Collective on Mat
4339 
4340    Input Parameter:
4341 +  A - the matrix to test
4342 -  B - the matrix to test against, this can equal the first parameter
4343 
4344    Output Parameters:
4345 .  flg - the result
4346 
4347    Notes:
4348    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4349    has a running time of the order of the number of nonzeros; the parallel
4350    test involves parallel copies of the block-offdiagonal parts of the matrix.
4351 
4352    Level: intermediate
4353 
4354    Concepts: matrices^transposing, matrix^symmetry
4355 
4356 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4357 @*/
4358 PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4359 {
4360   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4361 
4362   PetscFunctionBegin;
4363   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4364   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4365   PetscValidPointer(flg,3);
4366   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4367   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4368   if (f && g) {
4369     if (f==g) {
4370       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4371     } else {
4372       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4373     }
4374   }
4375   PetscFunctionReturn(0);
4376 }
4377 
4378 #undef __FUNCT__
4379 #define __FUNCT__ "MatHermitianTranspose"
4380 /*@
4381    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4382 
4383    Collective on Mat
4384 
4385    Input Parameter:
4386 +  mat - the matrix to transpose and complex conjugate
4387 -  reuse - store the transpose matrix in the provided B
4388 
4389    Output Parameters:
4390 .  B - the Hermitian
4391 
4392    Notes:
4393      If you  pass in &mat for B the Hermitian will be done in place
4394 
4395    Level: intermediate
4396 
4397    Concepts: matrices^transposing, complex conjugatex
4398 
4399 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4400 @*/
4401 PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4402 {
4403   PetscErrorCode ierr;
4404 
4405   PetscFunctionBegin;
4406   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4407 #if defined(PETSC_USE_COMPLEX)
4408   ierr = MatConjugate(*B);CHKERRQ(ierr);
4409 #endif
4410   PetscFunctionReturn(0);
4411 }
4412 
4413 #undef __FUNCT__
4414 #define __FUNCT__ "MatIsHermitianTranspose"
4415 /*@
4416    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4417 
4418    Collective on Mat
4419 
4420    Input Parameter:
4421 +  A - the matrix to test
4422 -  B - the matrix to test against, this can equal the first parameter
4423 
4424    Output Parameters:
4425 .  flg - the result
4426 
4427    Notes:
4428    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4429    has a running time of the order of the number of nonzeros; the parallel
4430    test involves parallel copies of the block-offdiagonal parts of the matrix.
4431 
4432    Level: intermediate
4433 
4434    Concepts: matrices^transposing, matrix^symmetry
4435 
4436 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4437 @*/
4438 PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4439 {
4440   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4441 
4442   PetscFunctionBegin;
4443   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4444   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4445   PetscValidPointer(flg,3);
4446   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4447   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4448   if (f && g) {
4449     if (f==g) {
4450       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4451     } else {
4452       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4453     }
4454   }
4455   PetscFunctionReturn(0);
4456 }
4457 
4458 #undef __FUNCT__
4459 #define __FUNCT__ "MatPermute"
4460 /*@
4461    MatPermute - Creates a new matrix with rows and columns permuted from the
4462    original.
4463 
4464    Collective on Mat
4465 
4466    Input Parameters:
4467 +  mat - the matrix to permute
4468 .  row - row permutation, each processor supplies only the permutation for its rows
4469 -  col - column permutation, each processor needs the entire column permutation, that is
4470          this is the same size as the total number of columns in the matrix. It can often
4471          be obtained with ISAllGather() on the row permutation
4472 
4473    Output Parameters:
4474 .  B - the permuted matrix
4475 
4476    Level: advanced
4477 
4478    Concepts: matrices^permuting
4479 
4480 .seealso: MatGetOrdering(), ISAllGather()
4481 
4482 @*/
4483 PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4484 {
4485   PetscErrorCode ierr;
4486 
4487   PetscFunctionBegin;
4488   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4489   PetscValidType(mat,1);
4490   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4491   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4492   PetscValidPointer(B,4);
4493   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4494   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4495   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4496   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4497 
4498   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4499   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4500   PetscFunctionReturn(0);
4501 }
4502 
4503 #undef __FUNCT__
4504 #define __FUNCT__ "MatEqual"
4505 /*@
4506    MatEqual - Compares two matrices.
4507 
4508    Collective on Mat
4509 
4510    Input Parameters:
4511 +  A - the first matrix
4512 -  B - the second matrix
4513 
4514    Output Parameter:
4515 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4516 
4517    Level: intermediate
4518 
4519    Concepts: matrices^equality between
4520 @*/
4521 PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4522 {
4523   PetscErrorCode ierr;
4524 
4525   PetscFunctionBegin;
4526   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4527   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4528   PetscValidType(A,1);
4529   PetscValidType(B,2);
4530   PetscValidIntPointer(flg,3);
4531   PetscCheckSameComm(A,1,B,2);
4532   ierr = MatPreallocated(B);CHKERRQ(ierr);
4533   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4534   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4535   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);
4536   if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4537   if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4538   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);
4539   ierr = MatPreallocated(A);CHKERRQ(ierr);
4540 
4541   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4542   PetscFunctionReturn(0);
4543 }
4544 
4545 #undef __FUNCT__
4546 #define __FUNCT__ "MatDiagonalScale"
4547 /*@
4548    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4549    matrices that are stored as vectors.  Either of the two scaling
4550    matrices can be PETSC_NULL.
4551 
4552    Collective on Mat
4553 
4554    Input Parameters:
4555 +  mat - the matrix to be scaled
4556 .  l - the left scaling vector (or PETSC_NULL)
4557 -  r - the right scaling vector (or PETSC_NULL)
4558 
4559    Notes:
4560    MatDiagonalScale() computes A = LAR, where
4561    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4562    The L scales the rows of the matrix, the R scales the columns of the matrix.
4563 
4564    Level: intermediate
4565 
4566    Concepts: matrices^diagonal scaling
4567    Concepts: diagonal scaling of matrices
4568 
4569 .seealso: MatScale()
4570 @*/
4571 PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4572 {
4573   PetscErrorCode ierr;
4574 
4575   PetscFunctionBegin;
4576   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4577   PetscValidType(mat,1);
4578   if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4579   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4580   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4581   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4582   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4583   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4584 
4585   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4586   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4587   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4588   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4589 #if defined(PETSC_HAVE_CUSP)
4590   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4591     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4592   }
4593 #endif
4594   PetscFunctionReturn(0);
4595 }
4596 
4597 #undef __FUNCT__
4598 #define __FUNCT__ "MatScale"
4599 /*@
4600     MatScale - Scales all elements of a matrix by a given number.
4601 
4602     Logically Collective on Mat
4603 
4604     Input Parameters:
4605 +   mat - the matrix to be scaled
4606 -   a  - the scaling value
4607 
4608     Output Parameter:
4609 .   mat - the scaled matrix
4610 
4611     Level: intermediate
4612 
4613     Concepts: matrices^scaling all entries
4614 
4615 .seealso: MatDiagonalScale()
4616 @*/
4617 PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4618 {
4619   PetscErrorCode ierr;
4620 
4621   PetscFunctionBegin;
4622   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4623   PetscValidType(mat,1);
4624   if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4625   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4626   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4627   PetscValidLogicalCollectiveScalar(mat,a,2);
4628   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4629 
4630   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4631   if (a != 1.0) {
4632     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4633     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4634   }
4635   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4636 #if defined(PETSC_HAVE_CUSP)
4637   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4638     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4639   }
4640 #endif
4641   PetscFunctionReturn(0);
4642 }
4643 
4644 #undef __FUNCT__
4645 #define __FUNCT__ "MatNorm"
4646 /*@
4647    MatNorm - Calculates various norms of a matrix.
4648 
4649    Collective on Mat
4650 
4651    Input Parameters:
4652 +  mat - the matrix
4653 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4654 
4655    Output Parameters:
4656 .  nrm - the resulting norm
4657 
4658    Level: intermediate
4659 
4660    Concepts: matrices^norm
4661    Concepts: norm^of matrix
4662 @*/
4663 PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4664 {
4665   PetscErrorCode ierr;
4666 
4667   PetscFunctionBegin;
4668   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4669   PetscValidType(mat,1);
4670   PetscValidScalarPointer(nrm,3);
4671 
4672   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4673   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4674   if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4675   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4676 
4677   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4678   PetscFunctionReturn(0);
4679 }
4680 
4681 /*
4682      This variable is used to prevent counting of MatAssemblyBegin() that
4683    are called from within a MatAssemblyEnd().
4684 */
4685 static PetscInt MatAssemblyEnd_InUse = 0;
4686 #undef __FUNCT__
4687 #define __FUNCT__ "MatAssemblyBegin"
4688 /*@
4689    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4690    be called after completing all calls to MatSetValues().
4691 
4692    Collective on Mat
4693 
4694    Input Parameters:
4695 +  mat - the matrix
4696 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4697 
4698    Notes:
4699    MatSetValues() generally caches the values.  The matrix is ready to
4700    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4701    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4702    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4703    using the matrix.
4704 
4705    Level: beginner
4706 
4707    Concepts: matrices^assembling
4708 
4709 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4710 @*/
4711 PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4712 {
4713   PetscErrorCode ierr;
4714 
4715   PetscFunctionBegin;
4716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4717   PetscValidType(mat,1);
4718   ierr = MatPreallocated(mat);CHKERRQ(ierr);
4719   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4720   if (mat->assembled) {
4721     mat->was_assembled = PETSC_TRUE;
4722     mat->assembled     = PETSC_FALSE;
4723   }
4724   if (!MatAssemblyEnd_InUse) {
4725     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4726     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4727     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4728   } else {
4729     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4730   }
4731   PetscFunctionReturn(0);
4732 }
4733 
4734 #undef __FUNCT__
4735 #define __FUNCT__ "MatAssembled"
4736 /*@
4737    MatAssembled - Indicates if a matrix has been assembled and is ready for
4738      use; for example, in matrix-vector product.
4739 
4740    Not Collective
4741 
4742    Input Parameter:
4743 .  mat - the matrix
4744 
4745    Output Parameter:
4746 .  assembled - PETSC_TRUE or PETSC_FALSE
4747 
4748    Level: advanced
4749 
4750    Concepts: matrices^assembled?
4751 
4752 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4753 @*/
4754 PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4755 {
4756   PetscFunctionBegin;
4757   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4758   PetscValidType(mat,1);
4759   PetscValidPointer(assembled,2);
4760   *assembled = mat->assembled;
4761   PetscFunctionReturn(0);
4762 }
4763 
4764 #undef __FUNCT__
4765 #define __FUNCT__ "MatView_Private"
4766 /*
4767     Processes command line options to determine if/how a matrix
4768   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4769 */
4770 PetscErrorCode MatView_Private(Mat mat)
4771 {
4772   PetscErrorCode    ierr;
4773   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4774   static PetscBool  incall = PETSC_FALSE;
4775 #if defined(PETSC_USE_SOCKET_VIEWER)
4776   PetscBool         flg5 = PETSC_FALSE;
4777 #endif
4778 
4779   PetscFunctionBegin;
4780   if (incall) PetscFunctionReturn(0);
4781   incall = PETSC_TRUE;
4782   ierr = PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
4783     ierr = PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr);
4784     ierr = PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr);
4785     ierr = PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr);
4786     ierr = PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr);
4787 #if defined(PETSC_USE_SOCKET_VIEWER)
4788     ierr = PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr);
4789 #endif
4790     ierr = PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr);
4791     ierr = PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr);
4792   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4793 
4794   if (flg1) {
4795     PetscViewer viewer;
4796 
4797     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4798     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4799     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4800     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4801   }
4802   if (flg2) {
4803     PetscViewer viewer;
4804 
4805     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4806     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4807     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4808     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4809   }
4810   if (flg3) {
4811     PetscViewer viewer;
4812 
4813     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4814     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4815   }
4816   if (flg4) {
4817     PetscViewer viewer;
4818 
4819     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4820     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4821     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4822     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4823   }
4824 #if defined(PETSC_USE_SOCKET_VIEWER)
4825   if (flg5) {
4826     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4827     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4828   }
4829 #endif
4830   if (flg6) {
4831     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4832     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4833   }
4834   if (flg7) {
4835     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr);
4836     if (flg8) {
4837       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4838     }
4839     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4840     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4841     if (flg8) {
4842       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4843     }
4844   }
4845   incall = PETSC_FALSE;
4846   PetscFunctionReturn(0);
4847 }
4848 
4849 #undef __FUNCT__
4850 #define __FUNCT__ "MatAssemblyEnd"
4851 /*@
4852    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4853    be called after MatAssemblyBegin().
4854 
4855    Collective on Mat
4856 
4857    Input Parameters:
4858 +  mat - the matrix
4859 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4860 
4861    Options Database Keys:
4862 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4863 .  -mat_view_info_detailed - Prints more detailed info
4864 .  -mat_view - Prints matrix in ASCII format
4865 .  -mat_view_matlab - Prints matrix in Matlab format
4866 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4867 .  -display <name> - Sets display name (default is host)
4868 .  -draw_pause <sec> - Sets number of seconds to pause after display
4869 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4870 .  -viewer_socket_machine <machine>
4871 .  -viewer_socket_port <port>
4872 .  -mat_view_binary - save matrix to file in binary format
4873 -  -viewer_binary_filename <name>
4874 
4875    Notes:
4876    MatSetValues() generally caches the values.  The matrix is ready to
4877    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4878    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4879    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4880    using the matrix.
4881 
4882    Level: beginner
4883 
4884 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4885 @*/
4886 PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4887 {
4888   PetscErrorCode  ierr;
4889   static PetscInt inassm = 0;
4890   PetscBool       flg = PETSC_FALSE;
4891 
4892   PetscFunctionBegin;
4893   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4894   PetscValidType(mat,1);
4895 
4896   inassm++;
4897   MatAssemblyEnd_InUse++;
4898   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4899     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4900     if (mat->ops->assemblyend) {
4901       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4902     }
4903     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4904   } else {
4905     if (mat->ops->assemblyend) {
4906       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4907     }
4908   }
4909 
4910   /* Flush assembly is not a true assembly */
4911   if (type != MAT_FLUSH_ASSEMBLY) {
4912     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4913   }
4914   mat->insertmode = NOT_SET_VALUES;
4915   MatAssemblyEnd_InUse--;
4916   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4917   if (!mat->symmetric_eternal) {
4918     mat->symmetric_set              = PETSC_FALSE;
4919     mat->hermitian_set              = PETSC_FALSE;
4920     mat->structurally_symmetric_set = PETSC_FALSE;
4921   }
4922   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4923     ierr = MatView_Private(mat);CHKERRQ(ierr);
4924     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);CHKERRQ(ierr);
4925     if (flg) {
4926       PetscReal tol = 0.0;
4927       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
4928       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
4929       if (flg) {
4930         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4931       } else {
4932         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
4933       }
4934     }
4935   }
4936   inassm--;
4937 #if defined(PETSC_HAVE_CUSP)
4938   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4939     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4940   }
4941 #endif
4942   PetscFunctionReturn(0);
4943 }
4944 
4945 #undef __FUNCT__
4946 #define __FUNCT__ "MatSetOption"
4947 /*@
4948    MatSetOption - Sets a parameter option for a matrix. Some options
4949    may be specific to certain storage formats.  Some options
4950    determine how values will be inserted (or added). Sorted,
4951    row-oriented input will generally assemble the fastest. The default
4952    is row-oriented, nonsorted input.
4953 
4954    Logically Collective on Mat
4955 
4956    Input Parameters:
4957 +  mat - the matrix
4958 .  option - the option, one of those listed below (and possibly others),
4959 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4960 
4961   Options Describing Matrix Structure:
4962 +    MAT_SPD - symmetric positive definite
4963 -    MAT_SYMMETRIC - symmetric in terms of both structure and value
4964 .    MAT_HERMITIAN - transpose is the complex conjugation
4965 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4966 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4967                             you set to be kept with all future use of the matrix
4968                             including after MatAssemblyBegin/End() which could
4969                             potentially change the symmetry structure, i.e. you
4970                             KNOW the matrix will ALWAYS have the property you set.
4971 
4972 
4973    Options For Use with MatSetValues():
4974    Insert a logically dense subblock, which can be
4975 .    MAT_ROW_ORIENTED - row-oriented (default)
4976 
4977    Note these options reflect the data you pass in with MatSetValues(); it has
4978    nothing to do with how the data is stored internally in the matrix
4979    data structure.
4980 
4981    When (re)assembling a matrix, we can restrict the input for
4982    efficiency/debugging purposes.  These options include
4983 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4984         allowed if they generate a new nonzero
4985 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4986 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4987 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4988 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4989 +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4990         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4991         performance for very large process counts.
4992 
4993    Notes:
4994    Some options are relevant only for particular matrix types and
4995    are thus ignored by others.  Other options are not supported by
4996    certain matrix types and will generate an error message if set.
4997 
4998    If using a Fortran 77 module to compute a matrix, one may need to
4999    use the column-oriented option (or convert to the row-oriented
5000    format).
5001 
5002    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5003    that would generate a new entry in the nonzero structure is instead
5004    ignored.  Thus, if memory has not alredy been allocated for this particular
5005    data, then the insertion is ignored. For dense matrices, in which
5006    the entire array is allocated, no entries are ever ignored.
5007    Set after the first MatAssemblyEnd()
5008 
5009    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5010    that would generate a new entry in the nonzero structure instead produces
5011    an error. (Currently supported for AIJ and BAIJ formats only.)
5012    This is a useful flag when using SAME_NONZERO_PATTERN in calling
5013    KSPSetOperators() to ensure that the nonzero pattern truely does
5014    remain unchanged. Set after the first MatAssemblyEnd()
5015 
5016    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5017    that would generate a new entry that has not been preallocated will
5018    instead produce an error. (Currently supported for AIJ and BAIJ formats
5019    only.) This is a useful flag when debugging matrix memory preallocation.
5020 
5021    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5022    other processors should be dropped, rather than stashed.
5023    This is useful if you know that the "owning" processor is also
5024    always generating the correct matrix entries, so that PETSc need
5025    not transfer duplicate entries generated on another processor.
5026 
5027    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5028    searches during matrix assembly. When this flag is set, the hash table
5029    is created during the first Matrix Assembly. This hash table is
5030    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5031    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5032    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5033    supported by MATMPIBAIJ format only.
5034 
5035    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5036    are kept in the nonzero structure
5037 
5038    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5039    a zero location in the matrix
5040 
5041    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5042    ROWBS matrix types
5043 
5044   MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5045         zero row routines and thus improves performance for very large process counts.
5046 
5047    Level: intermediate
5048 
5049    Concepts: matrices^setting options
5050 
5051 @*/
5052 PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5053 {
5054   PetscErrorCode ierr;
5055 
5056   PetscFunctionBegin;
5057   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5058   PetscValidType(mat,1);
5059   PetscValidLogicalCollectiveEnum(mat,op,2);
5060   PetscValidLogicalCollectiveBool(mat,flg,3);
5061 
5062   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);
5063   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()");
5064   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5065   switch (op) {
5066   case MAT_NO_OFF_PROC_ENTRIES:
5067     mat->nooffprocentries                = flg;
5068     PetscFunctionReturn(0);
5069     break;
5070   case MAT_NO_OFF_PROC_ZERO_ROWS:
5071     mat->nooffproczerorows               = flg;
5072     PetscFunctionReturn(0);
5073     break;
5074   case MAT_SPD:
5075     mat->spd_set                         = PETSC_TRUE;
5076     mat->spd                             = flg;
5077     if (flg) {
5078       mat->symmetric                     = PETSC_TRUE;
5079       mat->structurally_symmetric        = PETSC_TRUE;
5080       mat->symmetric_set                 = PETSC_TRUE;
5081       mat->structurally_symmetric_set    = PETSC_TRUE;
5082     }
5083     break;
5084   case MAT_SYMMETRIC:
5085     mat->symmetric                       = flg;
5086     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5087     mat->symmetric_set                   = PETSC_TRUE;
5088     mat->structurally_symmetric_set      = flg;
5089     break;
5090   case MAT_HERMITIAN:
5091     mat->hermitian                       = flg;
5092     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5093     mat->hermitian_set                   = PETSC_TRUE;
5094     mat->structurally_symmetric_set      = flg;
5095     break;
5096   case MAT_STRUCTURALLY_SYMMETRIC:
5097     mat->structurally_symmetric          = flg;
5098     mat->structurally_symmetric_set      = PETSC_TRUE;
5099     break;
5100   case MAT_SYMMETRY_ETERNAL:
5101     mat->symmetric_eternal               = flg;
5102     break;
5103   default:
5104     break;
5105   }
5106   if (mat->ops->setoption) {
5107     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5108   }
5109   PetscFunctionReturn(0);
5110 }
5111 
5112 #undef __FUNCT__
5113 #define __FUNCT__ "MatZeroEntries"
5114 /*@
5115    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5116    this routine retains the old nonzero structure.
5117 
5118    Logically Collective on Mat
5119 
5120    Input Parameters:
5121 .  mat - the matrix
5122 
5123    Level: intermediate
5124 
5125    Concepts: matrices^zeroing
5126 
5127 .seealso: MatZeroRows()
5128 @*/
5129 PetscErrorCode  MatZeroEntries(Mat mat)
5130 {
5131   PetscErrorCode ierr;
5132 
5133   PetscFunctionBegin;
5134   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5135   PetscValidType(mat,1);
5136   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5137   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");
5138   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5139   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5140 
5141   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5142   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5143   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5144   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5145 #if defined(PETSC_HAVE_CUSP)
5146   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5147     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5148   }
5149 #endif
5150   PetscFunctionReturn(0);
5151 }
5152 
5153 #undef __FUNCT__
5154 #define __FUNCT__ "MatZeroRowsColumns"
5155 /*@C
5156    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5157    of a set of rows and columns of a matrix.
5158 
5159    Collective on Mat
5160 
5161    Input Parameters:
5162 +  mat - the matrix
5163 .  numRows - the number of rows to remove
5164 .  rows - the global row indices
5165 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5166 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5167 -  b - optional vector of right hand side, that will be adjusted by provided solution
5168 
5169    Notes:
5170    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5171 
5172    The user can set a value in the diagonal entry (or for the AIJ and
5173    row formats can optionally remove the main diagonal entry from the
5174    nonzero structure as well, by passing 0.0 as the final argument).
5175 
5176    For the parallel case, all processes that share the matrix (i.e.,
5177    those in the communicator used for matrix creation) MUST call this
5178    routine, regardless of whether any rows being zeroed are owned by
5179    them.
5180 
5181    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5182    list only rows local to itself).
5183 
5184    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5185 
5186    Level: intermediate
5187 
5188    Concepts: matrices^zeroing rows
5189 
5190 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5191 @*/
5192 PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5193 {
5194   PetscErrorCode ierr;
5195 
5196   PetscFunctionBegin;
5197   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5198   PetscValidType(mat,1);
5199   if (numRows) PetscValidIntPointer(rows,3);
5200   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5201   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5202   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5203   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5204 
5205   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5206   ierr = MatView_Private(mat);CHKERRQ(ierr);
5207   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5208 #if defined(PETSC_HAVE_CUSP)
5209   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5210     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5211   }
5212 #endif
5213   PetscFunctionReturn(0);
5214 }
5215 
5216 #undef __FUNCT__
5217 #define __FUNCT__ "MatZeroRowsColumnsIS"
5218 /*@C
5219    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5220    of a set of rows and columns of a matrix.
5221 
5222    Collective on Mat
5223 
5224    Input Parameters:
5225 +  mat - the matrix
5226 .  is - the rows to zero
5227 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5228 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5229 -  b - optional vector of right hand side, that will be adjusted by provided solution
5230 
5231    Notes:
5232    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5233 
5234    The user can set a value in the diagonal entry (or for the AIJ and
5235    row formats can optionally remove the main diagonal entry from the
5236    nonzero structure as well, by passing 0.0 as the final argument).
5237 
5238    For the parallel case, all processes that share the matrix (i.e.,
5239    those in the communicator used for matrix creation) MUST call this
5240    routine, regardless of whether any rows being zeroed are owned by
5241    them.
5242 
5243    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5244    list only rows local to itself).
5245 
5246    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5247 
5248    Level: intermediate
5249 
5250    Concepts: matrices^zeroing rows
5251 
5252 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5253 @*/
5254 PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5255 {
5256   PetscErrorCode ierr;
5257   PetscInt       numRows;
5258   const PetscInt *rows;
5259 
5260   PetscFunctionBegin;
5261   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5262   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5263   PetscValidType(mat,1);
5264   PetscValidType(is,2);
5265   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5266   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5267   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5268   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5269   PetscFunctionReturn(0);
5270 }
5271 
5272 #undef __FUNCT__
5273 #define __FUNCT__ "MatZeroRows"
5274 /*@C
5275    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5276    of a set of rows of a matrix.
5277 
5278    Collective on Mat
5279 
5280    Input Parameters:
5281 +  mat - the matrix
5282 .  numRows - the number of rows to remove
5283 .  rows - the global row indices
5284 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5285 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5286 -  b - optional vector of right hand side, that will be adjusted by provided solution
5287 
5288    Notes:
5289    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5290    but does not release memory.  For the dense and block diagonal
5291    formats this does not alter the nonzero structure.
5292 
5293    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5294    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5295    merely zeroed.
5296 
5297    The user can set a value in the diagonal entry (or for the AIJ and
5298    row formats can optionally remove the main diagonal entry from the
5299    nonzero structure as well, by passing 0.0 as the final argument).
5300 
5301    For the parallel case, all processes that share the matrix (i.e.,
5302    those in the communicator used for matrix creation) MUST call this
5303    routine, regardless of whether any rows being zeroed are owned by
5304    them.
5305 
5306    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5307    list only rows local to itself).
5308 
5309    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5310    owns that are to be zeroed. This saves a global synchronization in the implementation.
5311 
5312    Level: intermediate
5313 
5314    Concepts: matrices^zeroing rows
5315 
5316 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5317 @*/
5318 PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5319 {
5320   PetscErrorCode ierr;
5321 
5322   PetscFunctionBegin;
5323   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5324   PetscValidType(mat,1);
5325   if (numRows) PetscValidIntPointer(rows,3);
5326   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5327   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5328   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5329   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5330 
5331   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5332   ierr = MatView_Private(mat);CHKERRQ(ierr);
5333   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5334 #if defined(PETSC_HAVE_CUSP)
5335   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5336     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5337   }
5338 #endif
5339   PetscFunctionReturn(0);
5340 }
5341 
5342 #undef __FUNCT__
5343 #define __FUNCT__ "MatZeroRowsIS"
5344 /*@C
5345    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5346    of a set of rows of a matrix.
5347 
5348    Collective on Mat
5349 
5350    Input Parameters:
5351 +  mat - the matrix
5352 .  is - index set of rows to remove
5353 .  diag - value put in all diagonals of eliminated rows
5354 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5355 -  b - optional vector of right hand side, that will be adjusted by provided solution
5356 
5357    Notes:
5358    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5359    but does not release memory.  For the dense and block diagonal
5360    formats this does not alter the nonzero structure.
5361 
5362    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5363    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5364    merely zeroed.
5365 
5366    The user can set a value in the diagonal entry (or for the AIJ and
5367    row formats can optionally remove the main diagonal entry from the
5368    nonzero structure as well, by passing 0.0 as the final argument).
5369 
5370    For the parallel case, all processes that share the matrix (i.e.,
5371    those in the communicator used for matrix creation) MUST call this
5372    routine, regardless of whether any rows being zeroed are owned by
5373    them.
5374 
5375    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5376    list only rows local to itself).
5377 
5378    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5379    owns that are to be zeroed. This saves a global synchronization in the implementation.
5380 
5381    Level: intermediate
5382 
5383    Concepts: matrices^zeroing rows
5384 
5385 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5386 @*/
5387 PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5388 {
5389   PetscInt       numRows;
5390   const PetscInt *rows;
5391   PetscErrorCode ierr;
5392 
5393   PetscFunctionBegin;
5394   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5395   PetscValidType(mat,1);
5396   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5397   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5398   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5399   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5400   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5401   PetscFunctionReturn(0);
5402 }
5403 
5404 #undef __FUNCT__
5405 #define __FUNCT__ "MatZeroRowsStencil"
5406 /*@C
5407    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5408    of a set of rows of a matrix. These rows must be local to the process.
5409 
5410    Collective on Mat
5411 
5412    Input Parameters:
5413 +  mat - the matrix
5414 .  numRows - the number of rows to remove
5415 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5416 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5417 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5418 -  b - optional vector of right hand side, that will be adjusted by provided solution
5419 
5420    Notes:
5421    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5422    but does not release memory.  For the dense and block diagonal
5423    formats this does not alter the nonzero structure.
5424 
5425    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5426    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5427    merely zeroed.
5428 
5429    The user can set a value in the diagonal entry (or for the AIJ and
5430    row formats can optionally remove the main diagonal entry from the
5431    nonzero structure as well, by passing 0.0 as the final argument).
5432 
5433    For the parallel case, all processes that share the matrix (i.e.,
5434    those in the communicator used for matrix creation) MUST call this
5435    routine, regardless of whether any rows being zeroed are owned by
5436    them.
5437 
5438    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5439    list only rows local to itself).
5440 
5441    The grid coordinates are across the entire grid, not just the local portion
5442 
5443    In Fortran idxm and idxn should be declared as
5444 $     MatStencil idxm(4,m)
5445    and the values inserted using
5446 $    idxm(MatStencil_i,1) = i
5447 $    idxm(MatStencil_j,1) = j
5448 $    idxm(MatStencil_k,1) = k
5449 $    idxm(MatStencil_c,1) = c
5450    etc
5451 
5452    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5453    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5454    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5455    DMDA_BOUNDARY_PERIODIC boundary type.
5456 
5457    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
5458    a single value per point) you can skip filling those indices.
5459 
5460    Level: intermediate
5461 
5462    Concepts: matrices^zeroing rows
5463 
5464 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5465 @*/
5466 PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5467 {
5468   PetscInt       dim    = mat->stencil.dim;
5469   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5470   PetscInt      *dims   = mat->stencil.dims+1;
5471   PetscInt      *starts = mat->stencil.starts;
5472   PetscInt      *dxm    = (PetscInt *) rows;
5473   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5474   PetscErrorCode ierr;
5475 
5476   PetscFunctionBegin;
5477   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5478   PetscValidType(mat,1);
5479   if (numRows) PetscValidIntPointer(rows,3);
5480 
5481   ierr = PetscMalloc(numRows * sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5482   for(i = 0; i < numRows; ++i) {
5483     /* Skip unused dimensions (they are ordered k, j, i, c) */
5484     for(j = 0; j < 3-sdim; ++j) dxm++;
5485     /* Local index in X dir */
5486     tmp = *dxm++ - starts[0];
5487     /* Loop over remaining dimensions */
5488     for(j = 0; j < dim-1; ++j) {
5489       /* If nonlocal, set index to be negative */
5490       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5491       /* Update local index */
5492       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5493     }
5494     /* Skip component slot if necessary */
5495     if (mat->stencil.noc) dxm++;
5496     /* Local row number */
5497     if (tmp >= 0) {
5498       jdxm[numNewRows++] = tmp;
5499     }
5500   }
5501   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5502   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5503   PetscFunctionReturn(0);
5504 }
5505 
5506 #undef __FUNCT__
5507 #define __FUNCT__ "MatZeroRowsLocal"
5508 /*@C
5509    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5510    of a set of rows of a matrix; using local numbering of rows.
5511 
5512    Collective on Mat
5513 
5514    Input Parameters:
5515 +  mat - the matrix
5516 .  numRows - the number of rows to remove
5517 .  rows - the global row indices
5518 .  diag - value put in all diagonals of eliminated rows
5519 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5520 -  b - optional vector of right hand side, that will be adjusted by provided solution
5521 
5522    Notes:
5523    Before calling MatZeroRowsLocal(), the user must first set the
5524    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5525 
5526    For the AIJ matrix formats this removes the old nonzero structure,
5527    but does not release memory.  For the dense and block diagonal
5528    formats this does not alter the nonzero structure.
5529 
5530    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5531    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5532    merely zeroed.
5533 
5534    The user can set a value in the diagonal entry (or for the AIJ and
5535    row formats can optionally remove the main diagonal entry from the
5536    nonzero structure as well, by passing 0.0 as the final argument).
5537 
5538    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5539    owns that are to be zeroed. This saves a global synchronization in the implementation.
5540 
5541    Level: intermediate
5542 
5543    Concepts: matrices^zeroing
5544 
5545 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5546 @*/
5547 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5548 {
5549   PetscErrorCode ierr;
5550   PetscMPIInt    size;
5551 
5552   PetscFunctionBegin;
5553   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5554   PetscValidType(mat,1);
5555   if (numRows) PetscValidIntPointer(rows,3);
5556   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5557   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5558   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5559 
5560   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5561   if (mat->ops->zerorowslocal) {
5562     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5563   } else if (size == 1) {
5564     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5565   } else {
5566     IS             is, newis;
5567     const PetscInt *newRows;
5568 
5569     if (!mat->rmapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5570     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5571     ierr = ISLocalToGlobalMappingApplyIS(mat->rmapping,is,&newis);CHKERRQ(ierr);
5572     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5573     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5574     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5575     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5576     ierr = ISDestroy(&is);CHKERRQ(ierr);
5577   }
5578   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5579 #if defined(PETSC_HAVE_CUSP)
5580   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5581     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5582   }
5583 #endif
5584   PetscFunctionReturn(0);
5585 }
5586 
5587 #undef __FUNCT__
5588 #define __FUNCT__ "MatZeroRowsLocalIS"
5589 /*@C
5590    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5591    of a set of rows of a matrix; using local numbering of rows.
5592 
5593    Collective on Mat
5594 
5595    Input Parameters:
5596 +  mat - the matrix
5597 .  is - index set of rows to remove
5598 .  diag - value put in all diagonals of eliminated rows
5599 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5600 -  b - optional vector of right hand side, that will be adjusted by provided solution
5601 
5602    Notes:
5603    Before calling MatZeroRowsLocalIS(), the user must first set the
5604    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5605 
5606    For the AIJ matrix formats this removes the old nonzero structure,
5607    but does not release memory.  For the dense and block diagonal
5608    formats this does not alter the nonzero structure.
5609 
5610    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5611    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5612    merely zeroed.
5613 
5614    The user can set a value in the diagonal entry (or for the AIJ and
5615    row formats can optionally remove the main diagonal entry from the
5616    nonzero structure as well, by passing 0.0 as the final argument).
5617 
5618    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5619    owns that are to be zeroed. This saves a global synchronization in the implementation.
5620 
5621    Level: intermediate
5622 
5623    Concepts: matrices^zeroing
5624 
5625 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5626 @*/
5627 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5628 {
5629   PetscErrorCode ierr;
5630   PetscInt       numRows;
5631   const PetscInt *rows;
5632 
5633   PetscFunctionBegin;
5634   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5635   PetscValidType(mat,1);
5636   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5637   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5638   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5639   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5640 
5641   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5642   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5643   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5644   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5645   PetscFunctionReturn(0);
5646 }
5647 
5648 #undef __FUNCT__
5649 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5650 /*@C
5651    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5652    of a set of rows and columns of a matrix; using local numbering of rows.
5653 
5654    Collective on Mat
5655 
5656    Input Parameters:
5657 +  mat - the matrix
5658 .  numRows - the number of rows to remove
5659 .  rows - the global row indices
5660 .  diag - value put in all diagonals of eliminated rows
5661 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5662 -  b - optional vector of right hand side, that will be adjusted by provided solution
5663 
5664    Notes:
5665    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5666    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5667 
5668    The user can set a value in the diagonal entry (or for the AIJ and
5669    row formats can optionally remove the main diagonal entry from the
5670    nonzero structure as well, by passing 0.0 as the final argument).
5671 
5672    Level: intermediate
5673 
5674    Concepts: matrices^zeroing
5675 
5676 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5677 @*/
5678 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5679 {
5680   PetscErrorCode ierr;
5681   PetscMPIInt    size;
5682 
5683   PetscFunctionBegin;
5684   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5685   PetscValidType(mat,1);
5686   if (numRows) PetscValidIntPointer(rows,3);
5687   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5688   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5689   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5690 
5691   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5692   if (size == 1) {
5693     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5694   } else {
5695     IS             is, newis;
5696     const PetscInt *newRows;
5697 
5698     if (!mat->cmapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5699     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5700     ierr = ISLocalToGlobalMappingApplyIS(mat->cmapping,is,&newis);CHKERRQ(ierr);
5701     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5702     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5703     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5704     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5705     ierr = ISDestroy(&is);CHKERRQ(ierr);
5706   }
5707   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5708 #if defined(PETSC_HAVE_CUSP)
5709   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5710     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5711   }
5712 #endif
5713   PetscFunctionReturn(0);
5714 }
5715 
5716 #undef __FUNCT__
5717 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5718 /*@C
5719    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5720    of a set of rows and columns of a matrix; using local numbering of rows.
5721 
5722    Collective on Mat
5723 
5724    Input Parameters:
5725 +  mat - the matrix
5726 .  is - index set of rows to remove
5727 .  diag - value put in all diagonals of eliminated rows
5728 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5729 -  b - optional vector of right hand side, that will be adjusted by provided solution
5730 
5731    Notes:
5732    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5733    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5734 
5735    The user can set a value in the diagonal entry (or for the AIJ and
5736    row formats can optionally remove the main diagonal entry from the
5737    nonzero structure as well, by passing 0.0 as the final argument).
5738 
5739    Level: intermediate
5740 
5741    Concepts: matrices^zeroing
5742 
5743 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5744 @*/
5745 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5746 {
5747   PetscErrorCode ierr;
5748   PetscInt       numRows;
5749   const PetscInt *rows;
5750 
5751   PetscFunctionBegin;
5752   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5753   PetscValidType(mat,1);
5754   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5755   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5756   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5757   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5758 
5759   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5760   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5761   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5762   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5763   PetscFunctionReturn(0);
5764 }
5765 
5766 #undef __FUNCT__
5767 #define __FUNCT__ "MatGetSize"
5768 /*@
5769    MatGetSize - Returns the numbers of rows and columns in a matrix.
5770 
5771    Not Collective
5772 
5773    Input Parameter:
5774 .  mat - the matrix
5775 
5776    Output Parameters:
5777 +  m - the number of global rows
5778 -  n - the number of global columns
5779 
5780    Note: both output parameters can be PETSC_NULL on input.
5781 
5782    Level: beginner
5783 
5784    Concepts: matrices^size
5785 
5786 .seealso: MatGetLocalSize()
5787 @*/
5788 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5789 {
5790   PetscFunctionBegin;
5791   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5792   if (m) *m = mat->rmap->N;
5793   if (n) *n = mat->cmap->N;
5794   PetscFunctionReturn(0);
5795 }
5796 
5797 #undef __FUNCT__
5798 #define __FUNCT__ "MatGetLocalSize"
5799 /*@
5800    MatGetLocalSize - Returns the number of rows and columns in a matrix
5801    stored locally.  This information may be implementation dependent, so
5802    use with care.
5803 
5804    Not Collective
5805 
5806    Input Parameters:
5807 .  mat - the matrix
5808 
5809    Output Parameters:
5810 +  m - the number of local rows
5811 -  n - the number of local columns
5812 
5813    Note: both output parameters can be PETSC_NULL on input.
5814 
5815    Level: beginner
5816 
5817    Concepts: matrices^local size
5818 
5819 .seealso: MatGetSize()
5820 @*/
5821 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5822 {
5823   PetscFunctionBegin;
5824   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5825   if (m) PetscValidIntPointer(m,2);
5826   if (n) PetscValidIntPointer(n,3);
5827   if (m) *m = mat->rmap->n;
5828   if (n) *n = mat->cmap->n;
5829   PetscFunctionReturn(0);
5830 }
5831 
5832 #undef __FUNCT__
5833 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5834 /*@
5835    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5836    this processor.
5837 
5838    Not Collective, unless matrix has not been allocated, then collective on Mat
5839 
5840    Input Parameters:
5841 .  mat - the matrix
5842 
5843    Output Parameters:
5844 +  m - the global index of the first local column
5845 -  n - one more than the global index of the last local column
5846 
5847    Notes: both output parameters can be PETSC_NULL on input.
5848 
5849    Level: developer
5850 
5851    Concepts: matrices^column ownership
5852 
5853 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5854 
5855 @*/
5856 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5857 {
5858   PetscErrorCode ierr;
5859 
5860   PetscFunctionBegin;
5861   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5862   PetscValidType(mat,1);
5863   if (m) PetscValidIntPointer(m,2);
5864   if (n) PetscValidIntPointer(n,3);
5865   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5866   if (m) *m = mat->cmap->rstart;
5867   if (n) *n = mat->cmap->rend;
5868   PetscFunctionReturn(0);
5869 }
5870 
5871 #undef __FUNCT__
5872 #define __FUNCT__ "MatGetOwnershipRange"
5873 /*@
5874    MatGetOwnershipRange - Returns the range of matrix rows owned by
5875    this processor, assuming that the matrix is laid out with the first
5876    n1 rows on the first processor, the next n2 rows on the second, etc.
5877    For certain parallel layouts this range may not be well defined.
5878 
5879    Not Collective, unless matrix has not been allocated, then collective on Mat
5880 
5881    Input Parameters:
5882 .  mat - the matrix
5883 
5884    Output Parameters:
5885 +  m - the global index of the first local row
5886 -  n - one more than the global index of the last local row
5887 
5888    Note: both output parameters can be PETSC_NULL on input.
5889 
5890    Level: beginner
5891 
5892    Concepts: matrices^row ownership
5893 
5894 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5895 
5896 @*/
5897 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5898 {
5899   PetscErrorCode ierr;
5900 
5901   PetscFunctionBegin;
5902   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5903   PetscValidType(mat,1);
5904   if (m) PetscValidIntPointer(m,2);
5905   if (n) PetscValidIntPointer(n,3);
5906   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5907   if (m) *m = mat->rmap->rstart;
5908   if (n) *n = mat->rmap->rend;
5909   PetscFunctionReturn(0);
5910 }
5911 
5912 #undef __FUNCT__
5913 #define __FUNCT__ "MatGetOwnershipRanges"
5914 /*@C
5915    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5916    each process
5917 
5918    Not Collective, unless matrix has not been allocated, then collective on Mat
5919 
5920    Input Parameters:
5921 .  mat - the matrix
5922 
5923    Output Parameters:
5924 .  ranges - start of each processors portion plus one more then the total length at the end
5925 
5926    Level: beginner
5927 
5928    Concepts: matrices^row ownership
5929 
5930 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5931 
5932 @*/
5933 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5934 {
5935   PetscErrorCode ierr;
5936 
5937   PetscFunctionBegin;
5938   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5939   PetscValidType(mat,1);
5940   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5941   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5942   PetscFunctionReturn(0);
5943 }
5944 
5945 #undef __FUNCT__
5946 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5947 /*@C
5948    MatGetOwnershipRangesColumn - Returns the range of local columns for each process
5949 
5950    Not Collective, unless matrix has not been allocated, then collective on Mat
5951 
5952    Input Parameters:
5953 .  mat - the matrix
5954 
5955    Output Parameters:
5956 .  ranges - start of each processors portion plus one more then the total length at the end
5957 
5958    Level: beginner
5959 
5960    Concepts: matrices^column ownership
5961 
5962 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
5963 
5964 @*/
5965 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5966 {
5967   PetscErrorCode ierr;
5968 
5969   PetscFunctionBegin;
5970   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5971   PetscValidType(mat,1);
5972   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5973   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
5974   PetscFunctionReturn(0);
5975 }
5976 
5977 #undef __FUNCT__
5978 #define __FUNCT__ "MatILUFactorSymbolic"
5979 /*@C
5980    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5981    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
5982    to complete the factorization.
5983 
5984    Collective on Mat
5985 
5986    Input Parameters:
5987 +  mat - the matrix
5988 .  row - row permutation
5989 .  column - column permutation
5990 -  info - structure containing
5991 $      levels - number of levels of fill.
5992 $      expected fill - as ratio of original fill.
5993 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5994                 missing diagonal entries)
5995 
5996    Output Parameters:
5997 .  fact - new matrix that has been symbolically factored
5998 
5999    Notes:
6000    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6001    choosing the fill factor for better efficiency.
6002 
6003    Most users should employ the simplified KSP interface for linear solvers
6004    instead of working directly with matrix algebra routines such as this.
6005    See, e.g., KSPCreate().
6006 
6007    Level: developer
6008 
6009   Concepts: matrices^symbolic LU factorization
6010   Concepts: matrices^factorization
6011   Concepts: LU^symbolic factorization
6012 
6013 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6014           MatGetOrdering(), MatFactorInfo
6015 
6016     Developer Note: fortran interface is not autogenerated as the f90
6017     interface defintion cannot be generated correctly [due to MatFactorInfo]
6018 
6019 @*/
6020 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6021 {
6022   PetscErrorCode ierr;
6023 
6024   PetscFunctionBegin;
6025   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6026   PetscValidType(mat,1);
6027   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6028   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6029   PetscValidPointer(info,4);
6030   PetscValidPointer(fact,5);
6031   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6032   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6033   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
6034   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6035   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6036   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6037 
6038   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6039   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6040   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6041   PetscFunctionReturn(0);
6042 }
6043 
6044 #undef __FUNCT__
6045 #define __FUNCT__ "MatICCFactorSymbolic"
6046 /*@C
6047    MatICCFactorSymbolic - Performs symbolic incomplete
6048    Cholesky factorization for a symmetric matrix.  Use
6049    MatCholeskyFactorNumeric() to complete the factorization.
6050 
6051    Collective on Mat
6052 
6053    Input Parameters:
6054 +  mat - the matrix
6055 .  perm - row and column permutation
6056 -  info - structure containing
6057 $      levels - number of levels of fill.
6058 $      expected fill - as ratio of original fill.
6059 
6060    Output Parameter:
6061 .  fact - the factored matrix
6062 
6063    Notes:
6064    Most users should employ the KSP interface for linear solvers
6065    instead of working directly with matrix algebra routines such as this.
6066    See, e.g., KSPCreate().
6067 
6068    Level: developer
6069 
6070   Concepts: matrices^symbolic incomplete Cholesky factorization
6071   Concepts: matrices^factorization
6072   Concepts: Cholsky^symbolic factorization
6073 
6074 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6075 
6076     Developer Note: fortran interface is not autogenerated as the f90
6077     interface defintion cannot be generated correctly [due to MatFactorInfo]
6078 
6079 @*/
6080 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6081 {
6082   PetscErrorCode ierr;
6083 
6084   PetscFunctionBegin;
6085   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6086   PetscValidType(mat,1);
6087   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6088   PetscValidPointer(info,3);
6089   PetscValidPointer(fact,4);
6090   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6091   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6092   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6093   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
6094   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6095   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6096 
6097   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6098   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6099   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6100   PetscFunctionReturn(0);
6101 }
6102 
6103 #undef __FUNCT__
6104 #define __FUNCT__ "MatGetArray"
6105 /*@C
6106    MatGetArray - Returns a pointer to the element values in the matrix.
6107    The result of this routine is dependent on the underlying matrix data
6108    structure, and may not even work for certain matrix types.  You MUST
6109    call MatRestoreArray() when you no longer need to access the array.
6110 
6111    Not Collective
6112 
6113    Input Parameter:
6114 .  mat - the matrix
6115 
6116    Output Parameter:
6117 .  v - the location of the values
6118 
6119 
6120    Fortran Note:
6121    This routine is used differently from Fortran, e.g.,
6122 .vb
6123         Mat         mat
6124         PetscScalar mat_array(1)
6125         PetscOffset i_mat
6126         PetscErrorCode ierr
6127         call MatGetArray(mat,mat_array,i_mat,ierr)
6128 
6129   C  Access first local entry in matrix; note that array is
6130   C  treated as one dimensional
6131         value = mat_array(i_mat + 1)
6132 
6133         [... other code ...]
6134         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6135 .ve
6136 
6137    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6138    src/mat/examples/tests for details.
6139 
6140    Level: advanced
6141 
6142    Concepts: matrices^access array
6143 
6144 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6145 @*/
6146 PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6147 {
6148   PetscErrorCode ierr;
6149 
6150   PetscFunctionBegin;
6151   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6152   PetscValidType(mat,1);
6153   PetscValidPointer(v,2);
6154   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6155   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6156   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6157   CHKMEMQ;
6158   PetscFunctionReturn(0);
6159 }
6160 
6161 #undef __FUNCT__
6162 #define __FUNCT__ "MatRestoreArray"
6163 /*@C
6164    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6165 
6166    Not Collective
6167 
6168    Input Parameter:
6169 +  mat - the matrix
6170 -  v - the location of the values
6171 
6172    Fortran Note:
6173    This routine is used differently from Fortran, e.g.,
6174 .vb
6175         Mat         mat
6176         PetscScalar mat_array(1)
6177         PetscOffset i_mat
6178         PetscErrorCode ierr
6179         call MatGetArray(mat,mat_array,i_mat,ierr)
6180 
6181   C  Access first local entry in matrix; note that array is
6182   C  treated as one dimensional
6183         value = mat_array(i_mat + 1)
6184 
6185         [... other code ...]
6186         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6187 .ve
6188 
6189    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6190    src/mat/examples/tests for details
6191 
6192    Level: advanced
6193 
6194 .seealso: MatGetArray(), MatRestoreArrayF90()
6195 @*/
6196 PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6197 {
6198   PetscErrorCode ierr;
6199 
6200   PetscFunctionBegin;
6201   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6202   PetscValidType(mat,1);
6203   PetscValidPointer(v,2);
6204 #if defined(PETSC_USE_DEBUG)
6205   CHKMEMQ;
6206 #endif
6207   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6208   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6209   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6210 #if defined(PETSC_HAVE_CUSP)
6211   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6212     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6213   }
6214 #endif
6215   PetscFunctionReturn(0);
6216 }
6217 
6218 #undef __FUNCT__
6219 #define __FUNCT__ "MatGetSubMatrices"
6220 /*@C
6221    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6222    points to an array of valid matrices, they may be reused to store the new
6223    submatrices.
6224 
6225    Collective on Mat
6226 
6227    Input Parameters:
6228 +  mat - the matrix
6229 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6230 .  irow, icol - index sets of rows and columns to extract
6231 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6232 
6233    Output Parameter:
6234 .  submat - the array of submatrices
6235 
6236    Notes:
6237    MatGetSubMatrices() can extract ONLY sequential submatrices
6238    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6239    to extract a parallel submatrix.
6240 
6241    When extracting submatrices from a parallel matrix, each processor can
6242    form a different submatrix by setting the rows and columns of its
6243    individual index sets according to the local submatrix desired.
6244 
6245    When finished using the submatrices, the user should destroy
6246    them with MatDestroyMatrices().
6247 
6248    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6249    original matrix has not changed from that last call to MatGetSubMatrices().
6250 
6251    This routine creates the matrices in submat; you should NOT create them before
6252    calling it. It also allocates the array of matrix pointers submat.
6253 
6254    For BAIJ matrices the index sets must respect the block structure, that is if they
6255    request one row/column in a block, they must request all rows/columns that are in
6256    that block. For example, if the block size is 2 you cannot request just row 0 and
6257    column 0.
6258 
6259    Fortran Note:
6260    The Fortran interface is slightly different from that given below; it
6261    requires one to pass in  as submat a Mat (integer) array of size at least m.
6262 
6263    Level: advanced
6264 
6265    Concepts: matrices^accessing submatrices
6266    Concepts: submatrices
6267 
6268 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6269 @*/
6270 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6271 {
6272   PetscErrorCode ierr;
6273   PetscInt        i;
6274   PetscBool       eq;
6275 
6276   PetscFunctionBegin;
6277   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6278   PetscValidType(mat,1);
6279   if (n) {
6280     PetscValidPointer(irow,3);
6281     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6282     PetscValidPointer(icol,4);
6283     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6284   }
6285   PetscValidPointer(submat,6);
6286   if (n && scall == MAT_REUSE_MATRIX) {
6287     PetscValidPointer(*submat,6);
6288     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6289   }
6290   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6291   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6292   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6293   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6294 
6295   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6296   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6297   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6298   for (i=0; i<n; i++) {
6299     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6300       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6301       if (eq) {
6302 	if (mat->symmetric){
6303 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6304 	} else if (mat->hermitian) {
6305 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6306 	} else if (mat->structurally_symmetric) {
6307 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6308 	}
6309       }
6310     }
6311   }
6312   PetscFunctionReturn(0);
6313 }
6314 
6315 #undef __FUNCT__
6316 #define __FUNCT__ "MatGetSubMatricesParallel"
6317 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6318 {
6319   PetscErrorCode ierr;
6320   PetscInt        i;
6321   PetscBool       eq;
6322 
6323   PetscFunctionBegin;
6324   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6325   PetscValidType(mat,1);
6326   if (n) {
6327     PetscValidPointer(irow,3);
6328     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6329     PetscValidPointer(icol,4);
6330     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6331   }
6332   PetscValidPointer(submat,6);
6333   if (n && scall == MAT_REUSE_MATRIX) {
6334     PetscValidPointer(*submat,6);
6335     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6336   }
6337   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6338   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6339   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6340   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6341 
6342   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6343   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6344   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6345   for (i=0; i<n; i++) {
6346     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6347       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6348       if (eq) {
6349 	if (mat->symmetric){
6350 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6351 	} else if (mat->hermitian) {
6352 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6353 	} else if (mat->structurally_symmetric) {
6354 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6355 	}
6356       }
6357     }
6358   }
6359   PetscFunctionReturn(0);
6360 }
6361 
6362 #undef __FUNCT__
6363 #define __FUNCT__ "MatDestroyMatrices"
6364 /*@C
6365    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6366 
6367    Collective on Mat
6368 
6369    Input Parameters:
6370 +  n - the number of local matrices
6371 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6372                        sequence of MatGetSubMatrices())
6373 
6374    Level: advanced
6375 
6376     Notes: Frees not only the matrices, but also the array that contains the matrices
6377            In Fortran will not free the array.
6378 
6379 .seealso: MatGetSubMatrices()
6380 @*/
6381 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6382 {
6383   PetscErrorCode ierr;
6384   PetscInt       i;
6385 
6386   PetscFunctionBegin;
6387   if (!*mat) PetscFunctionReturn(0);
6388   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6389   PetscValidPointer(mat,2);
6390   for (i=0; i<n; i++) {
6391     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6392   }
6393   /* memory is allocated even if n = 0 */
6394   ierr = PetscFree(*mat);CHKERRQ(ierr);
6395   *mat = PETSC_NULL;
6396   PetscFunctionReturn(0);
6397 }
6398 
6399 #undef __FUNCT__
6400 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6401 /*@C
6402    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6403 
6404    Collective on Mat
6405 
6406    Input Parameters:
6407 .  mat - the matrix
6408 
6409    Output Parameter:
6410 .  matstruct - the sequential matrix with the nonzero structure of mat
6411 
6412   Level: intermediate
6413 
6414 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6415 @*/
6416 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6417 {
6418   PetscErrorCode ierr;
6419 
6420   PetscFunctionBegin;
6421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6422   PetscValidPointer(matstruct,2);
6423 
6424   PetscValidType(mat,1);
6425   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6426   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6427 
6428   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6429   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6430   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6431   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6432   PetscFunctionReturn(0);
6433 }
6434 
6435 #undef __FUNCT__
6436 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6437 /*@C
6438    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6439 
6440    Collective on Mat
6441 
6442    Input Parameters:
6443 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6444                        sequence of MatGetSequentialNonzeroStructure())
6445 
6446    Level: advanced
6447 
6448     Notes: Frees not only the matrices, but also the array that contains the matrices
6449 
6450 .seealso: MatGetSeqNonzeroStructure()
6451 @*/
6452 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6453 {
6454   PetscErrorCode ierr;
6455 
6456   PetscFunctionBegin;
6457   PetscValidPointer(mat,1);
6458   ierr = MatDestroy(mat);CHKERRQ(ierr);
6459   PetscFunctionReturn(0);
6460 }
6461 
6462 #undef __FUNCT__
6463 #define __FUNCT__ "MatIncreaseOverlap"
6464 /*@
6465    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6466    replaces the index sets by larger ones that represent submatrices with
6467    additional overlap.
6468 
6469    Collective on Mat
6470 
6471    Input Parameters:
6472 +  mat - the matrix
6473 .  n   - the number of index sets
6474 .  is  - the array of index sets (these index sets will changed during the call)
6475 -  ov  - the additional overlap requested
6476 
6477    Level: developer
6478 
6479    Concepts: overlap
6480    Concepts: ASM^computing overlap
6481 
6482 .seealso: MatGetSubMatrices()
6483 @*/
6484 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6485 {
6486   PetscErrorCode ierr;
6487 
6488   PetscFunctionBegin;
6489   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6490   PetscValidType(mat,1);
6491   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6492   if (n) {
6493     PetscValidPointer(is,3);
6494     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6495   }
6496   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6497   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6498   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6499 
6500   if (!ov) PetscFunctionReturn(0);
6501   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6502   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6503   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6504   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6505   PetscFunctionReturn(0);
6506 }
6507 
6508 #undef __FUNCT__
6509 #define __FUNCT__ "MatGetBlockSize"
6510 /*@
6511    MatGetBlockSize - Returns the matrix block size; useful especially for the
6512    block row and block diagonal formats.
6513 
6514    Not Collective
6515 
6516    Input Parameter:
6517 .  mat - the matrix
6518 
6519    Output Parameter:
6520 .  bs - block size
6521 
6522    Notes:
6523    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6524 
6525    Level: intermediate
6526 
6527    Concepts: matrices^block size
6528 
6529 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6530 @*/
6531 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6532 {
6533   PetscErrorCode ierr;
6534 
6535   PetscFunctionBegin;
6536   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6537   PetscValidType(mat,1);
6538   PetscValidIntPointer(bs,2);
6539   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6540   *bs = mat->rmap->bs;
6541   PetscFunctionReturn(0);
6542 }
6543 
6544 #undef __FUNCT__
6545 #define __FUNCT__ "MatSetBlockSize"
6546 /*@
6547    MatSetBlockSize - Sets the matrix block size; for many matrix types you
6548      cannot use this and MUST set the blocksize when you preallocate the matrix
6549 
6550    Logically Collective on Mat
6551 
6552    Input Parameters:
6553 +  mat - the matrix
6554 -  bs - block size
6555 
6556    Notes:
6557      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6558      it is not possible to change BAIJ block sizes after preallocation.
6559 
6560    Level: intermediate
6561 
6562    Concepts: matrices^block size
6563 
6564 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6565 @*/
6566 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6567 {
6568   PetscErrorCode ierr;
6569 
6570   PetscFunctionBegin;
6571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6572   PetscValidType(mat,1);
6573   PetscValidLogicalCollectiveInt(mat,bs,2);
6574   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6575   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6576   if (mat->ops->setblocksize) {
6577     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
6578   } else {
6579     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6580   }
6581   PetscFunctionReturn(0);
6582 }
6583 
6584 #undef __FUNCT__
6585 #define __FUNCT__ "MatGetRowIJ"
6586 /*@C
6587     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6588 
6589    Collective on Mat
6590 
6591     Input Parameters:
6592 +   mat - the matrix
6593 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6594 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6595                 symmetrized
6596 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6597                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6598                  always used.
6599 
6600     Output Parameters:
6601 +   n - number of rows in the (possibly compressed) matrix
6602 .   ia - the row pointers [of length n+1]
6603 .   ja - the column indices
6604 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6605            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6606 
6607     Level: developer
6608 
6609     Notes: You CANNOT change any of the ia[] or ja[] values.
6610 
6611            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6612 
6613     Fortran Node
6614 
6615            In Fortran use
6616 $           PetscInt ia(1), ja(1)
6617 $           PetscOffset iia, jja
6618 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6619 $
6620 $          or
6621 $
6622 $           PetscScalar, pointer :: xx_v(:)
6623 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6624 
6625 
6626        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6627 
6628 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6629 @*/
6630 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6631 {
6632   PetscErrorCode ierr;
6633 
6634   PetscFunctionBegin;
6635   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6636   PetscValidType(mat,1);
6637   PetscValidIntPointer(n,4);
6638   if (ia) PetscValidIntPointer(ia,5);
6639   if (ja) PetscValidIntPointer(ja,6);
6640   PetscValidIntPointer(done,7);
6641   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6642   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6643   else {
6644     *done = PETSC_TRUE;
6645     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6646     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6647     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6648   }
6649   PetscFunctionReturn(0);
6650 }
6651 
6652 #undef __FUNCT__
6653 #define __FUNCT__ "MatGetColumnIJ"
6654 /*@C
6655     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6656 
6657     Collective on Mat
6658 
6659     Input Parameters:
6660 +   mat - the matrix
6661 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6662 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6663                 symmetrized
6664 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6665                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6666                  always used.
6667 
6668     Output Parameters:
6669 +   n - number of columns in the (possibly compressed) matrix
6670 .   ia - the column pointers
6671 .   ja - the row indices
6672 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6673 
6674     Level: developer
6675 
6676 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6677 @*/
6678 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6679 {
6680   PetscErrorCode ierr;
6681 
6682   PetscFunctionBegin;
6683   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6684   PetscValidType(mat,1);
6685   PetscValidIntPointer(n,4);
6686   if (ia) PetscValidIntPointer(ia,5);
6687   if (ja) PetscValidIntPointer(ja,6);
6688   PetscValidIntPointer(done,7);
6689   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6690   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6691   else {
6692     *done = PETSC_TRUE;
6693     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6694   }
6695   PetscFunctionReturn(0);
6696 }
6697 
6698 #undef __FUNCT__
6699 #define __FUNCT__ "MatRestoreRowIJ"
6700 /*@C
6701     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6702     MatGetRowIJ().
6703 
6704     Collective on Mat
6705 
6706     Input Parameters:
6707 +   mat - the matrix
6708 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6709 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6710                 symmetrized
6711 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6712                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6713                  always used.
6714 
6715     Output Parameters:
6716 +   n - size of (possibly compressed) matrix
6717 .   ia - the row pointers
6718 .   ja - the column indices
6719 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6720 
6721     Level: developer
6722 
6723 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6724 @*/
6725 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6726 {
6727   PetscErrorCode ierr;
6728 
6729   PetscFunctionBegin;
6730   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6731   PetscValidType(mat,1);
6732   if (ia) PetscValidIntPointer(ia,5);
6733   if (ja) PetscValidIntPointer(ja,6);
6734   PetscValidIntPointer(done,7);
6735   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6736 
6737   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6738   else {
6739     *done = PETSC_TRUE;
6740     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6741   }
6742   PetscFunctionReturn(0);
6743 }
6744 
6745 #undef __FUNCT__
6746 #define __FUNCT__ "MatRestoreColumnIJ"
6747 /*@C
6748     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6749     MatGetColumnIJ().
6750 
6751     Collective on Mat
6752 
6753     Input Parameters:
6754 +   mat - the matrix
6755 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6756 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6757                 symmetrized
6758 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6759                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6760                  always used.
6761 
6762     Output Parameters:
6763 +   n - size of (possibly compressed) matrix
6764 .   ia - the column pointers
6765 .   ja - the row indices
6766 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6767 
6768     Level: developer
6769 
6770 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6771 @*/
6772 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6773 {
6774   PetscErrorCode ierr;
6775 
6776   PetscFunctionBegin;
6777   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6778   PetscValidType(mat,1);
6779   if (ia) PetscValidIntPointer(ia,5);
6780   if (ja) PetscValidIntPointer(ja,6);
6781   PetscValidIntPointer(done,7);
6782   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6783 
6784   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6785   else {
6786     *done = PETSC_TRUE;
6787     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6788   }
6789   PetscFunctionReturn(0);
6790 }
6791 
6792 #undef __FUNCT__
6793 #define __FUNCT__ "MatColoringPatch"
6794 /*@C
6795     MatColoringPatch -Used inside matrix coloring routines that
6796     use MatGetRowIJ() and/or MatGetColumnIJ().
6797 
6798     Collective on Mat
6799 
6800     Input Parameters:
6801 +   mat - the matrix
6802 .   ncolors - max color value
6803 .   n   - number of entries in colorarray
6804 -   colorarray - array indicating color for each column
6805 
6806     Output Parameters:
6807 .   iscoloring - coloring generated using colorarray information
6808 
6809     Level: developer
6810 
6811 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6812 
6813 @*/
6814 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6815 {
6816   PetscErrorCode ierr;
6817 
6818   PetscFunctionBegin;
6819   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6820   PetscValidType(mat,1);
6821   PetscValidIntPointer(colorarray,4);
6822   PetscValidPointer(iscoloring,5);
6823   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6824 
6825   if (!mat->ops->coloringpatch){
6826     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6827   } else {
6828     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6829   }
6830   PetscFunctionReturn(0);
6831 }
6832 
6833 
6834 #undef __FUNCT__
6835 #define __FUNCT__ "MatSetUnfactored"
6836 /*@
6837    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6838 
6839    Logically Collective on Mat
6840 
6841    Input Parameter:
6842 .  mat - the factored matrix to be reset
6843 
6844    Notes:
6845    This routine should be used only with factored matrices formed by in-place
6846    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6847    format).  This option can save memory, for example, when solving nonlinear
6848    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6849    ILU(0) preconditioner.
6850 
6851    Note that one can specify in-place ILU(0) factorization by calling
6852 .vb
6853      PCType(pc,PCILU);
6854      PCFactorSeUseInPlace(pc);
6855 .ve
6856    or by using the options -pc_type ilu -pc_factor_in_place
6857 
6858    In-place factorization ILU(0) can also be used as a local
6859    solver for the blocks within the block Jacobi or additive Schwarz
6860    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6861    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6862    local solver options.
6863 
6864    Most users should employ the simplified KSP interface for linear solvers
6865    instead of working directly with matrix algebra routines such as this.
6866    See, e.g., KSPCreate().
6867 
6868    Level: developer
6869 
6870 .seealso: PCFactorSetUseInPlace()
6871 
6872    Concepts: matrices^unfactored
6873 
6874 @*/
6875 PetscErrorCode  MatSetUnfactored(Mat mat)
6876 {
6877   PetscErrorCode ierr;
6878 
6879   PetscFunctionBegin;
6880   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6881   PetscValidType(mat,1);
6882   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6883   mat->factortype = MAT_FACTOR_NONE;
6884   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6885   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6886   PetscFunctionReturn(0);
6887 }
6888 
6889 /*MC
6890     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6891 
6892     Synopsis:
6893     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6894 
6895     Not collective
6896 
6897     Input Parameter:
6898 .   x - matrix
6899 
6900     Output Parameters:
6901 +   xx_v - the Fortran90 pointer to the array
6902 -   ierr - error code
6903 
6904     Example of Usage:
6905 .vb
6906       PetscScalar, pointer xx_v(:)
6907       ....
6908       call MatGetArrayF90(x,xx_v,ierr)
6909       a = xx_v(3)
6910       call MatRestoreArrayF90(x,xx_v,ierr)
6911 .ve
6912 
6913     Notes:
6914     Not yet supported for all F90 compilers
6915 
6916     Level: advanced
6917 
6918 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6919 
6920     Concepts: matrices^accessing array
6921 
6922 M*/
6923 
6924 /*MC
6925     MatRestoreArrayF90 - Restores a matrix array that has been
6926     accessed with MatGetArrayF90().
6927 
6928     Synopsis:
6929     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6930 
6931     Not collective
6932 
6933     Input Parameters:
6934 +   x - matrix
6935 -   xx_v - the Fortran90 pointer to the array
6936 
6937     Output Parameter:
6938 .   ierr - error code
6939 
6940     Example of Usage:
6941 .vb
6942        PetscScalar, pointer xx_v(:)
6943        ....
6944        call MatGetArrayF90(x,xx_v,ierr)
6945        a = xx_v(3)
6946        call MatRestoreArrayF90(x,xx_v,ierr)
6947 .ve
6948 
6949     Notes:
6950     Not yet supported for all F90 compilers
6951 
6952     Level: advanced
6953 
6954 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
6955 
6956 M*/
6957 
6958 
6959 #undef __FUNCT__
6960 #define __FUNCT__ "MatGetSubMatrix"
6961 /*@
6962     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6963                       as the original matrix.
6964 
6965     Collective on Mat
6966 
6967     Input Parameters:
6968 +   mat - the original matrix
6969 .   isrow - parallel IS containing the rows this processor should obtain
6970 .   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.
6971 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6972 
6973     Output Parameter:
6974 .   newmat - the new submatrix, of the same type as the old
6975 
6976     Level: advanced
6977 
6978     Notes:
6979     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
6980 
6981     The rows in isrow will be sorted into the same order as the original matrix on each process.
6982 
6983       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6984    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6985    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
6986    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
6987    you are finished using it.
6988 
6989     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6990     the input matrix.
6991 
6992     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
6993 
6994    Example usage:
6995    Consider the following 8x8 matrix with 34 non-zero values, that is
6996    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
6997    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6998    as follows:
6999 
7000 .vb
7001             1  2  0  |  0  3  0  |  0  4
7002     Proc0   0  5  6  |  7  0  0  |  8  0
7003             9  0 10  | 11  0  0  | 12  0
7004     -------------------------------------
7005            13  0 14  | 15 16 17  |  0  0
7006     Proc1   0 18  0  | 19 20 21  |  0  0
7007             0  0  0  | 22 23  0  | 24  0
7008     -------------------------------------
7009     Proc2  25 26 27  |  0  0 28  | 29  0
7010            30  0  0  | 31 32 33  |  0 34
7011 .ve
7012 
7013     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7014 
7015 .vb
7016             2  0  |  0  3  0  |  0
7017     Proc0   5  6  |  7  0  0  |  8
7018     -------------------------------
7019     Proc1  18  0  | 19 20 21  |  0
7020     -------------------------------
7021     Proc2  26 27  |  0  0 28  | 29
7022             0  0  | 31 32 33  |  0
7023 .ve
7024 
7025 
7026     Concepts: matrices^submatrices
7027 
7028 .seealso: MatGetSubMatrices()
7029 @*/
7030 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7031 {
7032   PetscErrorCode ierr;
7033   PetscMPIInt    size;
7034   Mat            *local;
7035   IS             iscoltmp;
7036 
7037   PetscFunctionBegin;
7038   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7039   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7040   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7041   PetscValidPointer(newmat,5);
7042   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7043   PetscValidType(mat,1);
7044   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7045   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7046   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7047 
7048   if (!iscol) {
7049     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7050   } else {
7051     iscoltmp = iscol;
7052   }
7053 
7054   /* if original matrix is on just one processor then use submatrix generated */
7055   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7056     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7057     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7058     PetscFunctionReturn(0);
7059   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7060     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7061     *newmat = *local;
7062     ierr    = PetscFree(local);CHKERRQ(ierr);
7063     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7064     PetscFunctionReturn(0);
7065   } else if (!mat->ops->getsubmatrix) {
7066     /* Create a new matrix type that implements the operation using the full matrix */
7067     switch (cll) {
7068       case MAT_INITIAL_MATRIX:
7069         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7070         break;
7071       case MAT_REUSE_MATRIX:
7072         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7073         break;
7074       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7075     }
7076     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7077     PetscFunctionReturn(0);
7078   }
7079 
7080   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7081   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7082   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7083   ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);
7084   PetscFunctionReturn(0);
7085 }
7086 
7087 #undef __FUNCT__
7088 #define __FUNCT__ "MatStashSetInitialSize"
7089 /*@
7090    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7091    used during the assembly process to store values that belong to
7092    other processors.
7093 
7094    Not Collective
7095 
7096    Input Parameters:
7097 +  mat   - the matrix
7098 .  size  - the initial size of the stash.
7099 -  bsize - the initial size of the block-stash(if used).
7100 
7101    Options Database Keys:
7102 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7103 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7104 
7105    Level: intermediate
7106 
7107    Notes:
7108      The block-stash is used for values set with MatSetValuesBlocked() while
7109      the stash is used for values set with MatSetValues()
7110 
7111      Run with the option -info and look for output of the form
7112      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7113      to determine the appropriate value, MM, to use for size and
7114      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7115      to determine the value, BMM to use for bsize
7116 
7117    Concepts: stash^setting matrix size
7118    Concepts: matrices^stash
7119 
7120 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7121 
7122 @*/
7123 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7124 {
7125   PetscErrorCode ierr;
7126 
7127   PetscFunctionBegin;
7128   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7129   PetscValidType(mat,1);
7130   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7131   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7132   PetscFunctionReturn(0);
7133 }
7134 
7135 #undef __FUNCT__
7136 #define __FUNCT__ "MatInterpolateAdd"
7137 /*@
7138    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7139      the matrix
7140 
7141    Neighbor-wise Collective on Mat
7142 
7143    Input Parameters:
7144 +  mat   - the matrix
7145 .  x,y - the vectors
7146 -  w - where the result is stored
7147 
7148    Level: intermediate
7149 
7150    Notes:
7151     w may be the same vector as y.
7152 
7153     This allows one to use either the restriction or interpolation (its transpose)
7154     matrix to do the interpolation
7155 
7156     Concepts: interpolation
7157 
7158 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7159 
7160 @*/
7161 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7162 {
7163   PetscErrorCode ierr;
7164   PetscInt       M,N,Ny;
7165 
7166   PetscFunctionBegin;
7167   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7168   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7169   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7170   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7171   PetscValidType(A,1);
7172   ierr = MatPreallocated(A);CHKERRQ(ierr);
7173   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7174   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7175   if (M == Ny) {
7176     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7177   } else {
7178     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7179   }
7180   PetscFunctionReturn(0);
7181 }
7182 
7183 #undef __FUNCT__
7184 #define __FUNCT__ "MatInterpolate"
7185 /*@
7186    MatInterpolate - y = A*x or A'*x depending on the shape of
7187      the matrix
7188 
7189    Neighbor-wise Collective on Mat
7190 
7191    Input Parameters:
7192 +  mat   - the matrix
7193 -  x,y - the vectors
7194 
7195    Level: intermediate
7196 
7197    Notes:
7198     This allows one to use either the restriction or interpolation (its transpose)
7199     matrix to do the interpolation
7200 
7201    Concepts: matrices^interpolation
7202 
7203 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7204 
7205 @*/
7206 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7207 {
7208   PetscErrorCode ierr;
7209   PetscInt       M,N,Ny;
7210 
7211   PetscFunctionBegin;
7212   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7213   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7214   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7215   PetscValidType(A,1);
7216   ierr = MatPreallocated(A);CHKERRQ(ierr);
7217   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7218   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7219   if (M == Ny) {
7220     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7221   } else {
7222     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7223   }
7224   PetscFunctionReturn(0);
7225 }
7226 
7227 #undef __FUNCT__
7228 #define __FUNCT__ "MatRestrict"
7229 /*@
7230    MatRestrict - y = A*x or A'*x
7231 
7232    Neighbor-wise Collective on Mat
7233 
7234    Input Parameters:
7235 +  mat   - the matrix
7236 -  x,y - the vectors
7237 
7238    Level: intermediate
7239 
7240    Notes:
7241     This allows one to use either the restriction or interpolation (its transpose)
7242     matrix to do the restriction
7243 
7244    Concepts: matrices^restriction
7245 
7246 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7247 
7248 @*/
7249 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7250 {
7251   PetscErrorCode ierr;
7252   PetscInt       M,N,Ny;
7253 
7254   PetscFunctionBegin;
7255   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7256   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7257   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7258   PetscValidType(A,1);
7259   ierr = MatPreallocated(A);CHKERRQ(ierr);
7260 
7261   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7262   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7263   if (M == Ny) {
7264     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7265   } else {
7266     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7267   }
7268   PetscFunctionReturn(0);
7269 }
7270 
7271 #undef __FUNCT__
7272 #define __FUNCT__ "MatNullSpaceAttach"
7273 /*@
7274    MatNullSpaceAttach - attaches a null space to a matrix.
7275         This null space will be removed from the resulting vector whenever
7276         MatMult() is called
7277 
7278    Logically Collective on Mat and MatNullSpace
7279 
7280    Input Parameters:
7281 +  mat - the matrix
7282 -  nullsp - the null space object
7283 
7284    Level: developer
7285 
7286    Notes:
7287       Overwrites any previous null space that may have been attached
7288 
7289    Concepts: null space^attaching to matrix
7290 
7291 .seealso: MatCreate(), MatNullSpaceCreate()
7292 @*/
7293 PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
7294 {
7295   PetscErrorCode ierr;
7296 
7297   PetscFunctionBegin;
7298   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7299   PetscValidType(mat,1);
7300   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7301   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7302   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7303   if (mat->nullsp) { ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); }
7304   mat->nullsp = nullsp;
7305   PetscFunctionReturn(0);
7306 }
7307 
7308 #undef __FUNCT__
7309 #define __FUNCT__ "MatICCFactor"
7310 /*@C
7311    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7312 
7313    Collective on Mat
7314 
7315    Input Parameters:
7316 +  mat - the matrix
7317 .  row - row/column permutation
7318 .  fill - expected fill factor >= 1.0
7319 -  level - level of fill, for ICC(k)
7320 
7321    Notes:
7322    Probably really in-place only when level of fill is zero, otherwise allocates
7323    new space to store factored matrix and deletes previous memory.
7324 
7325    Most users should employ the simplified KSP interface for linear solvers
7326    instead of working directly with matrix algebra routines such as this.
7327    See, e.g., KSPCreate().
7328 
7329    Level: developer
7330 
7331    Concepts: matrices^incomplete Cholesky factorization
7332    Concepts: Cholesky factorization
7333 
7334 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7335 
7336     Developer Note: fortran interface is not autogenerated as the f90
7337     interface defintion cannot be generated correctly [due to MatFactorInfo]
7338 
7339 @*/
7340 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7341 {
7342   PetscErrorCode ierr;
7343 
7344   PetscFunctionBegin;
7345   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7346   PetscValidType(mat,1);
7347   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7348   PetscValidPointer(info,3);
7349   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7350   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7351   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7352   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7353   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7354   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7355   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7356   PetscFunctionReturn(0);
7357 }
7358 
7359 #undef __FUNCT__
7360 #define __FUNCT__ "MatSetValuesAdic"
7361 /*@
7362    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7363 
7364    Not Collective
7365 
7366    Input Parameters:
7367 +  mat - the matrix
7368 -  v - the values compute with ADIC
7369 
7370    Level: developer
7371 
7372    Notes:
7373      Must call MatSetColoring() before using this routine. Also this matrix must already
7374      have its nonzero pattern determined.
7375 
7376 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7377           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7378 @*/
7379 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7380 {
7381   PetscErrorCode ierr;
7382 
7383   PetscFunctionBegin;
7384   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7385   PetscValidType(mat,1);
7386   PetscValidPointer(mat,2);
7387 
7388   if (!mat->assembled) {
7389     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7390   }
7391   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7392   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7393   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7394   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7395   ierr = MatView_Private(mat);CHKERRQ(ierr);
7396   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7397   PetscFunctionReturn(0);
7398 }
7399 
7400 
7401 #undef __FUNCT__
7402 #define __FUNCT__ "MatSetColoring"
7403 /*@
7404    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7405 
7406    Not Collective
7407 
7408    Input Parameters:
7409 +  mat - the matrix
7410 -  coloring - the coloring
7411 
7412    Level: developer
7413 
7414 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7415           MatSetValues(), MatSetValuesAdic()
7416 @*/
7417 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7418 {
7419   PetscErrorCode ierr;
7420 
7421   PetscFunctionBegin;
7422   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7423   PetscValidType(mat,1);
7424   PetscValidPointer(coloring,2);
7425 
7426   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7427   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7428   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7429   PetscFunctionReturn(0);
7430 }
7431 
7432 #undef __FUNCT__
7433 #define __FUNCT__ "MatSetValuesAdifor"
7434 /*@
7435    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7436 
7437    Not Collective
7438 
7439    Input Parameters:
7440 +  mat - the matrix
7441 .  nl - leading dimension of v
7442 -  v - the values compute with ADIFOR
7443 
7444    Level: developer
7445 
7446    Notes:
7447      Must call MatSetColoring() before using this routine. Also this matrix must already
7448      have its nonzero pattern determined.
7449 
7450 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7451           MatSetValues(), MatSetColoring()
7452 @*/
7453 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7454 {
7455   PetscErrorCode ierr;
7456 
7457   PetscFunctionBegin;
7458   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7459   PetscValidType(mat,1);
7460   PetscValidPointer(v,3);
7461 
7462   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7463   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7464   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7465   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7466   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7467   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7468   PetscFunctionReturn(0);
7469 }
7470 
7471 #undef __FUNCT__
7472 #define __FUNCT__ "MatDiagonalScaleLocal"
7473 /*@
7474    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7475          ghosted ones.
7476 
7477    Not Collective
7478 
7479    Input Parameters:
7480 +  mat - the matrix
7481 -  diag = the diagonal values, including ghost ones
7482 
7483    Level: developer
7484 
7485    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7486 
7487 .seealso: MatDiagonalScale()
7488 @*/
7489 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7490 {
7491   PetscErrorCode ierr;
7492   PetscMPIInt    size;
7493 
7494   PetscFunctionBegin;
7495   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7496   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7497   PetscValidType(mat,1);
7498 
7499   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7500   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7501   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7502   if (size == 1) {
7503     PetscInt n,m;
7504     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7505     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7506     if (m == n) {
7507       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7508     } else {
7509       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7510     }
7511   } else {
7512     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7513   }
7514   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7515   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7516   PetscFunctionReturn(0);
7517 }
7518 
7519 #undef __FUNCT__
7520 #define __FUNCT__ "MatGetInertia"
7521 /*@
7522    MatGetInertia - Gets the inertia from a factored matrix
7523 
7524    Collective on Mat
7525 
7526    Input Parameter:
7527 .  mat - the matrix
7528 
7529    Output Parameters:
7530 +   nneg - number of negative eigenvalues
7531 .   nzero - number of zero eigenvalues
7532 -   npos - number of positive eigenvalues
7533 
7534    Level: advanced
7535 
7536    Notes: Matrix must have been factored by MatCholeskyFactor()
7537 
7538 
7539 @*/
7540 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7541 {
7542   PetscErrorCode ierr;
7543 
7544   PetscFunctionBegin;
7545   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7546   PetscValidType(mat,1);
7547   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7548   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7549   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7550   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7551   PetscFunctionReturn(0);
7552 }
7553 
7554 /* ----------------------------------------------------------------*/
7555 #undef __FUNCT__
7556 #define __FUNCT__ "MatSolves"
7557 /*@C
7558    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7559 
7560    Neighbor-wise Collective on Mat and Vecs
7561 
7562    Input Parameters:
7563 +  mat - the factored matrix
7564 -  b - the right-hand-side vectors
7565 
7566    Output Parameter:
7567 .  x - the result vectors
7568 
7569    Notes:
7570    The vectors b and x cannot be the same.  I.e., one cannot
7571    call MatSolves(A,x,x).
7572 
7573    Notes:
7574    Most users should employ the simplified KSP interface for linear solvers
7575    instead of working directly with matrix algebra routines such as this.
7576    See, e.g., KSPCreate().
7577 
7578    Level: developer
7579 
7580    Concepts: matrices^triangular solves
7581 
7582 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7583 @*/
7584 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7585 {
7586   PetscErrorCode ierr;
7587 
7588   PetscFunctionBegin;
7589   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7590   PetscValidType(mat,1);
7591   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7592   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7593   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7594 
7595   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7596   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7597   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7598   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7599   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7600   PetscFunctionReturn(0);
7601 }
7602 
7603 #undef __FUNCT__
7604 #define __FUNCT__ "MatIsSymmetric"
7605 /*@
7606    MatIsSymmetric - Test whether a matrix is symmetric
7607 
7608    Collective on Mat
7609 
7610    Input Parameter:
7611 +  A - the matrix to test
7612 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7613 
7614    Output Parameters:
7615 .  flg - the result
7616 
7617    Level: intermediate
7618 
7619    Concepts: matrix^symmetry
7620 
7621 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7622 @*/
7623 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7624 {
7625   PetscErrorCode ierr;
7626 
7627   PetscFunctionBegin;
7628   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7629   PetscValidPointer(flg,2);
7630 
7631   if (!A->symmetric_set) {
7632     if (!A->ops->issymmetric) {
7633       const MatType mattype;
7634       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7635       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7636     }
7637     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7638     if (!tol) {
7639       A->symmetric_set = PETSC_TRUE;
7640       A->symmetric = *flg;
7641       if (A->symmetric) {
7642 	A->structurally_symmetric_set = PETSC_TRUE;
7643 	A->structurally_symmetric     = PETSC_TRUE;
7644       }
7645     }
7646   } else if (A->symmetric) {
7647     *flg = PETSC_TRUE;
7648   } else if (!tol) {
7649     *flg = PETSC_FALSE;
7650   } else {
7651     if (!A->ops->issymmetric) {
7652       const MatType mattype;
7653       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7654       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7655     }
7656     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7657   }
7658   PetscFunctionReturn(0);
7659 }
7660 
7661 #undef __FUNCT__
7662 #define __FUNCT__ "MatIsHermitian"
7663 /*@
7664    MatIsHermitian - Test whether a matrix is Hermitian
7665 
7666    Collective on Mat
7667 
7668    Input Parameter:
7669 +  A - the matrix to test
7670 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7671 
7672    Output Parameters:
7673 .  flg - the result
7674 
7675    Level: intermediate
7676 
7677    Concepts: matrix^symmetry
7678 
7679 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7680 @*/
7681 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7682 {
7683   PetscErrorCode ierr;
7684 
7685   PetscFunctionBegin;
7686   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7687   PetscValidPointer(flg,2);
7688 
7689   if (!A->hermitian_set) {
7690     if (!A->ops->ishermitian) {
7691       const MatType mattype;
7692       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7693       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7694     }
7695     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7696     if (!tol) {
7697       A->hermitian_set = PETSC_TRUE;
7698       A->hermitian = *flg;
7699       if (A->hermitian) {
7700 	A->structurally_symmetric_set = PETSC_TRUE;
7701 	A->structurally_symmetric     = PETSC_TRUE;
7702       }
7703     }
7704   } else if (A->hermitian) {
7705     *flg = PETSC_TRUE;
7706   } else if (!tol) {
7707     *flg = PETSC_FALSE;
7708   } else {
7709     if (!A->ops->ishermitian) {
7710       const MatType mattype;
7711       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7712       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7713     }
7714     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7715   }
7716   PetscFunctionReturn(0);
7717 }
7718 
7719 #undef __FUNCT__
7720 #define __FUNCT__ "MatIsSymmetricKnown"
7721 /*@
7722    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7723 
7724    Not Collective
7725 
7726    Input Parameter:
7727 .  A - the matrix to check
7728 
7729    Output Parameters:
7730 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7731 -  flg - the result
7732 
7733    Level: advanced
7734 
7735    Concepts: matrix^symmetry
7736 
7737    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7738          if you want it explicitly checked
7739 
7740 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7741 @*/
7742 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7743 {
7744   PetscFunctionBegin;
7745   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7746   PetscValidPointer(set,2);
7747   PetscValidPointer(flg,3);
7748   if (A->symmetric_set) {
7749     *set = PETSC_TRUE;
7750     *flg = A->symmetric;
7751   } else {
7752     *set = PETSC_FALSE;
7753   }
7754   PetscFunctionReturn(0);
7755 }
7756 
7757 #undef __FUNCT__
7758 #define __FUNCT__ "MatIsHermitianKnown"
7759 /*@
7760    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7761 
7762    Not Collective
7763 
7764    Input Parameter:
7765 .  A - the matrix to check
7766 
7767    Output Parameters:
7768 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7769 -  flg - the result
7770 
7771    Level: advanced
7772 
7773    Concepts: matrix^symmetry
7774 
7775    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7776          if you want it explicitly checked
7777 
7778 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7779 @*/
7780 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7781 {
7782   PetscFunctionBegin;
7783   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7784   PetscValidPointer(set,2);
7785   PetscValidPointer(flg,3);
7786   if (A->hermitian_set) {
7787     *set = PETSC_TRUE;
7788     *flg = A->hermitian;
7789   } else {
7790     *set = PETSC_FALSE;
7791   }
7792   PetscFunctionReturn(0);
7793 }
7794 
7795 #undef __FUNCT__
7796 #define __FUNCT__ "MatIsStructurallySymmetric"
7797 /*@
7798    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7799 
7800    Collective on Mat
7801 
7802    Input Parameter:
7803 .  A - the matrix to test
7804 
7805    Output Parameters:
7806 .  flg - the result
7807 
7808    Level: intermediate
7809 
7810    Concepts: matrix^symmetry
7811 
7812 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7813 @*/
7814 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
7815 {
7816   PetscErrorCode ierr;
7817 
7818   PetscFunctionBegin;
7819   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7820   PetscValidPointer(flg,2);
7821   if (!A->structurally_symmetric_set) {
7822     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7823     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7824     A->structurally_symmetric_set = PETSC_TRUE;
7825   }
7826   *flg = A->structurally_symmetric;
7827   PetscFunctionReturn(0);
7828 }
7829 
7830 #undef __FUNCT__
7831 #define __FUNCT__ "MatStashGetInfo"
7832 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7833 /*@
7834    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7835        to be communicated to other processors during the MatAssemblyBegin/End() process
7836 
7837     Not collective
7838 
7839    Input Parameter:
7840 .   vec - the vector
7841 
7842    Output Parameters:
7843 +   nstash   - the size of the stash
7844 .   reallocs - the number of additional mallocs incurred.
7845 .   bnstash   - the size of the block stash
7846 -   breallocs - the number of additional mallocs incurred.in the block stash
7847 
7848    Level: advanced
7849 
7850 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7851 
7852 @*/
7853 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7854 {
7855   PetscErrorCode ierr;
7856   PetscFunctionBegin;
7857   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7858   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7859   PetscFunctionReturn(0);
7860 }
7861 
7862 #undef __FUNCT__
7863 #define __FUNCT__ "MatGetVecs"
7864 /*@C
7865    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7866      parallel layout
7867 
7868    Collective on Mat
7869 
7870    Input Parameter:
7871 .  mat - the matrix
7872 
7873    Output Parameter:
7874 +   right - (optional) vector that the matrix can be multiplied against
7875 -   left - (optional) vector that the matrix vector product can be stored in
7876 
7877   Level: advanced
7878 
7879 .seealso: MatCreate()
7880 @*/
7881 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7882 {
7883   PetscErrorCode ierr;
7884 
7885   PetscFunctionBegin;
7886   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7887   PetscValidType(mat,1);
7888   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7889   if (mat->ops->getvecs) {
7890     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7891   } else {
7892     PetscMPIInt size;
7893     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7894     if (right) {
7895       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7896       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7897       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7898       if (size > 1) {
7899         /* New vectors uses Mat cmap and does not create a new one */
7900 	ierr = PetscLayoutDestroy(&(*right)->map);CHKERRQ(ierr);
7901 	(*right)->map = mat->cmap;
7902 	mat->cmap->refcnt++;
7903 
7904         ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);
7905       } else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
7906     }
7907     if (left) {
7908       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7909       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7910       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7911       if (size > 1) {
7912         /* New vectors uses Mat rmap and does not create a new one */
7913 	ierr = PetscLayoutDestroy(&(*left)->map);CHKERRQ(ierr);
7914 	(*left)->map = mat->rmap;
7915 	mat->rmap->refcnt++;
7916 
7917         ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);
7918       } else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
7919     }
7920   }
7921   if (mat->rmapping) {
7922     if (right) {ierr = VecSetLocalToGlobalMapping(*right,mat->cmapping);CHKERRQ(ierr);}
7923     if (left) {ierr = VecSetLocalToGlobalMapping(*left,mat->rmapping);CHKERRQ(ierr);}
7924   }
7925   if (mat->rbmapping) {
7926     if (right) {ierr = VecSetLocalToGlobalMappingBlock(*right,mat->cbmapping);CHKERRQ(ierr);}
7927     if (left) {ierr = VecSetLocalToGlobalMappingBlock(*left,mat->rbmapping);CHKERRQ(ierr);}
7928   }
7929   PetscFunctionReturn(0);
7930 }
7931 
7932 #undef __FUNCT__
7933 #define __FUNCT__ "MatFactorInfoInitialize"
7934 /*@C
7935    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7936      with default values.
7937 
7938    Not Collective
7939 
7940    Input Parameters:
7941 .    info - the MatFactorInfo data structure
7942 
7943 
7944    Notes: The solvers are generally used through the KSP and PC objects, for example
7945           PCLU, PCILU, PCCHOLESKY, PCICC
7946 
7947    Level: developer
7948 
7949 .seealso: MatFactorInfo
7950 
7951     Developer Note: fortran interface is not autogenerated as the f90
7952     interface defintion cannot be generated correctly [due to MatFactorInfo]
7953 
7954 @*/
7955 
7956 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7957 {
7958   PetscErrorCode ierr;
7959 
7960   PetscFunctionBegin;
7961   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
7962   PetscFunctionReturn(0);
7963 }
7964 
7965 #undef __FUNCT__
7966 #define __FUNCT__ "MatPtAP"
7967 /*@
7968    MatPtAP - Creates the matrix product C = P^T * A * P
7969 
7970    Neighbor-wise Collective on Mat
7971 
7972    Input Parameters:
7973 +  A - the matrix
7974 .  P - the projection matrix
7975 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7976 -  fill - expected fill as ratio of nnz(C)/nnz(A)
7977 
7978    Output Parameters:
7979 .  C - the product matrix
7980 
7981    Notes:
7982    C will be created and must be destroyed by the user with MatDestroy().
7983 
7984    This routine is currently only implemented for pairs of AIJ matrices and classes
7985    which inherit from AIJ.
7986 
7987    Level: intermediate
7988 
7989 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7990 @*/
7991 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7992 {
7993   PetscErrorCode ierr;
7994 
7995   PetscFunctionBegin;
7996   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7997   PetscValidType(A,1);
7998   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7999   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8000   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8001   PetscValidType(P,2);
8002   ierr = MatPreallocated(P);CHKERRQ(ierr);
8003   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8004   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8005   PetscValidPointer(C,3);
8006   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);
8007   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8008   ierr = MatPreallocated(A);CHKERRQ(ierr);
8009 
8010   if (!A->ops->ptap) {
8011     const MatType mattype;
8012     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8013     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8014   }
8015   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8016   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8017   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8018 
8019   PetscFunctionReturn(0);
8020 }
8021 
8022 #undef __FUNCT__
8023 #define __FUNCT__ "MatPtAPNumeric"
8024 /*@
8025    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8026 
8027    Neighbor-wise Collective on Mat
8028 
8029    Input Parameters:
8030 +  A - the matrix
8031 -  P - the projection matrix
8032 
8033    Output Parameters:
8034 .  C - the product matrix
8035 
8036    Notes:
8037    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8038    the user using MatDeatroy().
8039 
8040    This routine is currently only implemented for pairs of AIJ matrices and classes
8041    which inherit from AIJ.  C will be of type MATAIJ.
8042 
8043    Level: intermediate
8044 
8045 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8046 @*/
8047 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8048 {
8049   PetscErrorCode ierr;
8050 
8051   PetscFunctionBegin;
8052   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8053   PetscValidType(A,1);
8054   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8055   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8056   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8057   PetscValidType(P,2);
8058   ierr = MatPreallocated(P);CHKERRQ(ierr);
8059   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8060   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8061   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8062   PetscValidType(C,3);
8063   ierr = MatPreallocated(C);CHKERRQ(ierr);
8064   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8065   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);
8066   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);
8067   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);
8068   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);
8069   ierr = MatPreallocated(A);CHKERRQ(ierr);
8070 
8071   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8072   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8073   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8074   PetscFunctionReturn(0);
8075 }
8076 
8077 #undef __FUNCT__
8078 #define __FUNCT__ "MatPtAPSymbolic"
8079 /*@
8080    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8081 
8082    Neighbor-wise Collective on Mat
8083 
8084    Input Parameters:
8085 +  A - the matrix
8086 -  P - the projection matrix
8087 
8088    Output Parameters:
8089 .  C - the (i,j) structure of the product matrix
8090 
8091    Notes:
8092    C will be created and must be destroyed by the user with MatDestroy().
8093 
8094    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8095    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8096    this (i,j) structure by calling MatPtAPNumeric().
8097 
8098    Level: intermediate
8099 
8100 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8101 @*/
8102 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8103 {
8104   PetscErrorCode ierr;
8105 
8106   PetscFunctionBegin;
8107   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8108   PetscValidType(A,1);
8109   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8110   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8111   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8112   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8113   PetscValidType(P,2);
8114   ierr = MatPreallocated(P);CHKERRQ(ierr);
8115   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8116   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8117   PetscValidPointer(C,3);
8118 
8119   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);
8120   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);
8121   ierr = MatPreallocated(A);CHKERRQ(ierr);
8122   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8123   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8124   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8125 
8126   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8127 
8128   PetscFunctionReturn(0);
8129 }
8130 
8131 #undef __FUNCT__
8132 #define __FUNCT__ "MatMatMult"
8133 /*@
8134    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8135 
8136    Neighbor-wise Collective on Mat
8137 
8138    Input Parameters:
8139 +  A - the left matrix
8140 .  B - the right matrix
8141 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8142 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8143           if the result is a dense matrix this is irrelevent
8144 
8145    Output Parameters:
8146 .  C - the product matrix
8147 
8148    Notes:
8149    Unless scall is MAT_REUSE_MATRIX C will be created.
8150 
8151    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8152 
8153    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8154    actually needed.
8155 
8156    If you have many matrices with the same non-zero structure to multiply, you
8157    should either
8158 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8159 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8160 
8161    Level: intermediate
8162 
8163 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8164 @*/
8165 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8166 {
8167   PetscErrorCode ierr;
8168   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8169   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8170   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8171 
8172   PetscFunctionBegin;
8173   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8174   PetscValidType(A,1);
8175   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8176   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8177   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8178   PetscValidType(B,2);
8179   ierr = MatPreallocated(B);CHKERRQ(ierr);
8180   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8181   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8182   PetscValidPointer(C,3);
8183   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);
8184   if (scall == MAT_REUSE_MATRIX){
8185     PetscValidPointer(*C,5);
8186     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8187   }
8188   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8189   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8190   ierr = MatPreallocated(A);CHKERRQ(ierr);
8191 
8192   fA = A->ops->matmult;
8193   fB = B->ops->matmult;
8194   if (fB == fA) {
8195     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8196     mult = fB;
8197   } else {
8198     /* dispatch based on the type of A and B */
8199     char  multname[256];
8200     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8201     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8202     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8203     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8204     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8205     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8206     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);
8207   }
8208   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8209   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8210   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8211   PetscFunctionReturn(0);
8212 }
8213 
8214 #undef __FUNCT__
8215 #define __FUNCT__ "MatMatMultSymbolic"
8216 /*@
8217    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8218    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8219 
8220    Neighbor-wise Collective on Mat
8221 
8222    Input Parameters:
8223 +  A - the left matrix
8224 .  B - the right matrix
8225 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8226       if C is a dense matrix this is irrelevent
8227 
8228    Output Parameters:
8229 .  C - the product matrix
8230 
8231    Notes:
8232    Unless scall is MAT_REUSE_MATRIX C will be created.
8233 
8234    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8235    actually needed.
8236 
8237    This routine is currently implemented for
8238     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8239     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8240     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8241 
8242    Level: intermediate
8243 
8244    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8245      We should incorporate them into PETSc.
8246 
8247 .seealso: MatMatMult(), MatMatMultNumeric()
8248 @*/
8249 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8250 {
8251   PetscErrorCode ierr;
8252   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8253   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8254   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8255 
8256   PetscFunctionBegin;
8257   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8258   PetscValidType(A,1);
8259   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8260   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8261 
8262   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8263   PetscValidType(B,2);
8264   ierr = MatPreallocated(B);CHKERRQ(ierr);
8265   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8266   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8267   PetscValidPointer(C,3);
8268 
8269   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);
8270   if (fill == PETSC_DEFAULT) fill = 2.0;
8271   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8272   ierr = MatPreallocated(A);CHKERRQ(ierr);
8273 
8274   Asymbolic = A->ops->matmultsymbolic;
8275   Bsymbolic = B->ops->matmultsymbolic;
8276   if (Asymbolic == Bsymbolic){
8277     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8278     symbolic = Bsymbolic;
8279   } else { /* dispatch based on the type of A and B */
8280     char  symbolicname[256];
8281     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8282     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8283     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8284     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8285     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8286     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8287     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);
8288   }
8289   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8290   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8291   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8292   PetscFunctionReturn(0);
8293 }
8294 
8295 #undef __FUNCT__
8296 #define __FUNCT__ "MatMatMultNumeric"
8297 /*@
8298    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8299    Call this routine after first calling MatMatMultSymbolic().
8300 
8301    Neighbor-wise Collective on Mat
8302 
8303    Input Parameters:
8304 +  A - the left matrix
8305 -  B - the right matrix
8306 
8307    Output Parameters:
8308 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8309 
8310    Notes:
8311    C must have been created with MatMatMultSymbolic().
8312 
8313    This routine is currently implemented for
8314     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8315     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8316     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8317 
8318    Level: intermediate
8319 
8320 .seealso: MatMatMult(), MatMatMultSymbolic()
8321 @*/
8322 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8323 {
8324   PetscErrorCode ierr;
8325   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8326   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8327   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8328 
8329   PetscFunctionBegin;
8330   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8331   PetscValidType(A,1);
8332   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8333   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8334 
8335   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8336   PetscValidType(B,2);
8337   ierr = MatPreallocated(B);CHKERRQ(ierr);
8338   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8339   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8340 
8341   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8342   PetscValidType(C,3);
8343   ierr = MatPreallocated(C);CHKERRQ(ierr);
8344   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8345   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8346 
8347   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);
8348   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);
8349   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);
8350   ierr = MatPreallocated(A);CHKERRQ(ierr);
8351 
8352   Anumeric = A->ops->matmultnumeric;
8353   Bnumeric = B->ops->matmultnumeric;
8354   if (Anumeric == Bnumeric){
8355     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8356     numeric = Bnumeric;
8357   } else {
8358     char  numericname[256];
8359     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8360     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8361     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8362     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8363     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8364     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8365     if (!numeric)
8366       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);
8367   }
8368   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8369   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8370   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8371   PetscFunctionReturn(0);
8372 }
8373 
8374 #undef __FUNCT__
8375 #define __FUNCT__ "MatMatMultTranspose"
8376 /*@
8377    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8378 
8379    Neighbor-wise Collective on Mat
8380 
8381    Input Parameters:
8382 +  A - the left matrix
8383 .  B - the right matrix
8384 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8385 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8386 
8387    Output Parameters:
8388 .  C - the product matrix
8389 
8390    Notes:
8391    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8392 
8393    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8394 
8395   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8396    actually needed.
8397 
8398    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8399    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8400 
8401    Level: intermediate
8402 
8403 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8404 @*/
8405 PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8406 {
8407   PetscErrorCode ierr;
8408   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8409   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8410 
8411   PetscFunctionBegin;
8412   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8413   PetscValidType(A,1);
8414   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8415   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8416   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8417   PetscValidType(B,2);
8418   ierr = MatPreallocated(B);CHKERRQ(ierr);
8419   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8420   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8421   PetscValidPointer(C,3);
8422   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);
8423   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8424   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8425   ierr = MatPreallocated(A);CHKERRQ(ierr);
8426 
8427   fA = A->ops->matmulttranspose;
8428   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8429   fB = B->ops->matmulttranspose;
8430   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8431   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);
8432 
8433   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8434   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
8435   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8436 
8437   PetscFunctionReturn(0);
8438 }
8439 
8440 #undef __FUNCT__
8441 #define __FUNCT__ "MatGetRedundantMatrix"
8442 /*@C
8443    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8444 
8445    Collective on Mat
8446 
8447    Input Parameters:
8448 +  mat - the matrix
8449 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8450 .  subcomm - MPI communicator split from the communicator where mat resides in
8451 .  mlocal_red - number of local rows of the redundant matrix
8452 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8453 
8454    Output Parameter:
8455 .  matredundant - redundant matrix
8456 
8457    Notes:
8458    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8459    original matrix has not changed from that last call to MatGetRedundantMatrix().
8460 
8461    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8462    calling it.
8463 
8464    Only MPIAIJ matrix is supported.
8465 
8466    Level: advanced
8467 
8468    Concepts: subcommunicator
8469    Concepts: duplicate matrix
8470 
8471 .seealso: MatDestroy()
8472 @*/
8473 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8474 {
8475   PetscErrorCode ierr;
8476 
8477   PetscFunctionBegin;
8478   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8479   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8480     PetscValidPointer(*matredundant,6);
8481     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8482   }
8483   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8484   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8485   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8486   ierr = MatPreallocated(mat);CHKERRQ(ierr);
8487 
8488   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8489   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8490   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8491   PetscFunctionReturn(0);
8492 }
8493 
8494 #undef __FUNCT__
8495 #define __FUNCT__ "MatGetMultiProcBlock"
8496 /*@C
8497    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8498    a given 'mat' object. Each submatrix can span multiple procs.
8499 
8500    Collective on Mat
8501 
8502    Input Parameters:
8503 +  mat - the matrix
8504 -  subcomm - the subcommunicator obtained by com_split(comm)
8505 
8506    Output Parameter:
8507 .  subMat - 'parallel submatrices each spans a given subcomm
8508 
8509   Notes:
8510   The submatrix partition across processors is dicated by 'subComm' a
8511   communicator obtained by com_split(comm). The comm_split
8512   is not restriced to be grouped with consequitive original ranks.
8513 
8514   Due the comm_split() usage, the parallel layout of the submatrices
8515   map directly to the layout of the original matrix [wrt the local
8516   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8517   into the 'DiagonalMat' of the subMat, hence it is used directly from
8518   the subMat. However the offDiagMat looses some columns - and this is
8519   reconstructed with MatSetValues()
8520 
8521   Level: advanced
8522 
8523   Concepts: subcommunicator
8524   Concepts: submatrices
8525 
8526 .seealso: MatGetSubMatrices()
8527 @*/
8528 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8529 {
8530   PetscErrorCode ierr;
8531   PetscMPIInt    commsize,subCommSize;
8532 
8533   PetscFunctionBegin;
8534   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
8535   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
8536   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8537 
8538   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8539   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,subMat);CHKERRQ(ierr);
8540   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8541   PetscFunctionReturn(0);
8542 }
8543 
8544 #undef __FUNCT__
8545 #define __FUNCT__ "MatGetLocalSubMatrix"
8546 /*@
8547    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8548 
8549    Not Collective
8550 
8551    Input Arguments:
8552    mat - matrix to extract local submatrix from
8553    isrow - local row indices for submatrix
8554    iscol - local column indices for submatrix
8555 
8556    Output Arguments:
8557    submat - the submatrix
8558 
8559    Level: intermediate
8560 
8561    Notes:
8562    The submat should be returned with MatRestoreLocalSubMatrix().
8563 
8564    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
8565    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8566 
8567    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
8568    MatSetValuesBlockedLocal() will also be implemented.
8569 
8570 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8571 @*/
8572 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8573 {
8574   PetscErrorCode ierr;
8575 
8576   PetscFunctionBegin;
8577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8578   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8579   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8580   PetscCheckSameComm(isrow,2,iscol,3);
8581   PetscValidPointer(submat,4);
8582 
8583   if (mat->ops->getlocalsubmatrix) {
8584     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8585   } else {
8586     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
8587   }
8588   PetscFunctionReturn(0);
8589 }
8590 
8591 #undef __FUNCT__
8592 #define __FUNCT__ "MatRestoreLocalSubMatrix"
8593 /*@
8594    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8595 
8596    Not Collective
8597 
8598    Input Arguments:
8599    mat - matrix to extract local submatrix from
8600    isrow - local row indices for submatrix
8601    iscol - local column indices for submatrix
8602    submat - the submatrix
8603 
8604    Level: intermediate
8605 
8606 .seealso: MatGetLocalSubMatrix()
8607 @*/
8608 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8609 {
8610   PetscErrorCode ierr;
8611 
8612   PetscFunctionBegin;
8613   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8614   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8615   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8616   PetscCheckSameComm(isrow,2,iscol,3);
8617   PetscValidPointer(submat,4);
8618   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
8619 
8620   if (mat->ops->restorelocalsubmatrix) {
8621     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8622   } else {
8623     ierr = MatDestroy(submat);CHKERRQ(ierr);
8624   }
8625   *submat = PETSC_NULL;
8626   PetscFunctionReturn(0);
8627 }
8628 
8629 /* --------------------------------------------------------*/
8630 #undef __FUNCT__
8631 #define __FUNCT__ "MatFindZeroDiagonals"
8632 /*@
8633    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
8634 
8635    Collective on Mat
8636 
8637    Input Parameter:
8638 .  mat - the matrix
8639 
8640    Output Parameter:
8641 .  is - if any rows have zero diagonals this contains the list of them
8642 
8643    Level: developer
8644 
8645    Concepts: matrix-vector product
8646 
8647 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8648 @*/
8649 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
8650 {
8651   PetscErrorCode ierr;
8652 
8653   PetscFunctionBegin;
8654   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8655   PetscValidType(mat,1);
8656   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8657   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8658 
8659   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8660   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
8661   PetscFunctionReturn(0);
8662 }
8663