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