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