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