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