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