xref: /petsc/src/mat/interface/matrix.c (revision ed020824cf2871ebf0db89bae9162301a51fd7bc)
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__ "MatZeroRowsLocal"
5560 /*@C
5561    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5562    of a set of rows of a matrix; using local numbering of rows.
5563 
5564    Collective on Mat
5565 
5566    Input Parameters:
5567 +  mat - the matrix
5568 .  numRows - the number of rows to remove
5569 .  rows - the global row indices
5570 .  diag - value put in all diagonals of eliminated rows
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    Before calling MatZeroRowsLocal(), the user must first set the
5576    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5577 
5578    For the AIJ matrix formats this removes the old nonzero structure,
5579    but does not release memory.  For the dense and block diagonal
5580    formats this does not alter the nonzero structure.
5581 
5582    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5583    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5584    merely zeroed.
5585 
5586    The user can set a value in the diagonal entry (or for the AIJ and
5587    row formats can optionally remove the main diagonal entry from the
5588    nonzero structure as well, by passing 0.0 as the final argument).
5589 
5590    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5591    owns that are to be zeroed. This saves a global synchronization in the implementation.
5592 
5593    Level: intermediate
5594 
5595    Concepts: matrices^zeroing
5596 
5597 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5598 @*/
5599 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5600 {
5601   PetscErrorCode ierr;
5602   PetscMPIInt    size;
5603 
5604   PetscFunctionBegin;
5605   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5606   PetscValidType(mat,1);
5607   if (numRows) PetscValidIntPointer(rows,3);
5608   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5609   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5610   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5611 
5612   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5613   if (mat->ops->zerorowslocal) {
5614     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5615   } else if (size == 1) {
5616     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5617   } else {
5618     IS             is, newis;
5619     const PetscInt *newRows;
5620 
5621     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5622     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5623     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5624     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5625     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5626     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5627     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5628     ierr = ISDestroy(&is);CHKERRQ(ierr);
5629   }
5630   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5631 #if defined(PETSC_HAVE_CUSP)
5632   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5633     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5634   }
5635 #endif
5636   PetscFunctionReturn(0);
5637 }
5638 
5639 #undef __FUNCT__
5640 #define __FUNCT__ "MatZeroRowsLocalIS"
5641 /*@C
5642    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5643    of a set of rows of a matrix; using local numbering of rows.
5644 
5645    Collective on Mat
5646 
5647    Input Parameters:
5648 +  mat - the matrix
5649 .  is - index set of rows to remove
5650 .  diag - value put in all diagonals of eliminated rows
5651 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5652 -  b - optional vector of right hand side, that will be adjusted by provided solution
5653 
5654    Notes:
5655    Before calling MatZeroRowsLocalIS(), the user must first set the
5656    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5657 
5658    For the AIJ matrix formats this removes the old nonzero structure,
5659    but does not release memory.  For the dense and block diagonal
5660    formats this does not alter the nonzero structure.
5661 
5662    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5663    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5664    merely zeroed.
5665 
5666    The user can set a value in the diagonal entry (or for the AIJ and
5667    row formats can optionally remove the main diagonal entry from the
5668    nonzero structure as well, by passing 0.0 as the final argument).
5669 
5670    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5671    owns that are to be zeroed. This saves a global synchronization in the implementation.
5672 
5673    Level: intermediate
5674 
5675    Concepts: matrices^zeroing
5676 
5677 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5678 @*/
5679 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5680 {
5681   PetscErrorCode ierr;
5682   PetscInt       numRows;
5683   const PetscInt *rows;
5684 
5685   PetscFunctionBegin;
5686   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5687   PetscValidType(mat,1);
5688   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5689   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5690   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5691   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5692 
5693   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5694   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5695   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5696   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5697   PetscFunctionReturn(0);
5698 }
5699 
5700 #undef __FUNCT__
5701 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5702 /*@C
5703    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5704    of a set of rows and columns of a matrix; using local numbering of rows.
5705 
5706    Collective on Mat
5707 
5708    Input Parameters:
5709 +  mat - the matrix
5710 .  numRows - the number of rows to remove
5711 .  rows - the global row indices
5712 .  diag - value put in all diagonals of eliminated rows
5713 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5714 -  b - optional vector of right hand side, that will be adjusted by provided solution
5715 
5716    Notes:
5717    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5718    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5719 
5720    The user can set a value in the diagonal entry (or for the AIJ and
5721    row formats can optionally remove the main diagonal entry from the
5722    nonzero structure as well, by passing 0.0 as the final argument).
5723 
5724    Level: intermediate
5725 
5726    Concepts: matrices^zeroing
5727 
5728 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5729 @*/
5730 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5731 {
5732   PetscErrorCode ierr;
5733   PetscMPIInt    size;
5734 
5735   PetscFunctionBegin;
5736   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5737   PetscValidType(mat,1);
5738   if (numRows) PetscValidIntPointer(rows,3);
5739   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5740   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5741   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5742 
5743   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5744   if (size == 1) {
5745     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5746   } else {
5747     IS             is, newis;
5748     const PetscInt *newRows;
5749 
5750     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5751     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5752     ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
5753     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5754     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5755     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5756     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5757     ierr = ISDestroy(&is);CHKERRQ(ierr);
5758   }
5759   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5760 #if defined(PETSC_HAVE_CUSP)
5761   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5762     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5763   }
5764 #endif
5765   PetscFunctionReturn(0);
5766 }
5767 
5768 #undef __FUNCT__
5769 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5770 /*@C
5771    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5772    of a set of rows and columns of a matrix; using local numbering of rows.
5773 
5774    Collective on Mat
5775 
5776    Input Parameters:
5777 +  mat - the matrix
5778 .  is - index set of rows to remove
5779 .  diag - value put in all diagonals of eliminated rows
5780 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5781 -  b - optional vector of right hand side, that will be adjusted by provided solution
5782 
5783    Notes:
5784    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5785    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5786 
5787    The user can set a value in the diagonal entry (or for the AIJ and
5788    row formats can optionally remove the main diagonal entry from the
5789    nonzero structure as well, by passing 0.0 as the final argument).
5790 
5791    Level: intermediate
5792 
5793    Concepts: matrices^zeroing
5794 
5795 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5796 @*/
5797 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5798 {
5799   PetscErrorCode ierr;
5800   PetscInt       numRows;
5801   const PetscInt *rows;
5802 
5803   PetscFunctionBegin;
5804   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5805   PetscValidType(mat,1);
5806   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5807   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5808   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5809   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5810 
5811   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5812   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5813   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5814   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5815   PetscFunctionReturn(0);
5816 }
5817 
5818 #undef __FUNCT__
5819 #define __FUNCT__ "MatGetSize"
5820 /*@
5821    MatGetSize - Returns the numbers of rows and columns in a matrix.
5822 
5823    Not Collective
5824 
5825    Input Parameter:
5826 .  mat - the matrix
5827 
5828    Output Parameters:
5829 +  m - the number of global rows
5830 -  n - the number of global columns
5831 
5832    Note: both output parameters can be PETSC_NULL on input.
5833 
5834    Level: beginner
5835 
5836    Concepts: matrices^size
5837 
5838 .seealso: MatGetLocalSize()
5839 @*/
5840 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5841 {
5842   PetscFunctionBegin;
5843   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5844   if (m) *m = mat->rmap->N;
5845   if (n) *n = mat->cmap->N;
5846   PetscFunctionReturn(0);
5847 }
5848 
5849 #undef __FUNCT__
5850 #define __FUNCT__ "MatGetLocalSize"
5851 /*@
5852    MatGetLocalSize - Returns the number of rows and columns in a matrix
5853    stored locally.  This information may be implementation dependent, so
5854    use with care.
5855 
5856    Not Collective
5857 
5858    Input Parameters:
5859 .  mat - the matrix
5860 
5861    Output Parameters:
5862 +  m - the number of local rows
5863 -  n - the number of local columns
5864 
5865    Note: both output parameters can be PETSC_NULL on input.
5866 
5867    Level: beginner
5868 
5869    Concepts: matrices^local size
5870 
5871 .seealso: MatGetSize()
5872 @*/
5873 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5874 {
5875   PetscFunctionBegin;
5876   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5877   if (m) PetscValidIntPointer(m,2);
5878   if (n) PetscValidIntPointer(n,3);
5879   if (m) *m = mat->rmap->n;
5880   if (n) *n = mat->cmap->n;
5881   PetscFunctionReturn(0);
5882 }
5883 
5884 #undef __FUNCT__
5885 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5886 /*@
5887    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5888    this processor. (The columns of the "diagonal block")
5889 
5890    Not Collective, unless matrix has not been allocated, then collective on Mat
5891 
5892    Input Parameters:
5893 .  mat - the matrix
5894 
5895    Output Parameters:
5896 +  m - the global index of the first local column
5897 -  n - one more than the global index of the last local column
5898 
5899    Notes: both output parameters can be PETSC_NULL on input.
5900 
5901    Level: developer
5902 
5903    Concepts: matrices^column ownership
5904 
5905 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5906 
5907 @*/
5908 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5909 {
5910   PetscErrorCode ierr;
5911 
5912   PetscFunctionBegin;
5913   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5914   PetscValidType(mat,1);
5915   if (m) PetscValidIntPointer(m,2);
5916   if (n) PetscValidIntPointer(n,3);
5917   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5918   if (m) *m = mat->cmap->rstart;
5919   if (n) *n = mat->cmap->rend;
5920   PetscFunctionReturn(0);
5921 }
5922 
5923 #undef __FUNCT__
5924 #define __FUNCT__ "MatGetOwnershipRange"
5925 /*@
5926    MatGetOwnershipRange - Returns the range of matrix rows owned by
5927    this processor, assuming that the matrix is laid out with the first
5928    n1 rows on the first processor, the next n2 rows on the second, etc.
5929    For certain parallel layouts this range may not be well defined.
5930 
5931    Not Collective, unless matrix has not been allocated, then collective on Mat
5932 
5933    Input Parameters:
5934 .  mat - the matrix
5935 
5936    Output Parameters:
5937 +  m - the global index of the first local row
5938 -  n - one more than the global index of the last local row
5939 
5940    Note: both output parameters can be PETSC_NULL on input.
5941 
5942    Level: beginner
5943 
5944    Concepts: matrices^row ownership
5945 
5946 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5947 
5948 @*/
5949 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5950 {
5951   PetscErrorCode ierr;
5952 
5953   PetscFunctionBegin;
5954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5955   PetscValidType(mat,1);
5956   if (m) PetscValidIntPointer(m,2);
5957   if (n) PetscValidIntPointer(n,3);
5958   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5959   if (m) *m = mat->rmap->rstart;
5960   if (n) *n = mat->rmap->rend;
5961   PetscFunctionReturn(0);
5962 }
5963 
5964 #undef __FUNCT__
5965 #define __FUNCT__ "MatGetOwnershipRanges"
5966 /*@C
5967    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5968    each process
5969 
5970    Not Collective, unless matrix has not been allocated, then collective on Mat
5971 
5972    Input Parameters:
5973 .  mat - the matrix
5974 
5975    Output Parameters:
5976 .  ranges - start of each processors portion plus one more then the total length at the end
5977 
5978    Level: beginner
5979 
5980    Concepts: matrices^row ownership
5981 
5982 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5983 
5984 @*/
5985 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5986 {
5987   PetscErrorCode ierr;
5988 
5989   PetscFunctionBegin;
5990   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5991   PetscValidType(mat,1);
5992   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5993   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
5994   PetscFunctionReturn(0);
5995 }
5996 
5997 #undef __FUNCT__
5998 #define __FUNCT__ "MatGetOwnershipRangesColumn"
5999 /*@C
6000    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6001    this processor. (The columns of the "diagonal blocks" for each process)
6002 
6003    Not Collective, unless matrix has not been allocated, then collective on Mat
6004 
6005    Input Parameters:
6006 .  mat - the matrix
6007 
6008    Output Parameters:
6009 .  ranges - start of each processors portion plus one more then the total length at the end
6010 
6011    Level: beginner
6012 
6013    Concepts: matrices^column ownership
6014 
6015 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6016 
6017 @*/
6018 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6019 {
6020   PetscErrorCode ierr;
6021 
6022   PetscFunctionBegin;
6023   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6024   PetscValidType(mat,1);
6025   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6026   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6027   PetscFunctionReturn(0);
6028 }
6029 
6030 #undef __FUNCT__
6031 #define __FUNCT__ "MatILUFactorSymbolic"
6032 /*@C
6033    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6034    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6035    to complete the factorization.
6036 
6037    Collective on Mat
6038 
6039    Input Parameters:
6040 +  mat - the matrix
6041 .  row - row permutation
6042 .  column - column permutation
6043 -  info - structure containing
6044 $      levels - number of levels of fill.
6045 $      expected fill - as ratio of original fill.
6046 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6047                 missing diagonal entries)
6048 
6049    Output Parameters:
6050 .  fact - new matrix that has been symbolically factored
6051 
6052    Notes:
6053    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6054    choosing the fill factor for better efficiency.
6055 
6056    Most users should employ the simplified KSP interface for linear solvers
6057    instead of working directly with matrix algebra routines such as this.
6058    See, e.g., KSPCreate().
6059 
6060    Level: developer
6061 
6062   Concepts: matrices^symbolic LU factorization
6063   Concepts: matrices^factorization
6064   Concepts: LU^symbolic factorization
6065 
6066 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6067           MatGetOrdering(), MatFactorInfo
6068 
6069     Developer Note: fortran interface is not autogenerated as the f90
6070     interface defintion cannot be generated correctly [due to MatFactorInfo]
6071 
6072 @*/
6073 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6074 {
6075   PetscErrorCode ierr;
6076 
6077   PetscFunctionBegin;
6078   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6079   PetscValidType(mat,1);
6080   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6081   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6082   PetscValidPointer(info,4);
6083   PetscValidPointer(fact,5);
6084   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6085   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6086   if (!(fact)->ops->ilufactorsymbolic) {
6087     const MatSolverPackage spackage;
6088     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6089     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6090   }
6091   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6092   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6093   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6094 
6095   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6096   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6097   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6098   PetscFunctionReturn(0);
6099 }
6100 
6101 #undef __FUNCT__
6102 #define __FUNCT__ "MatICCFactorSymbolic"
6103 /*@C
6104    MatICCFactorSymbolic - Performs symbolic incomplete
6105    Cholesky factorization for a symmetric matrix.  Use
6106    MatCholeskyFactorNumeric() to complete the factorization.
6107 
6108    Collective on Mat
6109 
6110    Input Parameters:
6111 +  mat - the matrix
6112 .  perm - row and column permutation
6113 -  info - structure containing
6114 $      levels - number of levels of fill.
6115 $      expected fill - as ratio of original fill.
6116 
6117    Output Parameter:
6118 .  fact - the factored matrix
6119 
6120    Notes:
6121    Most users should employ the KSP interface for linear solvers
6122    instead of working directly with matrix algebra routines such as this.
6123    See, e.g., KSPCreate().
6124 
6125    Level: developer
6126 
6127   Concepts: matrices^symbolic incomplete Cholesky factorization
6128   Concepts: matrices^factorization
6129   Concepts: Cholsky^symbolic factorization
6130 
6131 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6132 
6133     Developer Note: fortran interface is not autogenerated as the f90
6134     interface defintion cannot be generated correctly [due to MatFactorInfo]
6135 
6136 @*/
6137 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6138 {
6139   PetscErrorCode ierr;
6140 
6141   PetscFunctionBegin;
6142   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6143   PetscValidType(mat,1);
6144   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6145   PetscValidPointer(info,3);
6146   PetscValidPointer(fact,4);
6147   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6148   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6149   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6150   if (!(fact)->ops->iccfactorsymbolic) {
6151     const MatSolverPackage spackage;
6152     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6153     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6154   }
6155   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6156   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6157 
6158   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6159   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6160   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6161   PetscFunctionReturn(0);
6162 }
6163 
6164 #undef __FUNCT__
6165 #define __FUNCT__ "MatGetArray"
6166 /*@C
6167    MatGetArray - Returns a pointer to the element values in the matrix.
6168    The result of this routine is dependent on the underlying matrix data
6169    structure, and may not even work for certain matrix types.  You MUST
6170    call MatRestoreArray() when you no longer need to access the array.
6171 
6172    Not Collective
6173 
6174    Input Parameter:
6175 .  mat - the matrix
6176 
6177    Output Parameter:
6178 .  v - the location of the values
6179 
6180 
6181    Fortran Note:
6182    This routine is used differently from Fortran, e.g.,
6183 .vb
6184         Mat         mat
6185         PetscScalar mat_array(1)
6186         PetscOffset i_mat
6187         PetscErrorCode ierr
6188         call MatGetArray(mat,mat_array,i_mat,ierr)
6189 
6190   C  Access first local entry in matrix; note that array is
6191   C  treated as one dimensional
6192         value = mat_array(i_mat + 1)
6193 
6194         [... other code ...]
6195         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6196 .ve
6197 
6198    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6199    src/mat/examples/tests for details.
6200 
6201    Level: advanced
6202 
6203    Concepts: matrices^access array
6204 
6205 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6206 @*/
6207 PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6208 {
6209   PetscErrorCode ierr;
6210 
6211   PetscFunctionBegin;
6212   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6213   PetscValidType(mat,1);
6214   PetscValidPointer(v,2);
6215   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6216   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6217   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6218   CHKMEMQ;
6219   PetscFunctionReturn(0);
6220 }
6221 
6222 #undef __FUNCT__
6223 #define __FUNCT__ "MatRestoreArray"
6224 /*@C
6225    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6226 
6227    Not Collective
6228 
6229    Input Parameter:
6230 +  mat - the matrix
6231 -  v - the location of the values
6232 
6233    Fortran Note:
6234    This routine is used differently from Fortran, e.g.,
6235 .vb
6236         Mat         mat
6237         PetscScalar mat_array(1)
6238         PetscOffset i_mat
6239         PetscErrorCode ierr
6240         call MatGetArray(mat,mat_array,i_mat,ierr)
6241 
6242   C  Access first local entry in matrix; note that array is
6243   C  treated as one dimensional
6244         value = mat_array(i_mat + 1)
6245 
6246         [... other code ...]
6247         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6248 .ve
6249 
6250    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6251    src/mat/examples/tests for details
6252 
6253    Level: advanced
6254 
6255 .seealso: MatGetArray(), MatRestoreArrayF90()
6256 @*/
6257 PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6258 {
6259   PetscErrorCode ierr;
6260 
6261   PetscFunctionBegin;
6262   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6263   PetscValidType(mat,1);
6264   PetscValidPointer(v,2);
6265   CHKMEMQ;
6266   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6267   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6268   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6269 #if defined(PETSC_HAVE_CUSP)
6270   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6271     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6272   }
6273 #endif
6274   PetscFunctionReturn(0);
6275 }
6276 
6277 #undef __FUNCT__
6278 #define __FUNCT__ "MatGetSubMatrices"
6279 /*@C
6280    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6281    points to an array of valid matrices, they may be reused to store the new
6282    submatrices.
6283 
6284    Collective on Mat
6285 
6286    Input Parameters:
6287 +  mat - the matrix
6288 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6289 .  irow, icol - index sets of rows and columns to extract
6290 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6291 
6292    Output Parameter:
6293 .  submat - the array of submatrices
6294 
6295    Notes:
6296    MatGetSubMatrices() can extract ONLY sequential submatrices
6297    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6298    to extract a parallel submatrix.
6299 
6300    When extracting submatrices from a parallel matrix, each processor can
6301    form a different submatrix by setting the rows and columns of its
6302    individual index sets according to the local submatrix desired.
6303 
6304    When finished using the submatrices, the user should destroy
6305    them with MatDestroyMatrices().
6306 
6307    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6308    original matrix has not changed from that last call to MatGetSubMatrices().
6309 
6310    This routine creates the matrices in submat; you should NOT create them before
6311    calling it. It also allocates the array of matrix pointers submat.
6312 
6313    For BAIJ matrices the index sets must respect the block structure, that is if they
6314    request one row/column in a block, they must request all rows/columns that are in
6315    that block. For example, if the block size is 2 you cannot request just row 0 and
6316    column 0.
6317 
6318    Fortran Note:
6319    The Fortran interface is slightly different from that given below; it
6320    requires one to pass in  as submat a Mat (integer) array of size at least m.
6321 
6322    Level: advanced
6323 
6324    Concepts: matrices^accessing submatrices
6325    Concepts: submatrices
6326 
6327 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6328 @*/
6329 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6330 {
6331   PetscErrorCode ierr;
6332   PetscInt        i;
6333   PetscBool       eq;
6334 
6335   PetscFunctionBegin;
6336   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6337   PetscValidType(mat,1);
6338   if (n) {
6339     PetscValidPointer(irow,3);
6340     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6341     PetscValidPointer(icol,4);
6342     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6343   }
6344   PetscValidPointer(submat,6);
6345   if (n && scall == MAT_REUSE_MATRIX) {
6346     PetscValidPointer(*submat,6);
6347     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6348   }
6349   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6350   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6351   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6352   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6353 
6354   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6355   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6356   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6357   for (i=0; i<n; i++) {
6358     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6359       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6360       if (eq) {
6361 	if (mat->symmetric){
6362 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6363 	} else if (mat->hermitian) {
6364 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6365 	} else if (mat->structurally_symmetric) {
6366 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6367 	}
6368       }
6369     }
6370   }
6371   PetscFunctionReturn(0);
6372 }
6373 
6374 #undef __FUNCT__
6375 #define __FUNCT__ "MatGetSubMatricesParallel"
6376 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6377 {
6378   PetscErrorCode ierr;
6379   PetscInt        i;
6380   PetscBool       eq;
6381 
6382   PetscFunctionBegin;
6383   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6384   PetscValidType(mat,1);
6385   if (n) {
6386     PetscValidPointer(irow,3);
6387     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6388     PetscValidPointer(icol,4);
6389     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6390   }
6391   PetscValidPointer(submat,6);
6392   if (n && scall == MAT_REUSE_MATRIX) {
6393     PetscValidPointer(*submat,6);
6394     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6395   }
6396   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6397   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6398   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6399   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6400 
6401   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6402   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6403   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6404   for (i=0; i<n; i++) {
6405     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6406       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6407       if (eq) {
6408 	if (mat->symmetric){
6409 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6410 	} else if (mat->hermitian) {
6411 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6412 	} else if (mat->structurally_symmetric) {
6413 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6414 	}
6415       }
6416     }
6417   }
6418   PetscFunctionReturn(0);
6419 }
6420 
6421 #undef __FUNCT__
6422 #define __FUNCT__ "MatDestroyMatrices"
6423 /*@C
6424    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6425 
6426    Collective on Mat
6427 
6428    Input Parameters:
6429 +  n - the number of local matrices
6430 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6431                        sequence of MatGetSubMatrices())
6432 
6433    Level: advanced
6434 
6435     Notes: Frees not only the matrices, but also the array that contains the matrices
6436            In Fortran will not free the array.
6437 
6438 .seealso: MatGetSubMatrices()
6439 @*/
6440 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6441 {
6442   PetscErrorCode ierr;
6443   PetscInt       i;
6444 
6445   PetscFunctionBegin;
6446   if (!*mat) PetscFunctionReturn(0);
6447   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6448   PetscValidPointer(mat,2);
6449   for (i=0; i<n; i++) {
6450     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6451   }
6452   /* memory is allocated even if n = 0 */
6453   ierr = PetscFree(*mat);CHKERRQ(ierr);
6454   *mat = PETSC_NULL;
6455   PetscFunctionReturn(0);
6456 }
6457 
6458 #undef __FUNCT__
6459 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6460 /*@C
6461    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6462 
6463    Collective on Mat
6464 
6465    Input Parameters:
6466 .  mat - the matrix
6467 
6468    Output Parameter:
6469 .  matstruct - the sequential matrix with the nonzero structure of mat
6470 
6471   Level: intermediate
6472 
6473 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6474 @*/
6475 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6476 {
6477   PetscErrorCode ierr;
6478 
6479   PetscFunctionBegin;
6480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6481   PetscValidPointer(matstruct,2);
6482 
6483   PetscValidType(mat,1);
6484   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6485   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6486 
6487   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6488   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6489   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6490   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6491   PetscFunctionReturn(0);
6492 }
6493 
6494 #undef __FUNCT__
6495 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6496 /*@C
6497    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6498 
6499    Collective on Mat
6500 
6501    Input Parameters:
6502 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6503                        sequence of MatGetSequentialNonzeroStructure())
6504 
6505    Level: advanced
6506 
6507     Notes: Frees not only the matrices, but also the array that contains the matrices
6508 
6509 .seealso: MatGetSeqNonzeroStructure()
6510 @*/
6511 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6512 {
6513   PetscErrorCode ierr;
6514 
6515   PetscFunctionBegin;
6516   PetscValidPointer(mat,1);
6517   ierr = MatDestroy(mat);CHKERRQ(ierr);
6518   PetscFunctionReturn(0);
6519 }
6520 
6521 #undef __FUNCT__
6522 #define __FUNCT__ "MatIncreaseOverlap"
6523 /*@
6524    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6525    replaces the index sets by larger ones that represent submatrices with
6526    additional overlap.
6527 
6528    Collective on Mat
6529 
6530    Input Parameters:
6531 +  mat - the matrix
6532 .  n   - the number of index sets
6533 .  is  - the array of index sets (these index sets will changed during the call)
6534 -  ov  - the additional overlap requested
6535 
6536    Level: developer
6537 
6538    Concepts: overlap
6539    Concepts: ASM^computing overlap
6540 
6541 .seealso: MatGetSubMatrices()
6542 @*/
6543 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6544 {
6545   PetscErrorCode ierr;
6546 
6547   PetscFunctionBegin;
6548   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6549   PetscValidType(mat,1);
6550   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6551   if (n) {
6552     PetscValidPointer(is,3);
6553     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6554   }
6555   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6556   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6557   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6558 
6559   if (!ov) PetscFunctionReturn(0);
6560   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6561   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6562   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6563   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6564   PetscFunctionReturn(0);
6565 }
6566 
6567 #undef __FUNCT__
6568 #define __FUNCT__ "MatGetBlockSize"
6569 /*@
6570    MatGetBlockSize - Returns the matrix block size; useful especially for the
6571    block row and block diagonal formats.
6572 
6573    Not Collective
6574 
6575    Input Parameter:
6576 .  mat - the matrix
6577 
6578    Output Parameter:
6579 .  bs - block size
6580 
6581    Notes:
6582    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6583 
6584    Level: intermediate
6585 
6586    Concepts: matrices^block size
6587 
6588 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6589 @*/
6590 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6591 {
6592   PetscErrorCode ierr;
6593 
6594   PetscFunctionBegin;
6595   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6596   PetscValidType(mat,1);
6597   PetscValidIntPointer(bs,2);
6598   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6599   *bs = mat->rmap->bs;
6600   PetscFunctionReturn(0);
6601 }
6602 
6603 #undef __FUNCT__
6604 #define __FUNCT__ "MatSetBlockSize"
6605 /*@
6606    MatSetBlockSize - Sets the matrix block size; for many matrix types you
6607      cannot use this and MUST set the blocksize when you preallocate the matrix
6608 
6609    Logically Collective on Mat
6610 
6611    Input Parameters:
6612 +  mat - the matrix
6613 -  bs - block size
6614 
6615    Notes:
6616      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6617      it is not possible to change BAIJ block sizes after preallocation.
6618 
6619    Level: intermediate
6620 
6621    Concepts: matrices^block size
6622 
6623 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6624 @*/
6625 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6626 {
6627   PetscErrorCode ierr;
6628 
6629   PetscFunctionBegin;
6630   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6631   PetscValidType(mat,1);
6632   PetscValidLogicalCollectiveInt(mat,bs,2);
6633   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6634   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6635   if (mat->ops->setblocksize) {
6636     ierr = (*mat->ops->setblocksize)(mat,bs);CHKERRQ(ierr);
6637   } else {
6638     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6639   }
6640   PetscFunctionReturn(0);
6641 }
6642 
6643 #undef __FUNCT__
6644 #define __FUNCT__ "MatGetRowIJ"
6645 /*@C
6646     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6647 
6648    Collective on Mat
6649 
6650     Input Parameters:
6651 +   mat - the matrix
6652 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6653 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6654 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6655                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6656                  always used.
6657 
6658     Output Parameters:
6659 +   n - number of rows in the (possibly compressed) matrix
6660 .   ia - the row pointers [of length n+1]
6661 .   ja - the column indices
6662 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6663            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6664 
6665     Level: developer
6666 
6667     Notes: You CANNOT change any of the ia[] or ja[] values.
6668 
6669            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6670 
6671     Fortran Node
6672 
6673            In Fortran use
6674 $           PetscInt ia(1), ja(1)
6675 $           PetscOffset iia, jja
6676 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6677 $
6678 $          or
6679 $
6680 $           PetscScalar, pointer :: xx_v(:)
6681 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6682 
6683 
6684        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6685 
6686 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6687 @*/
6688 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6689 {
6690   PetscErrorCode ierr;
6691 
6692   PetscFunctionBegin;
6693   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6694   PetscValidType(mat,1);
6695   PetscValidIntPointer(n,4);
6696   if (ia) PetscValidIntPointer(ia,5);
6697   if (ja) PetscValidIntPointer(ja,6);
6698   PetscValidIntPointer(done,7);
6699   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6700   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6701   else {
6702     *done = PETSC_TRUE;
6703     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6704     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6705     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6706   }
6707   PetscFunctionReturn(0);
6708 }
6709 
6710 #undef __FUNCT__
6711 #define __FUNCT__ "MatGetColumnIJ"
6712 /*@C
6713     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6714 
6715     Collective on Mat
6716 
6717     Input Parameters:
6718 +   mat - the matrix
6719 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6720 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6721                 symmetrized
6722 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6723                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6724                  always used.
6725 
6726     Output Parameters:
6727 +   n - number of columns in the (possibly compressed) matrix
6728 .   ia - the column pointers
6729 .   ja - the row indices
6730 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6731 
6732     Level: developer
6733 
6734 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6735 @*/
6736 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6737 {
6738   PetscErrorCode ierr;
6739 
6740   PetscFunctionBegin;
6741   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6742   PetscValidType(mat,1);
6743   PetscValidIntPointer(n,4);
6744   if (ia) PetscValidIntPointer(ia,5);
6745   if (ja) PetscValidIntPointer(ja,6);
6746   PetscValidIntPointer(done,7);
6747   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6748   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6749   else {
6750     *done = PETSC_TRUE;
6751     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6752   }
6753   PetscFunctionReturn(0);
6754 }
6755 
6756 #undef __FUNCT__
6757 #define __FUNCT__ "MatRestoreRowIJ"
6758 /*@C
6759     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6760     MatGetRowIJ().
6761 
6762     Collective on Mat
6763 
6764     Input Parameters:
6765 +   mat - the matrix
6766 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6767 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6768                 symmetrized
6769 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6770                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6771                  always used.
6772 
6773     Output Parameters:
6774 +   n - size of (possibly compressed) matrix
6775 .   ia - the row pointers
6776 .   ja - the column indices
6777 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6778 
6779     Level: developer
6780 
6781 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6782 @*/
6783 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6784 {
6785   PetscErrorCode ierr;
6786 
6787   PetscFunctionBegin;
6788   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6789   PetscValidType(mat,1);
6790   if (ia) PetscValidIntPointer(ia,5);
6791   if (ja) PetscValidIntPointer(ja,6);
6792   PetscValidIntPointer(done,7);
6793   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6794 
6795   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6796   else {
6797     *done = PETSC_TRUE;
6798     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6799   }
6800   PetscFunctionReturn(0);
6801 }
6802 
6803 #undef __FUNCT__
6804 #define __FUNCT__ "MatRestoreColumnIJ"
6805 /*@C
6806     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6807     MatGetColumnIJ().
6808 
6809     Collective on Mat
6810 
6811     Input Parameters:
6812 +   mat - the matrix
6813 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6814 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6815                 symmetrized
6816 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6817                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6818                  always used.
6819 
6820     Output Parameters:
6821 +   n - size of (possibly compressed) matrix
6822 .   ia - the column pointers
6823 .   ja - the row indices
6824 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6825 
6826     Level: developer
6827 
6828 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6829 @*/
6830 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6831 {
6832   PetscErrorCode ierr;
6833 
6834   PetscFunctionBegin;
6835   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6836   PetscValidType(mat,1);
6837   if (ia) PetscValidIntPointer(ia,5);
6838   if (ja) PetscValidIntPointer(ja,6);
6839   PetscValidIntPointer(done,7);
6840   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6841 
6842   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6843   else {
6844     *done = PETSC_TRUE;
6845     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6846   }
6847   PetscFunctionReturn(0);
6848 }
6849 
6850 #undef __FUNCT__
6851 #define __FUNCT__ "MatColoringPatch"
6852 /*@C
6853     MatColoringPatch -Used inside matrix coloring routines that
6854     use MatGetRowIJ() and/or MatGetColumnIJ().
6855 
6856     Collective on Mat
6857 
6858     Input Parameters:
6859 +   mat - the matrix
6860 .   ncolors - max color value
6861 .   n   - number of entries in colorarray
6862 -   colorarray - array indicating color for each column
6863 
6864     Output Parameters:
6865 .   iscoloring - coloring generated using colorarray information
6866 
6867     Level: developer
6868 
6869 .seealso: MatGetRowIJ(), MatGetColumnIJ()
6870 
6871 @*/
6872 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6873 {
6874   PetscErrorCode ierr;
6875 
6876   PetscFunctionBegin;
6877   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6878   PetscValidType(mat,1);
6879   PetscValidIntPointer(colorarray,4);
6880   PetscValidPointer(iscoloring,5);
6881   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6882 
6883   if (!mat->ops->coloringpatch){
6884     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6885   } else {
6886     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
6887   }
6888   PetscFunctionReturn(0);
6889 }
6890 
6891 
6892 #undef __FUNCT__
6893 #define __FUNCT__ "MatSetUnfactored"
6894 /*@
6895    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6896 
6897    Logically Collective on Mat
6898 
6899    Input Parameter:
6900 .  mat - the factored matrix to be reset
6901 
6902    Notes:
6903    This routine should be used only with factored matrices formed by in-place
6904    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6905    format).  This option can save memory, for example, when solving nonlinear
6906    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6907    ILU(0) preconditioner.
6908 
6909    Note that one can specify in-place ILU(0) factorization by calling
6910 .vb
6911      PCType(pc,PCILU);
6912      PCFactorSeUseInPlace(pc);
6913 .ve
6914    or by using the options -pc_type ilu -pc_factor_in_place
6915 
6916    In-place factorization ILU(0) can also be used as a local
6917    solver for the blocks within the block Jacobi or additive Schwarz
6918    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
6919    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6920    local solver options.
6921 
6922    Most users should employ the simplified KSP interface for linear solvers
6923    instead of working directly with matrix algebra routines such as this.
6924    See, e.g., KSPCreate().
6925 
6926    Level: developer
6927 
6928 .seealso: PCFactorSetUseInPlace()
6929 
6930    Concepts: matrices^unfactored
6931 
6932 @*/
6933 PetscErrorCode  MatSetUnfactored(Mat mat)
6934 {
6935   PetscErrorCode ierr;
6936 
6937   PetscFunctionBegin;
6938   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6939   PetscValidType(mat,1);
6940   ierr = MatPreallocated(mat);CHKERRQ(ierr);
6941   mat->factortype = MAT_FACTOR_NONE;
6942   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
6943   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
6944   PetscFunctionReturn(0);
6945 }
6946 
6947 /*MC
6948     MatGetArrayF90 - Accesses a matrix array from Fortran90.
6949 
6950     Synopsis:
6951     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
6952 
6953     Not collective
6954 
6955     Input Parameter:
6956 .   x - matrix
6957 
6958     Output Parameters:
6959 +   xx_v - the Fortran90 pointer to the array
6960 -   ierr - error code
6961 
6962     Example of Usage:
6963 .vb
6964       PetscScalar, pointer xx_v(:,:)
6965       ....
6966       call MatGetArrayF90(x,xx_v,ierr)
6967       a = xx_v(3)
6968       call MatRestoreArrayF90(x,xx_v,ierr)
6969 .ve
6970 
6971     Notes:
6972     Not yet supported for all F90 compilers
6973 
6974     Level: advanced
6975 
6976 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
6977 
6978     Concepts: matrices^accessing array
6979 
6980 M*/
6981 
6982 /*MC
6983     MatRestoreArrayF90 - Restores a matrix array that has been
6984     accessed with MatGetArrayF90().
6985 
6986     Synopsis:
6987     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
6988 
6989     Not collective
6990 
6991     Input Parameters:
6992 +   x - matrix
6993 -   xx_v - the Fortran90 pointer to the array
6994 
6995     Output Parameter:
6996 .   ierr - error code
6997 
6998     Example of Usage:
6999 .vb
7000        PetscScalar, pointer xx_v(:)
7001        ....
7002        call MatGetArrayF90(x,xx_v,ierr)
7003        a = xx_v(3)
7004        call MatRestoreArrayF90(x,xx_v,ierr)
7005 .ve
7006 
7007     Notes:
7008     Not yet supported for all F90 compilers
7009 
7010     Level: advanced
7011 
7012 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7013 
7014 M*/
7015 
7016 
7017 #undef __FUNCT__
7018 #define __FUNCT__ "MatGetSubMatrix"
7019 /*@
7020     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7021                       as the original matrix.
7022 
7023     Collective on Mat
7024 
7025     Input Parameters:
7026 +   mat - the original matrix
7027 .   isrow - parallel IS containing the rows this processor should obtain
7028 .   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.
7029 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7030 
7031     Output Parameter:
7032 .   newmat - the new submatrix, of the same type as the old
7033 
7034     Level: advanced
7035 
7036     Notes:
7037     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7038 
7039     The rows in isrow will be sorted into the same order as the original matrix on each process.
7040 
7041       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7042    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7043    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7044    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7045    you are finished using it.
7046 
7047     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7048     the input matrix.
7049 
7050     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7051 
7052    Example usage:
7053    Consider the following 8x8 matrix with 34 non-zero values, that is
7054    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7055    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7056    as follows:
7057 
7058 .vb
7059             1  2  0  |  0  3  0  |  0  4
7060     Proc0   0  5  6  |  7  0  0  |  8  0
7061             9  0 10  | 11  0  0  | 12  0
7062     -------------------------------------
7063            13  0 14  | 15 16 17  |  0  0
7064     Proc1   0 18  0  | 19 20 21  |  0  0
7065             0  0  0  | 22 23  0  | 24  0
7066     -------------------------------------
7067     Proc2  25 26 27  |  0  0 28  | 29  0
7068            30  0  0  | 31 32 33  |  0 34
7069 .ve
7070 
7071     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7072 
7073 .vb
7074             2  0  |  0  3  0  |  0
7075     Proc0   5  6  |  7  0  0  |  8
7076     -------------------------------
7077     Proc1  18  0  | 19 20 21  |  0
7078     -------------------------------
7079     Proc2  26 27  |  0  0 28  | 29
7080             0  0  | 31 32 33  |  0
7081 .ve
7082 
7083 
7084     Concepts: matrices^submatrices
7085 
7086 .seealso: MatGetSubMatrices()
7087 @*/
7088 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7089 {
7090   PetscErrorCode ierr;
7091   PetscMPIInt    size;
7092   Mat            *local;
7093   IS             iscoltmp;
7094 
7095   PetscFunctionBegin;
7096   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7097   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7098   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7099   PetscValidPointer(newmat,5);
7100   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7101   PetscValidType(mat,1);
7102   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7103   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7104   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7105 
7106   if (!iscol) {
7107     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7108   } else {
7109     iscoltmp = iscol;
7110   }
7111 
7112   /* if original matrix is on just one processor then use submatrix generated */
7113   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7114     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7115     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7116     PetscFunctionReturn(0);
7117   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7118     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7119     *newmat = *local;
7120     ierr    = PetscFree(local);CHKERRQ(ierr);
7121     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7122     PetscFunctionReturn(0);
7123   } else if (!mat->ops->getsubmatrix) {
7124     /* Create a new matrix type that implements the operation using the full matrix */
7125     switch (cll) {
7126       case MAT_INITIAL_MATRIX:
7127         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7128         break;
7129       case MAT_REUSE_MATRIX:
7130         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7131         break;
7132       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7133     }
7134     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7135     PetscFunctionReturn(0);
7136   }
7137 
7138   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7139   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7140   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7141   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7142   PetscFunctionReturn(0);
7143 }
7144 
7145 #undef __FUNCT__
7146 #define __FUNCT__ "MatStashSetInitialSize"
7147 /*@
7148    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7149    used during the assembly process to store values that belong to
7150    other processors.
7151 
7152    Not Collective
7153 
7154    Input Parameters:
7155 +  mat   - the matrix
7156 .  size  - the initial size of the stash.
7157 -  bsize - the initial size of the block-stash(if used).
7158 
7159    Options Database Keys:
7160 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7161 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7162 
7163    Level: intermediate
7164 
7165    Notes:
7166      The block-stash is used for values set with MatSetValuesBlocked() while
7167      the stash is used for values set with MatSetValues()
7168 
7169      Run with the option -info and look for output of the form
7170      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7171      to determine the appropriate value, MM, to use for size and
7172      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7173      to determine the value, BMM to use for bsize
7174 
7175    Concepts: stash^setting matrix size
7176    Concepts: matrices^stash
7177 
7178 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7179 
7180 @*/
7181 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7182 {
7183   PetscErrorCode ierr;
7184 
7185   PetscFunctionBegin;
7186   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7187   PetscValidType(mat,1);
7188   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7189   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7190   PetscFunctionReturn(0);
7191 }
7192 
7193 #undef __FUNCT__
7194 #define __FUNCT__ "MatInterpolateAdd"
7195 /*@
7196    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7197      the matrix
7198 
7199    Neighbor-wise Collective on Mat
7200 
7201    Input Parameters:
7202 +  mat   - the matrix
7203 .  x,y - the vectors
7204 -  w - where the result is stored
7205 
7206    Level: intermediate
7207 
7208    Notes:
7209     w may be the same vector as y.
7210 
7211     This allows one to use either the restriction or interpolation (its transpose)
7212     matrix to do the interpolation
7213 
7214     Concepts: interpolation
7215 
7216 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7217 
7218 @*/
7219 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7220 {
7221   PetscErrorCode ierr;
7222   PetscInt       M,N,Ny;
7223 
7224   PetscFunctionBegin;
7225   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7226   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7227   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7228   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7229   PetscValidType(A,1);
7230   ierr = MatPreallocated(A);CHKERRQ(ierr);
7231   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7232   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7233   if (M == Ny) {
7234     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7235   } else {
7236     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7237   }
7238   PetscFunctionReturn(0);
7239 }
7240 
7241 #undef __FUNCT__
7242 #define __FUNCT__ "MatInterpolate"
7243 /*@
7244    MatInterpolate - y = A*x or A'*x depending on the shape of
7245      the matrix
7246 
7247    Neighbor-wise Collective on Mat
7248 
7249    Input Parameters:
7250 +  mat   - the matrix
7251 -  x,y - the vectors
7252 
7253    Level: intermediate
7254 
7255    Notes:
7256     This allows one to use either the restriction or interpolation (its transpose)
7257     matrix to do the interpolation
7258 
7259    Concepts: matrices^interpolation
7260 
7261 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7262 
7263 @*/
7264 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7265 {
7266   PetscErrorCode ierr;
7267   PetscInt       M,N,Ny;
7268 
7269   PetscFunctionBegin;
7270   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7271   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7272   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7273   PetscValidType(A,1);
7274   ierr = MatPreallocated(A);CHKERRQ(ierr);
7275   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7276   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7277   if (M == Ny) {
7278     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7279   } else {
7280     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7281   }
7282   PetscFunctionReturn(0);
7283 }
7284 
7285 #undef __FUNCT__
7286 #define __FUNCT__ "MatRestrict"
7287 /*@
7288    MatRestrict - y = A*x or A'*x
7289 
7290    Neighbor-wise Collective on Mat
7291 
7292    Input Parameters:
7293 +  mat   - the matrix
7294 -  x,y - the vectors
7295 
7296    Level: intermediate
7297 
7298    Notes:
7299     This allows one to use either the restriction or interpolation (its transpose)
7300     matrix to do the restriction
7301 
7302    Concepts: matrices^restriction
7303 
7304 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7305 
7306 @*/
7307 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7308 {
7309   PetscErrorCode ierr;
7310   PetscInt       M,N,Ny;
7311 
7312   PetscFunctionBegin;
7313   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7314   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7315   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7316   PetscValidType(A,1);
7317   ierr = MatPreallocated(A);CHKERRQ(ierr);
7318 
7319   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7320   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7321   if (M == Ny) {
7322     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7323   } else {
7324     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7325   }
7326   PetscFunctionReturn(0);
7327 }
7328 
7329 #undef __FUNCT__
7330 #define __FUNCT__ "MatSetNullSpace"
7331 /*@
7332    MatSetNullSpace - attaches a null space to a matrix.
7333         This null space will be removed from the resulting vector whenever
7334         MatMult() is called
7335 
7336    Logically Collective on Mat and MatNullSpace
7337 
7338    Input Parameters:
7339 +  mat - the matrix
7340 -  nullsp - the null space object
7341 
7342    Level: developer
7343 
7344    Notes:
7345       Overwrites any previous null space that may have been attached
7346 
7347    Concepts: null space^attaching to matrix
7348 
7349 .seealso: MatCreate(), MatNullSpaceCreate()
7350 @*/
7351 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7352 {
7353   PetscErrorCode ierr;
7354 
7355   PetscFunctionBegin;
7356   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7357   PetscValidType(mat,1);
7358   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7359   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7360   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7361   if (mat->nullsp) { ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); }
7362   mat->nullsp = nullsp;
7363   PetscFunctionReturn(0);
7364 }
7365 
7366 #undef __FUNCT__
7367 #define __FUNCT__ "MatICCFactor"
7368 /*@C
7369    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7370 
7371    Collective on Mat
7372 
7373    Input Parameters:
7374 +  mat - the matrix
7375 .  row - row/column permutation
7376 .  fill - expected fill factor >= 1.0
7377 -  level - level of fill, for ICC(k)
7378 
7379    Notes:
7380    Probably really in-place only when level of fill is zero, otherwise allocates
7381    new space to store factored matrix and deletes previous memory.
7382 
7383    Most users should employ the simplified KSP interface for linear solvers
7384    instead of working directly with matrix algebra routines such as this.
7385    See, e.g., KSPCreate().
7386 
7387    Level: developer
7388 
7389    Concepts: matrices^incomplete Cholesky factorization
7390    Concepts: Cholesky factorization
7391 
7392 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7393 
7394     Developer Note: fortran interface is not autogenerated as the f90
7395     interface defintion cannot be generated correctly [due to MatFactorInfo]
7396 
7397 @*/
7398 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7399 {
7400   PetscErrorCode ierr;
7401 
7402   PetscFunctionBegin;
7403   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7404   PetscValidType(mat,1);
7405   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7406   PetscValidPointer(info,3);
7407   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7408   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7409   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7410   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7411   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7412   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7413   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7414   PetscFunctionReturn(0);
7415 }
7416 
7417 #undef __FUNCT__
7418 #define __FUNCT__ "MatSetValuesAdic"
7419 /*@
7420    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7421 
7422    Not Collective
7423 
7424    Input Parameters:
7425 +  mat - the matrix
7426 -  v - the values compute with ADIC
7427 
7428    Level: developer
7429 
7430    Notes:
7431      Must call MatSetColoring() before using this routine. Also this matrix must already
7432      have its nonzero pattern determined.
7433 
7434 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7435           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7436 @*/
7437 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7438 {
7439   PetscErrorCode ierr;
7440 
7441   PetscFunctionBegin;
7442   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7443   PetscValidType(mat,1);
7444   PetscValidPointer(mat,2);
7445 
7446   if (!mat->assembled) {
7447     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7448   }
7449   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7450   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7451   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7452   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7453   ierr = MatView_Private(mat);CHKERRQ(ierr);
7454   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7455   PetscFunctionReturn(0);
7456 }
7457 
7458 
7459 #undef __FUNCT__
7460 #define __FUNCT__ "MatSetColoring"
7461 /*@
7462    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7463 
7464    Not Collective
7465 
7466    Input Parameters:
7467 +  mat - the matrix
7468 -  coloring - the coloring
7469 
7470    Level: developer
7471 
7472 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7473           MatSetValues(), MatSetValuesAdic()
7474 @*/
7475 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7476 {
7477   PetscErrorCode ierr;
7478 
7479   PetscFunctionBegin;
7480   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7481   PetscValidType(mat,1);
7482   PetscValidPointer(coloring,2);
7483 
7484   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7485   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7486   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7487   PetscFunctionReturn(0);
7488 }
7489 
7490 #undef __FUNCT__
7491 #define __FUNCT__ "MatSetValuesAdifor"
7492 /*@
7493    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7494 
7495    Not Collective
7496 
7497    Input Parameters:
7498 +  mat - the matrix
7499 .  nl - leading dimension of v
7500 -  v - the values compute with ADIFOR
7501 
7502    Level: developer
7503 
7504    Notes:
7505      Must call MatSetColoring() before using this routine. Also this matrix must already
7506      have its nonzero pattern determined.
7507 
7508 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7509           MatSetValues(), MatSetColoring()
7510 @*/
7511 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7512 {
7513   PetscErrorCode ierr;
7514 
7515   PetscFunctionBegin;
7516   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7517   PetscValidType(mat,1);
7518   PetscValidPointer(v,3);
7519 
7520   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7521   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7522   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7523   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7524   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7525   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7526   PetscFunctionReturn(0);
7527 }
7528 
7529 #undef __FUNCT__
7530 #define __FUNCT__ "MatDiagonalScaleLocal"
7531 /*@
7532    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7533          ghosted ones.
7534 
7535    Not Collective
7536 
7537    Input Parameters:
7538 +  mat - the matrix
7539 -  diag = the diagonal values, including ghost ones
7540 
7541    Level: developer
7542 
7543    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7544 
7545 .seealso: MatDiagonalScale()
7546 @*/
7547 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7548 {
7549   PetscErrorCode ierr;
7550   PetscMPIInt    size;
7551 
7552   PetscFunctionBegin;
7553   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7554   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7555   PetscValidType(mat,1);
7556 
7557   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7558   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7559   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7560   if (size == 1) {
7561     PetscInt n,m;
7562     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7563     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7564     if (m == n) {
7565       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7566     } else {
7567       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7568     }
7569   } else {
7570     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7571   }
7572   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7573   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7574   PetscFunctionReturn(0);
7575 }
7576 
7577 #undef __FUNCT__
7578 #define __FUNCT__ "MatGetInertia"
7579 /*@
7580    MatGetInertia - Gets the inertia from a factored matrix
7581 
7582    Collective on Mat
7583 
7584    Input Parameter:
7585 .  mat - the matrix
7586 
7587    Output Parameters:
7588 +   nneg - number of negative eigenvalues
7589 .   nzero - number of zero eigenvalues
7590 -   npos - number of positive eigenvalues
7591 
7592    Level: advanced
7593 
7594    Notes: Matrix must have been factored by MatCholeskyFactor()
7595 
7596 
7597 @*/
7598 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7599 {
7600   PetscErrorCode ierr;
7601 
7602   PetscFunctionBegin;
7603   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7604   PetscValidType(mat,1);
7605   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7606   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7607   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7608   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7609   PetscFunctionReturn(0);
7610 }
7611 
7612 /* ----------------------------------------------------------------*/
7613 #undef __FUNCT__
7614 #define __FUNCT__ "MatSolves"
7615 /*@C
7616    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7617 
7618    Neighbor-wise Collective on Mat and Vecs
7619 
7620    Input Parameters:
7621 +  mat - the factored matrix
7622 -  b - the right-hand-side vectors
7623 
7624    Output Parameter:
7625 .  x - the result vectors
7626 
7627    Notes:
7628    The vectors b and x cannot be the same.  I.e., one cannot
7629    call MatSolves(A,x,x).
7630 
7631    Notes:
7632    Most users should employ the simplified KSP interface for linear solvers
7633    instead of working directly with matrix algebra routines such as this.
7634    See, e.g., KSPCreate().
7635 
7636    Level: developer
7637 
7638    Concepts: matrices^triangular solves
7639 
7640 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7641 @*/
7642 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7643 {
7644   PetscErrorCode ierr;
7645 
7646   PetscFunctionBegin;
7647   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7648   PetscValidType(mat,1);
7649   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7650   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7651   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7652 
7653   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7654   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7655   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7656   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7657   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7658   PetscFunctionReturn(0);
7659 }
7660 
7661 #undef __FUNCT__
7662 #define __FUNCT__ "MatIsSymmetric"
7663 /*@
7664    MatIsSymmetric - Test whether a matrix is symmetric
7665 
7666    Collective on Mat
7667 
7668    Input Parameter:
7669 +  A - the matrix to test
7670 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7671 
7672    Output Parameters:
7673 .  flg - the result
7674 
7675    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7676 
7677    Level: intermediate
7678 
7679    Concepts: matrix^symmetry
7680 
7681 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7682 @*/
7683 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7684 {
7685   PetscErrorCode ierr;
7686 
7687   PetscFunctionBegin;
7688   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7689   PetscValidPointer(flg,2);
7690 
7691   if (!A->symmetric_set) {
7692     if (!A->ops->issymmetric) {
7693       const MatType mattype;
7694       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7695       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7696     }
7697     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7698     if (!tol) {
7699       A->symmetric_set = PETSC_TRUE;
7700       A->symmetric = *flg;
7701       if (A->symmetric) {
7702 	A->structurally_symmetric_set = PETSC_TRUE;
7703 	A->structurally_symmetric     = PETSC_TRUE;
7704       }
7705     }
7706   } else if (A->symmetric) {
7707     *flg = PETSC_TRUE;
7708   } else if (!tol) {
7709     *flg = PETSC_FALSE;
7710   } else {
7711     if (!A->ops->issymmetric) {
7712       const MatType mattype;
7713       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7714       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7715     }
7716     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7717   }
7718   PetscFunctionReturn(0);
7719 }
7720 
7721 #undef __FUNCT__
7722 #define __FUNCT__ "MatIsHermitian"
7723 /*@
7724    MatIsHermitian - Test whether a matrix is Hermitian
7725 
7726    Collective on Mat
7727 
7728    Input Parameter:
7729 +  A - the matrix to test
7730 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7731 
7732    Output Parameters:
7733 .  flg - the result
7734 
7735    Level: intermediate
7736 
7737    Concepts: matrix^symmetry
7738 
7739 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7740           MatIsSymmetricKnown(), MatIsSymmetric()
7741 @*/
7742 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7743 {
7744   PetscErrorCode ierr;
7745 
7746   PetscFunctionBegin;
7747   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7748   PetscValidPointer(flg,2);
7749 
7750   if (!A->hermitian_set) {
7751     if (!A->ops->ishermitian) {
7752       const MatType mattype;
7753       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7754       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7755     }
7756     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7757     if (!tol) {
7758       A->hermitian_set = PETSC_TRUE;
7759       A->hermitian = *flg;
7760       if (A->hermitian) {
7761 	A->structurally_symmetric_set = PETSC_TRUE;
7762 	A->structurally_symmetric     = PETSC_TRUE;
7763       }
7764     }
7765   } else if (A->hermitian) {
7766     *flg = PETSC_TRUE;
7767   } else if (!tol) {
7768     *flg = PETSC_FALSE;
7769   } else {
7770     if (!A->ops->ishermitian) {
7771       const MatType mattype;
7772       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7773       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7774     }
7775     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7776   }
7777   PetscFunctionReturn(0);
7778 }
7779 
7780 #undef __FUNCT__
7781 #define __FUNCT__ "MatIsSymmetricKnown"
7782 /*@
7783    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7784 
7785    Not Collective
7786 
7787    Input Parameter:
7788 .  A - the matrix to check
7789 
7790    Output Parameters:
7791 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7792 -  flg - the result
7793 
7794    Level: advanced
7795 
7796    Concepts: matrix^symmetry
7797 
7798    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7799          if you want it explicitly checked
7800 
7801 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7802 @*/
7803 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7804 {
7805   PetscFunctionBegin;
7806   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7807   PetscValidPointer(set,2);
7808   PetscValidPointer(flg,3);
7809   if (A->symmetric_set) {
7810     *set = PETSC_TRUE;
7811     *flg = A->symmetric;
7812   } else {
7813     *set = PETSC_FALSE;
7814   }
7815   PetscFunctionReturn(0);
7816 }
7817 
7818 #undef __FUNCT__
7819 #define __FUNCT__ "MatIsHermitianKnown"
7820 /*@
7821    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7822 
7823    Not Collective
7824 
7825    Input Parameter:
7826 .  A - the matrix to check
7827 
7828    Output Parameters:
7829 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7830 -  flg - the result
7831 
7832    Level: advanced
7833 
7834    Concepts: matrix^symmetry
7835 
7836    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7837          if you want it explicitly checked
7838 
7839 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7840 @*/
7841 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7842 {
7843   PetscFunctionBegin;
7844   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7845   PetscValidPointer(set,2);
7846   PetscValidPointer(flg,3);
7847   if (A->hermitian_set) {
7848     *set = PETSC_TRUE;
7849     *flg = A->hermitian;
7850   } else {
7851     *set = PETSC_FALSE;
7852   }
7853   PetscFunctionReturn(0);
7854 }
7855 
7856 #undef __FUNCT__
7857 #define __FUNCT__ "MatIsStructurallySymmetric"
7858 /*@
7859    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
7860 
7861    Collective on Mat
7862 
7863    Input Parameter:
7864 .  A - the matrix to test
7865 
7866    Output Parameters:
7867 .  flg - the result
7868 
7869    Level: intermediate
7870 
7871    Concepts: matrix^symmetry
7872 
7873 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7874 @*/
7875 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
7876 {
7877   PetscErrorCode ierr;
7878 
7879   PetscFunctionBegin;
7880   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7881   PetscValidPointer(flg,2);
7882   if (!A->structurally_symmetric_set) {
7883     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7884     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
7885     A->structurally_symmetric_set = PETSC_TRUE;
7886   }
7887   *flg = A->structurally_symmetric;
7888   PetscFunctionReturn(0);
7889 }
7890 
7891 #undef __FUNCT__
7892 #define __FUNCT__ "MatStashGetInfo"
7893 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
7894 /*@
7895    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
7896        to be communicated to other processors during the MatAssemblyBegin/End() process
7897 
7898     Not collective
7899 
7900    Input Parameter:
7901 .   vec - the vector
7902 
7903    Output Parameters:
7904 +   nstash   - the size of the stash
7905 .   reallocs - the number of additional mallocs incurred.
7906 .   bnstash   - the size of the block stash
7907 -   breallocs - the number of additional mallocs incurred.in the block stash
7908 
7909    Level: advanced
7910 
7911 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7912 
7913 @*/
7914 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7915 {
7916   PetscErrorCode ierr;
7917   PetscFunctionBegin;
7918   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
7919   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
7920   PetscFunctionReturn(0);
7921 }
7922 
7923 #undef __FUNCT__
7924 #define __FUNCT__ "MatGetVecs"
7925 /*@C
7926    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
7927      parallel layout
7928 
7929    Collective on Mat
7930 
7931    Input Parameter:
7932 .  mat - the matrix
7933 
7934    Output Parameter:
7935 +   right - (optional) vector that the matrix can be multiplied against
7936 -   left - (optional) vector that the matrix vector product can be stored in
7937 
7938   Level: advanced
7939 
7940 .seealso: MatCreate()
7941 @*/
7942 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7943 {
7944   PetscErrorCode ierr;
7945 
7946   PetscFunctionBegin;
7947   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7948   PetscValidType(mat,1);
7949   ierr = MatPreallocated(mat);CHKERRQ(ierr);
7950   if (mat->ops->getvecs) {
7951     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
7952   } else {
7953     PetscMPIInt size;
7954     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
7955     if (right) {
7956       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
7957       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7958       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
7959       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
7960       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
7961     }
7962     if (left) {
7963       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
7964       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
7965       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
7966       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
7967       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
7968     }
7969   }
7970   PetscFunctionReturn(0);
7971 }
7972 
7973 #undef __FUNCT__
7974 #define __FUNCT__ "MatFactorInfoInitialize"
7975 /*@C
7976    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7977      with default values.
7978 
7979    Not Collective
7980 
7981    Input Parameters:
7982 .    info - the MatFactorInfo data structure
7983 
7984 
7985    Notes: The solvers are generally used through the KSP and PC objects, for example
7986           PCLU, PCILU, PCCHOLESKY, PCICC
7987 
7988    Level: developer
7989 
7990 .seealso: MatFactorInfo
7991 
7992     Developer Note: fortran interface is not autogenerated as the f90
7993     interface defintion cannot be generated correctly [due to MatFactorInfo]
7994 
7995 @*/
7996 
7997 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7998 {
7999   PetscErrorCode ierr;
8000 
8001   PetscFunctionBegin;
8002   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8003   PetscFunctionReturn(0);
8004 }
8005 
8006 #undef __FUNCT__
8007 #define __FUNCT__ "MatPtAP"
8008 /*@
8009    MatPtAP - Creates the matrix product C = P^T * A * P
8010 
8011    Neighbor-wise Collective on Mat
8012 
8013    Input Parameters:
8014 +  A - the matrix
8015 .  P - the projection matrix
8016 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8017 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8018 
8019    Output Parameters:
8020 .  C - the product matrix
8021 
8022    Notes:
8023    C will be created and must be destroyed by the user with MatDestroy().
8024 
8025    This routine is currently only implemented for pairs of AIJ matrices and classes
8026    which inherit from AIJ.
8027 
8028    Level: intermediate
8029 
8030 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
8031 @*/
8032 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8033 {
8034   PetscErrorCode ierr;
8035 
8036   PetscFunctionBegin;
8037   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8038   PetscValidType(A,1);
8039   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8040   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8041   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8042   PetscValidType(P,2);
8043   ierr = MatPreallocated(P);CHKERRQ(ierr);
8044   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8045   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8046   PetscValidPointer(C,3);
8047   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);
8048   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8049   ierr = MatPreallocated(A);CHKERRQ(ierr);
8050 
8051   if (!A->ops->ptap) {
8052     const MatType mattype;
8053     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8054     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8055   }
8056   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8057   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8058   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8059 
8060   PetscFunctionReturn(0);
8061 }
8062 
8063 #undef __FUNCT__
8064 #define __FUNCT__ "MatPtAPNumeric"
8065 /*@
8066    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8067 
8068    Neighbor-wise Collective on Mat
8069 
8070    Input Parameters:
8071 +  A - the matrix
8072 -  P - the projection matrix
8073 
8074    Output Parameters:
8075 .  C - the product matrix
8076 
8077    Notes:
8078    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8079    the user using MatDeatroy().
8080 
8081    This routine is currently only implemented for pairs of AIJ matrices and classes
8082    which inherit from AIJ.  C will be of type MATAIJ.
8083 
8084    Level: intermediate
8085 
8086 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8087 @*/
8088 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8089 {
8090   PetscErrorCode ierr;
8091 
8092   PetscFunctionBegin;
8093   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8094   PetscValidType(A,1);
8095   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8096   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8097   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8098   PetscValidType(P,2);
8099   ierr = MatPreallocated(P);CHKERRQ(ierr);
8100   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8101   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8102   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8103   PetscValidType(C,3);
8104   ierr = MatPreallocated(C);CHKERRQ(ierr);
8105   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8106   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);
8107   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);
8108   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);
8109   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);
8110   ierr = MatPreallocated(A);CHKERRQ(ierr);
8111 
8112   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8113   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8114   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8115   PetscFunctionReturn(0);
8116 }
8117 
8118 #undef __FUNCT__
8119 #define __FUNCT__ "MatPtAPSymbolic"
8120 /*@
8121    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8122 
8123    Neighbor-wise Collective on Mat
8124 
8125    Input Parameters:
8126 +  A - the matrix
8127 -  P - the projection matrix
8128 
8129    Output Parameters:
8130 .  C - the (i,j) structure of the product matrix
8131 
8132    Notes:
8133    C will be created and must be destroyed by the user with MatDestroy().
8134 
8135    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8136    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8137    this (i,j) structure by calling MatPtAPNumeric().
8138 
8139    Level: intermediate
8140 
8141 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8142 @*/
8143 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8144 {
8145   PetscErrorCode ierr;
8146 
8147   PetscFunctionBegin;
8148   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8149   PetscValidType(A,1);
8150   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8151   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8152   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8153   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8154   PetscValidType(P,2);
8155   ierr = MatPreallocated(P);CHKERRQ(ierr);
8156   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8157   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8158   PetscValidPointer(C,3);
8159 
8160   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);
8161   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);
8162   ierr = MatPreallocated(A);CHKERRQ(ierr);
8163   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8164   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8165   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8166 
8167   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8168 
8169   PetscFunctionReturn(0);
8170 }
8171 
8172 #undef __FUNCT__
8173 #define __FUNCT__ "MatMatMult"
8174 /*@
8175    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8176 
8177    Neighbor-wise Collective on Mat
8178 
8179    Input Parameters:
8180 +  A - the left matrix
8181 .  B - the right matrix
8182 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8183 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8184           if the result is a dense matrix this is irrelevent
8185 
8186    Output Parameters:
8187 .  C - the product matrix
8188 
8189    Notes:
8190    Unless scall is MAT_REUSE_MATRIX C will be created.
8191 
8192    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8193 
8194    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8195    actually needed.
8196 
8197    If you have many matrices with the same non-zero structure to multiply, you
8198    should either
8199 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8200 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8201 
8202    Level: intermediate
8203 
8204 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8205 @*/
8206 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8207 {
8208   PetscErrorCode ierr;
8209   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8210   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8211   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8212 
8213   PetscFunctionBegin;
8214   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8215   PetscValidType(A,1);
8216   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8217   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8218   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8219   PetscValidType(B,2);
8220   ierr = MatPreallocated(B);CHKERRQ(ierr);
8221   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8222   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8223   PetscValidPointer(C,3);
8224   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);
8225   if (scall == MAT_REUSE_MATRIX){
8226     PetscValidPointer(*C,5);
8227     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8228   }
8229   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8230   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8231   ierr = MatPreallocated(A);CHKERRQ(ierr);
8232 
8233   fA = A->ops->matmult;
8234   fB = B->ops->matmult;
8235   if (fB == fA) {
8236     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8237     mult = fB;
8238   } else {
8239     /* dispatch based on the type of A and B */
8240     char  multname[256];
8241     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8242     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8243     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8244     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8245     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8246     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8247     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);
8248   }
8249   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8250   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8251   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8252   PetscFunctionReturn(0);
8253 }
8254 
8255 #undef __FUNCT__
8256 #define __FUNCT__ "MatMatMultSymbolic"
8257 /*@
8258    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8259    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8260 
8261    Neighbor-wise Collective on Mat
8262 
8263    Input Parameters:
8264 +  A - the left matrix
8265 .  B - the right matrix
8266 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8267       if C is a dense matrix this is irrelevent
8268 
8269    Output Parameters:
8270 .  C - the product matrix
8271 
8272    Notes:
8273    Unless scall is MAT_REUSE_MATRIX C will be created.
8274 
8275    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8276    actually needed.
8277 
8278    This routine is currently implemented for
8279     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8280     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8281     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8282 
8283    Level: intermediate
8284 
8285    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8286      We should incorporate them into PETSc.
8287 
8288 .seealso: MatMatMult(), MatMatMultNumeric()
8289 @*/
8290 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8291 {
8292   PetscErrorCode ierr;
8293   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8294   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8295   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8296 
8297   PetscFunctionBegin;
8298   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8299   PetscValidType(A,1);
8300   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8301   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8302 
8303   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8304   PetscValidType(B,2);
8305   ierr = MatPreallocated(B);CHKERRQ(ierr);
8306   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8307   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8308   PetscValidPointer(C,3);
8309 
8310   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);
8311   if (fill == PETSC_DEFAULT) fill = 2.0;
8312   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8313   ierr = MatPreallocated(A);CHKERRQ(ierr);
8314 
8315   Asymbolic = A->ops->matmultsymbolic;
8316   Bsymbolic = B->ops->matmultsymbolic;
8317   if (Asymbolic == Bsymbolic){
8318     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8319     symbolic = Bsymbolic;
8320   } else { /* dispatch based on the type of A and B */
8321     char  symbolicname[256];
8322     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8323     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8324     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8325     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8326     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8327     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8328     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);
8329   }
8330   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8331   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8332   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8333   PetscFunctionReturn(0);
8334 }
8335 
8336 #undef __FUNCT__
8337 #define __FUNCT__ "MatMatMultNumeric"
8338 /*@
8339    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8340    Call this routine after first calling MatMatMultSymbolic().
8341 
8342    Neighbor-wise Collective on Mat
8343 
8344    Input Parameters:
8345 +  A - the left matrix
8346 -  B - the right matrix
8347 
8348    Output Parameters:
8349 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8350 
8351    Notes:
8352    C must have been created with MatMatMultSymbolic().
8353 
8354    This routine is currently implemented for
8355     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8356     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8357     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8358 
8359    Level: intermediate
8360 
8361 .seealso: MatMatMult(), MatMatMultSymbolic()
8362 @*/
8363 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8364 {
8365   PetscErrorCode ierr;
8366   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8367   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8368   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8369 
8370   PetscFunctionBegin;
8371   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8372   PetscValidType(A,1);
8373   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8374   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8375 
8376   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8377   PetscValidType(B,2);
8378   ierr = MatPreallocated(B);CHKERRQ(ierr);
8379   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8380   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8381 
8382   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8383   PetscValidType(C,3);
8384   ierr = MatPreallocated(C);CHKERRQ(ierr);
8385   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8386   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8387 
8388   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);
8389   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);
8390   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);
8391   ierr = MatPreallocated(A);CHKERRQ(ierr);
8392 
8393   Anumeric = A->ops->matmultnumeric;
8394   Bnumeric = B->ops->matmultnumeric;
8395   if (Anumeric == Bnumeric){
8396     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8397     numeric = Bnumeric;
8398   } else {
8399     char  numericname[256];
8400     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8401     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8402     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8403     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8404     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8405     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8406     if (!numeric)
8407       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);
8408   }
8409   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8410   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8411   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8412   PetscFunctionReturn(0);
8413 }
8414 
8415 #undef __FUNCT__
8416 #define __FUNCT__ "MatMatMultTranspose"
8417 /*@
8418    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
8419 
8420    Neighbor-wise Collective on Mat
8421 
8422    Input Parameters:
8423 +  A - the left matrix
8424 .  B - the right matrix
8425 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8426 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8427 
8428    Output Parameters:
8429 .  C - the product matrix
8430 
8431    Notes:
8432    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8433 
8434    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8435 
8436   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8437    actually needed.
8438 
8439    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8440    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8441 
8442    Level: intermediate
8443 
8444 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8445 @*/
8446 PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8447 {
8448   PetscErrorCode ierr;
8449   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8450   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8451 
8452   PetscFunctionBegin;
8453   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8454   PetscValidType(A,1);
8455   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8456   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8457   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8458   PetscValidType(B,2);
8459   ierr = MatPreallocated(B);CHKERRQ(ierr);
8460   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8461   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8462   PetscValidPointer(C,3);
8463   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);
8464   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8465   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8466   ierr = MatPreallocated(A);CHKERRQ(ierr);
8467 
8468   fA = A->ops->matmulttranspose;
8469   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8470   fB = B->ops->matmulttranspose;
8471   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8472   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);
8473 
8474   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8475   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
8476   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
8477 
8478   PetscFunctionReturn(0);
8479 }
8480 
8481 #undef __FUNCT__
8482 #define __FUNCT__ "MatGetRedundantMatrix"
8483 /*@C
8484    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8485 
8486    Collective on Mat
8487 
8488    Input Parameters:
8489 +  mat - the matrix
8490 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8491 .  subcomm - MPI communicator split from the communicator where mat resides in
8492 .  mlocal_red - number of local rows of the redundant matrix
8493 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8494 
8495    Output Parameter:
8496 .  matredundant - redundant matrix
8497 
8498    Notes:
8499    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8500    original matrix has not changed from that last call to MatGetRedundantMatrix().
8501 
8502    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8503    calling it.
8504 
8505    Only MPIAIJ matrix is supported.
8506 
8507    Level: advanced
8508 
8509    Concepts: subcommunicator
8510    Concepts: duplicate matrix
8511 
8512 .seealso: MatDestroy()
8513 @*/
8514 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8515 {
8516   PetscErrorCode ierr;
8517 
8518   PetscFunctionBegin;
8519   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8520   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8521     PetscValidPointer(*matredundant,6);
8522     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
8523   }
8524   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8525   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8526   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8527   ierr = MatPreallocated(mat);CHKERRQ(ierr);
8528 
8529   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8530   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
8531   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
8532   PetscFunctionReturn(0);
8533 }
8534 
8535 #undef __FUNCT__
8536 #define __FUNCT__ "MatGetMultiProcBlock"
8537 /*@C
8538    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8539    a given 'mat' object. Each submatrix can span multiple procs.
8540 
8541    Collective on Mat
8542 
8543    Input Parameters:
8544 +  mat - the matrix
8545 -  subcomm - the subcommunicator obtained by com_split(comm)
8546 
8547    Output Parameter:
8548 .  subMat - 'parallel submatrices each spans a given subcomm
8549 
8550   Notes:
8551   The submatrix partition across processors is dicated by 'subComm' a
8552   communicator obtained by com_split(comm). The comm_split
8553   is not restriced to be grouped with consequitive original ranks.
8554 
8555   Due the comm_split() usage, the parallel layout of the submatrices
8556   map directly to the layout of the original matrix [wrt the local
8557   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8558   into the 'DiagonalMat' of the subMat, hence it is used directly from
8559   the subMat. However the offDiagMat looses some columns - and this is
8560   reconstructed with MatSetValues()
8561 
8562   Level: advanced
8563 
8564   Concepts: subcommunicator
8565   Concepts: submatrices
8566 
8567 .seealso: MatGetSubMatrices()
8568 @*/
8569 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8570 {
8571   PetscErrorCode ierr;
8572   PetscMPIInt    commsize,subCommSize;
8573 
8574   PetscFunctionBegin;
8575   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
8576   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
8577   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8578 
8579   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8580   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,subMat);CHKERRQ(ierr);
8581   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
8582   PetscFunctionReturn(0);
8583 }
8584 
8585 #undef __FUNCT__
8586 #define __FUNCT__ "MatGetLocalSubMatrix"
8587 /*@
8588    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
8589 
8590    Not Collective
8591 
8592    Input Arguments:
8593    mat - matrix to extract local submatrix from
8594    isrow - local row indices for submatrix
8595    iscol - local column indices for submatrix
8596 
8597    Output Arguments:
8598    submat - the submatrix
8599 
8600    Level: intermediate
8601 
8602    Notes:
8603    The submat should be returned with MatRestoreLocalSubMatrix().
8604 
8605    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
8606    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
8607 
8608    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
8609    MatSetValuesBlockedLocal() will also be implemented.
8610 
8611 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8612 @*/
8613 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8614 {
8615   PetscErrorCode ierr;
8616 
8617   PetscFunctionBegin;
8618   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8619   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8620   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8621   PetscCheckSameComm(isrow,2,iscol,3);
8622   PetscValidPointer(submat,4);
8623 
8624   if (mat->ops->getlocalsubmatrix) {
8625     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8626   } else {
8627     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
8628   }
8629   PetscFunctionReturn(0);
8630 }
8631 
8632 #undef __FUNCT__
8633 #define __FUNCT__ "MatRestoreLocalSubMatrix"
8634 /*@
8635    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
8636 
8637    Not Collective
8638 
8639    Input Arguments:
8640    mat - matrix to extract local submatrix from
8641    isrow - local row indices for submatrix
8642    iscol - local column indices for submatrix
8643    submat - the submatrix
8644 
8645    Level: intermediate
8646 
8647 .seealso: MatGetLocalSubMatrix()
8648 @*/
8649 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8650 {
8651   PetscErrorCode ierr;
8652 
8653   PetscFunctionBegin;
8654   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8655   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
8656   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
8657   PetscCheckSameComm(isrow,2,iscol,3);
8658   PetscValidPointer(submat,4);
8659   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
8660 
8661   if (mat->ops->restorelocalsubmatrix) {
8662     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
8663   } else {
8664     ierr = MatDestroy(submat);CHKERRQ(ierr);
8665   }
8666   *submat = PETSC_NULL;
8667   PetscFunctionReturn(0);
8668 }
8669 
8670 /* --------------------------------------------------------*/
8671 #undef __FUNCT__
8672 #define __FUNCT__ "MatFindZeroDiagonals"
8673 /*@
8674    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
8675 
8676    Collective on Mat
8677 
8678    Input Parameter:
8679 .  mat - the matrix
8680 
8681    Output Parameter:
8682 .  is - if any rows have zero diagonals this contains the list of them
8683 
8684    Level: developer
8685 
8686    Concepts: matrix-vector product
8687 
8688 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8689 @*/
8690 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
8691 {
8692   PetscErrorCode ierr;
8693 
8694   PetscFunctionBegin;
8695   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8696   PetscValidType(mat,1);
8697   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8698   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8699 
8700   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8701   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
8702   PetscFunctionReturn(0);
8703 }
8704 
8705 #undef __FUNCT__
8706 #define __FUNCT__ "MatInvertBlockDiagonal"
8707 /*@
8708   MatInvertBlockDiagonal - Inverts the block diagonal entries.
8709 
8710   Collective on Mat
8711 
8712   Input Parameters:
8713 . mat - the matrix
8714 
8715   Output Parameters:
8716 . values - the block inverses in column major order (FORTRAN-like)
8717 
8718   Level: advanced
8719 @*/
8720 PetscErrorCode  MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
8721 {
8722   PetscErrorCode ierr;
8723 
8724   PetscFunctionBegin;
8725   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8726   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8727   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8728   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
8729   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
8730   PetscFunctionReturn(0);
8731 }
8732