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