xref: /petsc/src/mat/interface/matrix.c (revision 778a22469b81459d5eae5c09b2a1a114212df134)
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)) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3827 
3828   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0);
3829 
3830   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3831     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
3832   } else {
3833     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3834     const char     *prefix[3] = {"seq","mpi",""};
3835     PetscInt       i;
3836     /*
3837        Order of precedence:
3838        1) See if a specialized converter is known to the current matrix.
3839        2) See if a specialized converter is known to the desired matrix class.
3840        3) See if a good general converter is registered for the desired class
3841           (as of 6/27/03 only MATMPIADJ falls into this category).
3842        4) See if a good general converter is known for the current matrix.
3843        5) Use a really basic converter.
3844     */
3845 
3846     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3847     for (i=0; i<3; i++) {
3848       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3849       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3850       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3851       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3852       ierr = PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);CHKERRQ(ierr);
3853       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3854       ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3855       if (conv) goto foundconv;
3856     }
3857 
3858     /* 2)  See if a specialized converter is known to the desired matrix class. */
3859     ierr = MatCreate(((PetscObject)mat)->comm,&B);CHKERRQ(ierr);
3860     ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr);
3861     ierr = MatSetType(B,newtype);CHKERRQ(ierr);
3862     for (i=0; i<3; i++) {
3863       ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
3864       ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr);
3865       ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
3866       ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr);
3867       ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
3868       ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3869       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3870       if (conv) {
3871         ierr = MatDestroy(&B);CHKERRQ(ierr);
3872         goto foundconv;
3873       }
3874     }
3875 
3876     /* 3) See if a good general converter is registered for the desired class */
3877     conv = B->ops->convertfrom;
3878     ierr = MatDestroy(&B);CHKERRQ(ierr);
3879     if (conv) goto foundconv;
3880 
3881     /* 4) See if a good general converter is known for the current matrix */
3882     if (mat->ops->convert) {
3883       conv = mat->ops->convert;
3884     }
3885     if (conv) goto foundconv;
3886 
3887     /* 5) Use a really basic converter. */
3888     conv = MatConvert_Basic;
3889 
3890     foundconv:
3891     ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3892     ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr);
3893     ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
3894   }
3895   ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr);
3896 
3897   /* Copy Mat options */
3898   if (mat->symmetric){ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);}
3899   if (mat->hermitian){ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);}
3900   PetscFunctionReturn(0);
3901 }
3902 
3903 #undef __FUNCT__
3904 #define __FUNCT__ "MatFactorGetSolverPackage"
3905 /*@C
3906    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3907 
3908    Not Collective
3909 
3910    Input Parameter:
3911 .  mat - the matrix, must be a factored matrix
3912 
3913    Output Parameter:
3914 .   type - the string name of the package (do not free this string)
3915 
3916    Notes:
3917       In Fortran you pass in a empty string and the package name will be copied into it.
3918     (Make sure the string is long enough)
3919 
3920    Level: intermediate
3921 
3922 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3923 @*/
3924 PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3925 {
3926   PetscErrorCode         ierr;
3927   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);
3928 
3929   PetscFunctionBegin;
3930   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3931   PetscValidType(mat,1);
3932   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3933   ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);CHKERRQ(ierr);
3934   if (!conv) {
3935     *type = MATSOLVERPETSC;
3936   } else {
3937     ierr = (*conv)(mat,type);CHKERRQ(ierr);
3938   }
3939   PetscFunctionReturn(0);
3940 }
3941 
3942 #undef __FUNCT__
3943 #define __FUNCT__ "MatGetFactor"
3944 /*@C
3945    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3946 
3947    Collective on Mat
3948 
3949    Input Parameters:
3950 +  mat - the matrix
3951 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3952 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3953 
3954    Output Parameters:
3955 .  f - the factor matrix used with MatXXFactorSymbolic() calls
3956 
3957    Notes:
3958       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3959      such as pastix, superlu, mumps, spooles etc.
3960 
3961       PETSc must have been ./configure to use the external solver, using the option --download-package
3962 
3963    Level: intermediate
3964 
3965 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3966 @*/
3967 PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3968 {
3969   PetscErrorCode  ierr,(*conv)(Mat,MatFactorType,Mat*);
3970   char            convname[256];
3971 
3972   PetscFunctionBegin;
3973   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
3974   PetscValidType(mat,1);
3975 
3976   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3977   MatCheckPreallocated(mat,1);
3978 
3979   ierr = PetscStrcpy(convname,"MatGetFactor_");CHKERRQ(ierr);
3980   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
3981   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
3982   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
3983   if (!conv) {
3984     PetscBool  flag;
3985     MPI_Comm   comm;
3986 
3987     ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
3988     ierr = PetscStrcasecmp(MATSOLVERPETSC,type,&flag);CHKERRQ(ierr);
3989     if (flag) {
3990       SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3991     } else {
3992       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);
3993     }
3994   }
3995   ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr);
3996   PetscFunctionReturn(0);
3997 }
3998 
3999 #undef __FUNCT__
4000 #define __FUNCT__ "MatGetFactorAvailable"
4001 /*@C
4002    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4003 
4004    Not Collective
4005 
4006    Input Parameters:
4007 +  mat - the matrix
4008 .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
4009 -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4010 
4011    Output Parameter:
4012 .    flg - PETSC_TRUE if the factorization is available
4013 
4014    Notes:
4015       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4016      such as pastix, superlu, mumps, spooles etc.
4017 
4018       PETSc must have been ./configure to use the external solver, using the option --download-package
4019 
4020    Level: intermediate
4021 
4022 .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4023 @*/
4024 PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
4025 {
4026   PetscErrorCode         ierr;
4027   char                   convname[256];
4028   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscBool *);
4029 
4030   PetscFunctionBegin;
4031   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4032   PetscValidType(mat,1);
4033 
4034   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4035   MatCheckPreallocated(mat,1);
4036 
4037   ierr = PetscStrcpy(convname,"MatGetFactorAvailable_");CHKERRQ(ierr);
4038   ierr = PetscStrcat(convname,type);CHKERRQ(ierr);
4039   ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
4040   ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
4041   if (!conv) {
4042     *flg = PETSC_FALSE;
4043   } else {
4044     ierr = (*conv)(mat,ftype,flg);CHKERRQ(ierr);
4045   }
4046   PetscFunctionReturn(0);
4047 }
4048 
4049 
4050 #undef __FUNCT__
4051 #define __FUNCT__ "MatDuplicate"
4052 /*@
4053    MatDuplicate - Duplicates a matrix including the non-zero structure.
4054 
4055    Collective on Mat
4056 
4057    Input Parameters:
4058 +  mat - the matrix
4059 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4060         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4061 
4062    Output Parameter:
4063 .  M - pointer to place new matrix
4064 
4065    Level: intermediate
4066 
4067    Concepts: matrices^duplicating
4068 
4069     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4070 
4071 .seealso: MatCopy(), MatConvert()
4072 @*/
4073 PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4074 {
4075   PetscErrorCode ierr;
4076   Mat            B;
4077   PetscInt       i;
4078 
4079   PetscFunctionBegin;
4080   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4081   PetscValidType(mat,1);
4082   PetscValidPointer(M,3);
4083   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4084   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4085   MatCheckPreallocated(mat,1);
4086 
4087   *M  = 0;
4088   if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
4089   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4090   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
4091   B = *M;
4092 
4093   B->stencil.dim = mat->stencil.dim;
4094   B->stencil.noc = mat->stencil.noc;
4095   for (i=0; i<=mat->stencil.dim; i++) {
4096     B->stencil.dims[i]   = mat->stencil.dims[i];
4097     B->stencil.starts[i] = mat->stencil.starts[i];
4098   }
4099 
4100   B->nooffproczerorows = mat->nooffproczerorows;
4101   B->nooffprocentries  = mat->nooffprocentries;
4102   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
4103   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
4104   PetscFunctionReturn(0);
4105 }
4106 
4107 #undef __FUNCT__
4108 #define __FUNCT__ "MatGetDiagonal"
4109 /*@
4110    MatGetDiagonal - Gets the diagonal of a matrix.
4111 
4112    Logically Collective on Mat and Vec
4113 
4114    Input Parameters:
4115 +  mat - the matrix
4116 -  v - the vector for storing the diagonal
4117 
4118    Output Parameter:
4119 .  v - the diagonal of the matrix
4120 
4121    Level: intermediate
4122 
4123    Note:
4124    Currently only correct in parallel for square matrices.
4125 
4126    Concepts: matrices^accessing diagonals
4127 
4128 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4129 @*/
4130 PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4131 {
4132   PetscErrorCode ierr;
4133 
4134   PetscFunctionBegin;
4135   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4136   PetscValidType(mat,1);
4137   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4138   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4139   if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4140   MatCheckPreallocated(mat,1);
4141 
4142   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
4143   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4144   PetscFunctionReturn(0);
4145 }
4146 
4147 #undef __FUNCT__
4148 #define __FUNCT__ "MatGetRowMin"
4149 /*@
4150    MatGetRowMin - Gets the minimum value (of the real part) of each
4151         row of the matrix
4152 
4153    Logically Collective on Mat and Vec
4154 
4155    Input Parameters:
4156 .  mat - the matrix
4157 
4158    Output Parameter:
4159 +  v - the vector for storing the maximums
4160 -  idx - the indices of the column found for each row (optional)
4161 
4162    Level: intermediate
4163 
4164    Notes: The result of this call are the same as if one converted the matrix to dense format
4165       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4166 
4167     This code is only implemented for a couple of matrix formats.
4168 
4169    Concepts: matrices^getting row maximums
4170 
4171 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4172           MatGetRowMax()
4173 @*/
4174 PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4175 {
4176   PetscErrorCode ierr;
4177 
4178   PetscFunctionBegin;
4179   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4180   PetscValidType(mat,1);
4181   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4182   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4183   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4184   MatCheckPreallocated(mat,1);
4185 
4186   ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr);
4187   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4188   PetscFunctionReturn(0);
4189 }
4190 
4191 #undef __FUNCT__
4192 #define __FUNCT__ "MatGetRowMinAbs"
4193 /*@
4194    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4195         row of the matrix
4196 
4197    Logically Collective on Mat and Vec
4198 
4199    Input Parameters:
4200 .  mat - the matrix
4201 
4202    Output Parameter:
4203 +  v - the vector for storing the minimums
4204 -  idx - the indices of the column found for each row (or PETSC_NULL if not needed)
4205 
4206    Level: intermediate
4207 
4208    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4209     row is 0 (the first column).
4210 
4211     This code is only implemented for a couple of matrix formats.
4212 
4213    Concepts: matrices^getting row maximums
4214 
4215 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4216 @*/
4217 PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4218 {
4219   PetscErrorCode ierr;
4220 
4221   PetscFunctionBegin;
4222   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4223   PetscValidType(mat,1);
4224   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4225   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4226   if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4227   MatCheckPreallocated(mat,1);
4228   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4229 
4230   ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr);
4231   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4232   PetscFunctionReturn(0);
4233 }
4234 
4235 #undef __FUNCT__
4236 #define __FUNCT__ "MatGetRowMax"
4237 /*@
4238    MatGetRowMax - Gets the maximum value (of the real part) of each
4239         row of the matrix
4240 
4241    Logically Collective on Mat and Vec
4242 
4243    Input Parameters:
4244 .  mat - the matrix
4245 
4246    Output Parameter:
4247 +  v - the vector for storing the maximums
4248 -  idx - the indices of the column found for each row (optional)
4249 
4250    Level: intermediate
4251 
4252    Notes: The result of this call are the same as if one converted the matrix to dense format
4253       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4254 
4255     This code is only implemented for a couple of matrix formats.
4256 
4257    Concepts: matrices^getting row maximums
4258 
4259 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4260 @*/
4261 PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4262 {
4263   PetscErrorCode ierr;
4264 
4265   PetscFunctionBegin;
4266   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4267   PetscValidType(mat,1);
4268   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4269   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4270   if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4271   MatCheckPreallocated(mat,1);
4272 
4273   ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr);
4274   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4275   PetscFunctionReturn(0);
4276 }
4277 
4278 #undef __FUNCT__
4279 #define __FUNCT__ "MatGetRowMaxAbs"
4280 /*@
4281    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4282         row of the matrix
4283 
4284    Logically Collective on Mat and Vec
4285 
4286    Input Parameters:
4287 .  mat - the matrix
4288 
4289    Output Parameter:
4290 +  v - the vector for storing the maximums
4291 -  idx - the indices of the column found for each row (or PETSC_NULL if not needed)
4292 
4293    Level: intermediate
4294 
4295    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4296     row is 0 (the first column).
4297 
4298     This code is only implemented for a couple of matrix formats.
4299 
4300    Concepts: matrices^getting row maximums
4301 
4302 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4303 @*/
4304 PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4305 {
4306   PetscErrorCode ierr;
4307 
4308   PetscFunctionBegin;
4309   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4310   PetscValidType(mat,1);
4311   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4312   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4313   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4314   MatCheckPreallocated(mat,1);
4315   if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);}
4316 
4317   ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr);
4318   ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr);
4319   PetscFunctionReturn(0);
4320 }
4321 
4322 #undef __FUNCT__
4323 #define __FUNCT__ "MatGetRowSum"
4324 /*@
4325    MatGetRowSum - Gets the sum of each row of the matrix
4326 
4327    Logically Collective on Mat and Vec
4328 
4329    Input Parameters:
4330 .  mat - the matrix
4331 
4332    Output Parameter:
4333 .  v - the vector for storing the sum of rows
4334 
4335    Level: intermediate
4336 
4337    Notes: This code is slow since it is not currently specialized for different formats
4338 
4339    Concepts: matrices^getting row sums
4340 
4341 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4342 @*/
4343 PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4344 {
4345   PetscInt       start = 0, end = 0, row;
4346   PetscScalar   *array;
4347   PetscErrorCode ierr;
4348 
4349   PetscFunctionBegin;
4350   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4351   PetscValidType(mat,1);
4352   PetscValidHeaderSpecific(v,VEC_CLASSID,2);
4353   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4354   MatCheckPreallocated(mat,1);
4355   ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr);
4356   ierr = VecGetArray(v, &array);CHKERRQ(ierr);
4357   for(row = start; row < end; ++row) {
4358     PetscInt           ncols, col;
4359     const PetscInt    *cols;
4360     const PetscScalar *vals;
4361 
4362     array[row - start] = 0.0;
4363     ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4364     for(col = 0; col < ncols; col++) {
4365       array[row - start] += vals[col];
4366     }
4367     ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr);
4368   }
4369   ierr = VecRestoreArray(v, &array);CHKERRQ(ierr);
4370   ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr);
4371   PetscFunctionReturn(0);
4372 }
4373 
4374 #undef __FUNCT__
4375 #define __FUNCT__ "MatTranspose"
4376 /*@
4377    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4378 
4379    Collective on Mat
4380 
4381    Input Parameter:
4382 +  mat - the matrix to transpose
4383 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4384 
4385    Output Parameters:
4386 .  B - the transpose
4387 
4388    Notes:
4389      If you  pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4390 
4391      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4392 
4393    Level: intermediate
4394 
4395    Concepts: matrices^transposing
4396 
4397 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4398 @*/
4399 PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4400 {
4401   PetscErrorCode ierr;
4402 
4403   PetscFunctionBegin;
4404   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4405   PetscValidType(mat,1);
4406   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4407   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4408   if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4409   MatCheckPreallocated(mat,1);
4410 
4411   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4412   ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr);
4413   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
4414   if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);}
4415   PetscFunctionReturn(0);
4416 }
4417 
4418 #undef __FUNCT__
4419 #define __FUNCT__ "MatIsTranspose"
4420 /*@
4421    MatIsTranspose - Test whether a matrix is another one's transpose,
4422         or its own, in which case it tests symmetry.
4423 
4424    Collective on Mat
4425 
4426    Input Parameter:
4427 +  A - the matrix to test
4428 -  B - the matrix to test against, this can equal the first parameter
4429 
4430    Output Parameters:
4431 .  flg - the result
4432 
4433    Notes:
4434    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4435    has a running time of the order of the number of nonzeros; the parallel
4436    test involves parallel copies of the block-offdiagonal parts of the matrix.
4437 
4438    Level: intermediate
4439 
4440    Concepts: matrices^transposing, matrix^symmetry
4441 
4442 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4443 @*/
4444 PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4445 {
4446   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4447 
4448   PetscFunctionBegin;
4449   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4450   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4451   PetscValidPointer(flg,3);
4452   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4453   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4454   *flg = PETSC_FALSE;
4455   if (f && g) {
4456     if (f == g) {
4457       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4458     } else {
4459       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4460     }
4461   } else {
4462     const MatType mattype;
4463     if (!f) {ierr = MatGetType(A,&mattype);CHKERRQ(ierr);}
4464     else    {ierr = MatGetType(B,&mattype);CHKERRQ(ierr);}
4465     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4466   }
4467   PetscFunctionReturn(0);
4468 }
4469 
4470 #undef __FUNCT__
4471 #define __FUNCT__ "MatHermitianTranspose"
4472 /*@
4473    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4474 
4475    Collective on Mat
4476 
4477    Input Parameter:
4478 +  mat - the matrix to transpose and complex conjugate
4479 -  reuse - store the transpose matrix in the provided B
4480 
4481    Output Parameters:
4482 .  B - the Hermitian
4483 
4484    Notes:
4485      If you  pass in &mat for B the Hermitian will be done in place
4486 
4487    Level: intermediate
4488 
4489    Concepts: matrices^transposing, complex conjugatex
4490 
4491 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4492 @*/
4493 PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4494 {
4495   PetscErrorCode ierr;
4496 
4497   PetscFunctionBegin;
4498   ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr);
4499 #if defined(PETSC_USE_COMPLEX)
4500   ierr = MatConjugate(*B);CHKERRQ(ierr);
4501 #endif
4502   PetscFunctionReturn(0);
4503 }
4504 
4505 #undef __FUNCT__
4506 #define __FUNCT__ "MatIsHermitianTranspose"
4507 /*@
4508    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4509 
4510    Collective on Mat
4511 
4512    Input Parameter:
4513 +  A - the matrix to test
4514 -  B - the matrix to test against, this can equal the first parameter
4515 
4516    Output Parameters:
4517 .  flg - the result
4518 
4519    Notes:
4520    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4521    has a running time of the order of the number of nonzeros; the parallel
4522    test involves parallel copies of the block-offdiagonal parts of the matrix.
4523 
4524    Level: intermediate
4525 
4526    Concepts: matrices^transposing, matrix^symmetry
4527 
4528 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4529 @*/
4530 PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4531 {
4532   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);
4533 
4534   PetscFunctionBegin;
4535   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4536   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4537   PetscValidPointer(flg,3);
4538   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
4539   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
4540   if (f && g) {
4541     if (f==g) {
4542       ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr);
4543     } else {
4544       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4545     }
4546   }
4547   PetscFunctionReturn(0);
4548 }
4549 
4550 #undef __FUNCT__
4551 #define __FUNCT__ "MatPermute"
4552 /*@
4553    MatPermute - Creates a new matrix with rows and columns permuted from the
4554    original.
4555 
4556    Collective on Mat
4557 
4558    Input Parameters:
4559 +  mat - the matrix to permute
4560 .  row - row permutation, each processor supplies only the permutation for its rows
4561 -  col - column permutation, each processor needs the entire column permutation, that is
4562          this is the same size as the total number of columns in the matrix. It can often
4563          be obtained with ISAllGather() on the row permutation
4564 
4565    Output Parameters:
4566 .  B - the permuted matrix
4567 
4568    Level: advanced
4569 
4570    Concepts: matrices^permuting
4571 
4572 .seealso: MatGetOrdering(), ISAllGather()
4573 
4574 @*/
4575 PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4576 {
4577   PetscErrorCode ierr;
4578 
4579   PetscFunctionBegin;
4580   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4581   PetscValidType(mat,1);
4582   PetscValidHeaderSpecific(row,IS_CLASSID,2);
4583   PetscValidHeaderSpecific(col,IS_CLASSID,3);
4584   PetscValidPointer(B,4);
4585   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4586   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4587   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4588   MatCheckPreallocated(mat,1);
4589 
4590   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
4591   ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);
4592   PetscFunctionReturn(0);
4593 }
4594 
4595 #undef __FUNCT__
4596 #define __FUNCT__ "MatEqual"
4597 /*@
4598    MatEqual - Compares two matrices.
4599 
4600    Collective on Mat
4601 
4602    Input Parameters:
4603 +  A - the first matrix
4604 -  B - the second matrix
4605 
4606    Output Parameter:
4607 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4608 
4609    Level: intermediate
4610 
4611    Concepts: matrices^equality between
4612 @*/
4613 PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4614 {
4615   PetscErrorCode ierr;
4616 
4617   PetscFunctionBegin;
4618   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
4619   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
4620   PetscValidType(A,1);
4621   PetscValidType(B,2);
4622   PetscValidIntPointer(flg,3);
4623   PetscCheckSameComm(A,1,B,2);
4624   MatCheckPreallocated(B,2);
4625   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4626   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4627   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);
4628   if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4629   if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4630   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);
4631   MatCheckPreallocated(A,1);
4632 
4633   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
4634   PetscFunctionReturn(0);
4635 }
4636 
4637 #undef __FUNCT__
4638 #define __FUNCT__ "MatDiagonalScale"
4639 /*@
4640    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4641    matrices that are stored as vectors.  Either of the two scaling
4642    matrices can be PETSC_NULL.
4643 
4644    Collective on Mat
4645 
4646    Input Parameters:
4647 +  mat - the matrix to be scaled
4648 .  l - the left scaling vector (or PETSC_NULL)
4649 -  r - the right scaling vector (or PETSC_NULL)
4650 
4651    Notes:
4652    MatDiagonalScale() computes A = LAR, where
4653    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4654    The L scales the rows of the matrix, the R scales the columns of the matrix.
4655 
4656    Level: intermediate
4657 
4658    Concepts: matrices^diagonal scaling
4659    Concepts: diagonal scaling of matrices
4660 
4661 .seealso: MatScale()
4662 @*/
4663 PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4664 {
4665   PetscErrorCode ierr;
4666 
4667   PetscFunctionBegin;
4668   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4669   PetscValidType(mat,1);
4670   if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4671   if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);}
4672   if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);}
4673   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4674   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4675   MatCheckPreallocated(mat,1);
4676 
4677   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4678   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
4679   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4680   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4681 #if defined(PETSC_HAVE_CUSP)
4682   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4683     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4684   }
4685 #endif
4686   PetscFunctionReturn(0);
4687 }
4688 
4689 #undef __FUNCT__
4690 #define __FUNCT__ "MatScale"
4691 /*@
4692     MatScale - Scales all elements of a matrix by a given number.
4693 
4694     Logically Collective on Mat
4695 
4696     Input Parameters:
4697 +   mat - the matrix to be scaled
4698 -   a  - the scaling value
4699 
4700     Output Parameter:
4701 .   mat - the scaled matrix
4702 
4703     Level: intermediate
4704 
4705     Concepts: matrices^scaling all entries
4706 
4707 .seealso: MatDiagonalScale()
4708 @*/
4709 PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4710 {
4711   PetscErrorCode ierr;
4712 
4713   PetscFunctionBegin;
4714   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4715   PetscValidType(mat,1);
4716   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4717   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4718   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4719   PetscValidLogicalCollectiveScalar(mat,a,2);
4720   MatCheckPreallocated(mat,1);
4721 
4722   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4723   if (a != (PetscScalar)1.0) {
4724     ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr);
4725     ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
4726   }
4727   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
4728 #if defined(PETSC_HAVE_CUSP)
4729   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4730     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4731   }
4732 #endif
4733   PetscFunctionReturn(0);
4734 }
4735 
4736 #undef __FUNCT__
4737 #define __FUNCT__ "MatNorm"
4738 /*@
4739    MatNorm - Calculates various norms of a matrix.
4740 
4741    Collective on Mat
4742 
4743    Input Parameters:
4744 +  mat - the matrix
4745 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4746 
4747    Output Parameters:
4748 .  nrm - the resulting norm
4749 
4750    Level: intermediate
4751 
4752    Concepts: matrices^norm
4753    Concepts: norm^of matrix
4754 @*/
4755 PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4756 {
4757   PetscErrorCode ierr;
4758 
4759   PetscFunctionBegin;
4760   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4761   PetscValidType(mat,1);
4762   PetscValidScalarPointer(nrm,3);
4763 
4764   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4765   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4766   if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4767   MatCheckPreallocated(mat,1);
4768 
4769   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
4770   PetscFunctionReturn(0);
4771 }
4772 
4773 /*
4774      This variable is used to prevent counting of MatAssemblyBegin() that
4775    are called from within a MatAssemblyEnd().
4776 */
4777 static PetscInt MatAssemblyEnd_InUse = 0;
4778 #undef __FUNCT__
4779 #define __FUNCT__ "MatAssemblyBegin"
4780 /*@
4781    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4782    be called after completing all calls to MatSetValues().
4783 
4784    Collective on Mat
4785 
4786    Input Parameters:
4787 +  mat - the matrix
4788 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4789 
4790    Notes:
4791    MatSetValues() generally caches the values.  The matrix is ready to
4792    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4793    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4794    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4795    using the matrix.
4796 
4797    Level: beginner
4798 
4799    Concepts: matrices^assembling
4800 
4801 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4802 @*/
4803 PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4804 {
4805   PetscErrorCode ierr;
4806 
4807   PetscFunctionBegin;
4808   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4809   PetscValidType(mat,1);
4810   MatCheckPreallocated(mat,1);
4811   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4812   if (mat->assembled) {
4813     mat->was_assembled = PETSC_TRUE;
4814     mat->assembled     = PETSC_FALSE;
4815   }
4816   if (!MatAssemblyEnd_InUse) {
4817     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4818     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4819     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
4820   } else {
4821     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
4822   }
4823   PetscFunctionReturn(0);
4824 }
4825 
4826 #undef __FUNCT__
4827 #define __FUNCT__ "MatAssembled"
4828 /*@
4829    MatAssembled - Indicates if a matrix has been assembled and is ready for
4830      use; for example, in matrix-vector product.
4831 
4832    Not Collective
4833 
4834    Input Parameter:
4835 .  mat - the matrix
4836 
4837    Output Parameter:
4838 .  assembled - PETSC_TRUE or PETSC_FALSE
4839 
4840    Level: advanced
4841 
4842    Concepts: matrices^assembled?
4843 
4844 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4845 @*/
4846 PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4847 {
4848   PetscFunctionBegin;
4849   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4850   PetscValidType(mat,1);
4851   PetscValidPointer(assembled,2);
4852   *assembled = mat->assembled;
4853   PetscFunctionReturn(0);
4854 }
4855 
4856 #undef __FUNCT__
4857 #define __FUNCT__ "MatView_Private"
4858 /*
4859     Processes command line options to determine if/how a matrix
4860   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4861 */
4862 PetscErrorCode MatView_Private(Mat mat)
4863 {
4864   PetscErrorCode    ierr;
4865   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4866   static PetscBool  incall = PETSC_FALSE;
4867 #if defined(PETSC_USE_SOCKET_VIEWER)
4868   PetscBool         flg5 = PETSC_FALSE;
4869 #endif
4870 
4871   PetscFunctionBegin;
4872   if (incall) PetscFunctionReturn(0);
4873   incall = PETSC_TRUE;
4874   ierr = PetscObjectOptionsBegin((PetscObject)mat);CHKERRQ(ierr);
4875     ierr = PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr);
4876     ierr = PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr);
4877     ierr = PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr);
4878     ierr = PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr);
4879 #if defined(PETSC_USE_SOCKET_VIEWER)
4880     ierr = PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr);
4881 #endif
4882     ierr = PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr);
4883     ierr = PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr);
4884   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4885 
4886   if (flg1) {
4887     PetscViewer viewer;
4888 
4889     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4890     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
4891     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4892     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4893   }
4894   if (flg2) {
4895     PetscViewer viewer;
4896 
4897     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4898     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
4899     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4900     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4901   }
4902   if (flg3) {
4903     PetscViewer viewer;
4904 
4905     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4906     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4907   }
4908   if (flg4) {
4909     PetscViewer viewer;
4910 
4911     ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr);
4912     ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
4913     ierr = MatView(mat,viewer);CHKERRQ(ierr);
4914     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
4915   }
4916 #if defined(PETSC_USE_SOCKET_VIEWER)
4917   if (flg5) {
4918     ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4919     ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4920   }
4921 #endif
4922   if (flg6) {
4923     ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4924     ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4925   }
4926   if (flg7) {
4927     ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr);
4928     if (flg8) {
4929       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
4930     }
4931     ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4932     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4933     if (flg8) {
4934       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr);
4935     }
4936   }
4937   incall = PETSC_FALSE;
4938   PetscFunctionReturn(0);
4939 }
4940 
4941 #undef __FUNCT__
4942 #define __FUNCT__ "MatAssemblyEnd"
4943 /*@
4944    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4945    be called after MatAssemblyBegin().
4946 
4947    Collective on Mat
4948 
4949    Input Parameters:
4950 +  mat - the matrix
4951 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4952 
4953    Options Database Keys:
4954 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4955 .  -mat_view_info_detailed - Prints more detailed info
4956 .  -mat_view - Prints matrix in ASCII format
4957 .  -mat_view_matlab - Prints matrix in Matlab format
4958 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4959 .  -display <name> - Sets display name (default is host)
4960 .  -draw_pause <sec> - Sets number of seconds to pause after display
4961 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4962 .  -viewer_socket_machine <machine>
4963 .  -viewer_socket_port <port>
4964 .  -mat_view_binary - save matrix to file in binary format
4965 -  -viewer_binary_filename <name>
4966 
4967    Notes:
4968    MatSetValues() generally caches the values.  The matrix is ready to
4969    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4970    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4971    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4972    using the matrix.
4973 
4974    Level: beginner
4975 
4976 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4977 @*/
4978 PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4979 {
4980   PetscErrorCode  ierr;
4981   static PetscInt inassm = 0;
4982   PetscBool       flg = PETSC_FALSE;
4983 
4984   PetscFunctionBegin;
4985   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
4986   PetscValidType(mat,1);
4987 
4988   inassm++;
4989   MatAssemblyEnd_InUse++;
4990   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4991     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4992     if (mat->ops->assemblyend) {
4993       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4994     }
4995     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
4996   } else {
4997     if (mat->ops->assemblyend) {
4998       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
4999     }
5000   }
5001 
5002   /* Flush assembly is not a true assembly */
5003   if (type != MAT_FLUSH_ASSEMBLY) {
5004     mat->assembled  = PETSC_TRUE; mat->num_ass++;
5005   }
5006   mat->insertmode = NOT_SET_VALUES;
5007   MatAssemblyEnd_InUse--;
5008   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5009   if (!mat->symmetric_eternal) {
5010     mat->symmetric_set              = PETSC_FALSE;
5011     mat->hermitian_set              = PETSC_FALSE;
5012     mat->structurally_symmetric_set = PETSC_FALSE;
5013   }
5014 #if defined(PETSC_HAVE_CUSP)
5015   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5016     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5017   }
5018 #endif
5019   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5020     ierr = MatView_Private(mat);CHKERRQ(ierr);
5021     ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr);
5022     if (flg) {
5023       PetscReal tol = 0.0;
5024       ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr);
5025       ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr);
5026       if (flg) {
5027         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
5028       } else {
5029         ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr);
5030       }
5031     }
5032   }
5033   inassm--;
5034   PetscFunctionReturn(0);
5035 }
5036 
5037 #undef __FUNCT__
5038 #define __FUNCT__ "MatSetOption"
5039 /*@
5040    MatSetOption - Sets a parameter option for a matrix. Some options
5041    may be specific to certain storage formats.  Some options
5042    determine how values will be inserted (or added). Sorted,
5043    row-oriented input will generally assemble the fastest. The default
5044    is row-oriented, nonsorted input.
5045 
5046    Logically Collective on Mat
5047 
5048    Input Parameters:
5049 +  mat - the matrix
5050 .  option - the option, one of those listed below (and possibly others),
5051 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5052 
5053   Options Describing Matrix Structure:
5054 +    MAT_SPD - symmetric positive definite
5055 -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5056 .    MAT_HERMITIAN - transpose is the complex conjugation
5057 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5058 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5059                             you set to be kept with all future use of the matrix
5060                             including after MatAssemblyBegin/End() which could
5061                             potentially change the symmetry structure, i.e. you
5062                             KNOW the matrix will ALWAYS have the property you set.
5063 
5064 
5065    Options For Use with MatSetValues():
5066    Insert a logically dense subblock, which can be
5067 .    MAT_ROW_ORIENTED - row-oriented (default)
5068 
5069    Note these options reflect the data you pass in with MatSetValues(); it has
5070    nothing to do with how the data is stored internally in the matrix
5071    data structure.
5072 
5073    When (re)assembling a matrix, we can restrict the input for
5074    efficiency/debugging purposes.  These options include
5075 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5076         allowed if they generate a new nonzero
5077 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5078 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5079 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5080 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5081 +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5082         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5083         performance for very large process counts.
5084 
5085    Notes:
5086    Some options are relevant only for particular matrix types and
5087    are thus ignored by others.  Other options are not supported by
5088    certain matrix types and will generate an error message if set.
5089 
5090    If using a Fortran 77 module to compute a matrix, one may need to
5091    use the column-oriented option (or convert to the row-oriented
5092    format).
5093 
5094    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5095    that would generate a new entry in the nonzero structure is instead
5096    ignored.  Thus, if memory has not alredy been allocated for this particular
5097    data, then the insertion is ignored. For dense matrices, in which
5098    the entire array is allocated, no entries are ever ignored.
5099    Set after the first MatAssemblyEnd()
5100 
5101    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5102    that would generate a new entry in the nonzero structure instead produces
5103    an error. (Currently supported for AIJ and BAIJ formats only.)
5104    This is a useful flag when using SAME_NONZERO_PATTERN in calling
5105    KSPSetOperators() to ensure that the nonzero pattern truely does
5106    remain unchanged. Set after the first MatAssemblyEnd()
5107 
5108    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5109    that would generate a new entry that has not been preallocated will
5110    instead produce an error. (Currently supported for AIJ and BAIJ formats
5111    only.) This is a useful flag when debugging matrix memory preallocation.
5112 
5113    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5114    other processors should be dropped, rather than stashed.
5115    This is useful if you know that the "owning" processor is also
5116    always generating the correct matrix entries, so that PETSc need
5117    not transfer duplicate entries generated on another processor.
5118 
5119    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5120    searches during matrix assembly. When this flag is set, the hash table
5121    is created during the first Matrix Assembly. This hash table is
5122    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5123    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5124    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5125    supported by MATMPIBAIJ format only.
5126 
5127    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5128    are kept in the nonzero structure
5129 
5130    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5131    a zero location in the matrix
5132 
5133    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5134    ROWBS matrix types
5135 
5136    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5137         zero row routines and thus improves performance for very large process counts.
5138 
5139    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5140         part of the matrix (since they should match the upper triangular part).
5141 
5142    Level: intermediate
5143 
5144    Concepts: matrices^setting options
5145 
5146 @*/
5147 PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5148 {
5149   PetscErrorCode ierr;
5150 
5151   PetscFunctionBegin;
5152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5153   PetscValidType(mat,1);
5154   PetscValidLogicalCollectiveEnum(mat,op,2);
5155   PetscValidLogicalCollectiveBool(mat,flg,3);
5156 
5157   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);
5158   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()");
5159   MatCheckPreallocated(mat,1);
5160   switch (op) {
5161   case MAT_NO_OFF_PROC_ENTRIES:
5162     mat->nooffprocentries                = flg;
5163     PetscFunctionReturn(0);
5164     break;
5165   case MAT_NO_OFF_PROC_ZERO_ROWS:
5166     mat->nooffproczerorows               = flg;
5167     PetscFunctionReturn(0);
5168     break;
5169   case MAT_SPD:
5170     mat->spd_set                         = PETSC_TRUE;
5171     mat->spd                             = flg;
5172     if (flg) {
5173       mat->symmetric                     = PETSC_TRUE;
5174       mat->structurally_symmetric        = PETSC_TRUE;
5175       mat->symmetric_set                 = PETSC_TRUE;
5176       mat->structurally_symmetric_set    = PETSC_TRUE;
5177     }
5178     break;
5179   case MAT_SYMMETRIC:
5180     mat->symmetric                       = flg;
5181     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5182     mat->symmetric_set                   = PETSC_TRUE;
5183     mat->structurally_symmetric_set      = flg;
5184     break;
5185   case MAT_HERMITIAN:
5186     mat->hermitian                       = flg;
5187     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5188     mat->hermitian_set                   = PETSC_TRUE;
5189     mat->structurally_symmetric_set      = flg;
5190     break;
5191   case MAT_STRUCTURALLY_SYMMETRIC:
5192     mat->structurally_symmetric          = flg;
5193     mat->structurally_symmetric_set      = PETSC_TRUE;
5194     break;
5195   case MAT_SYMMETRY_ETERNAL:
5196     mat->symmetric_eternal               = flg;
5197     break;
5198   default:
5199     break;
5200   }
5201   if (mat->ops->setoption) {
5202     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5203   }
5204   PetscFunctionReturn(0);
5205 }
5206 
5207 #undef __FUNCT__
5208 #define __FUNCT__ "MatZeroEntries"
5209 /*@
5210    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5211    this routine retains the old nonzero structure.
5212 
5213    Logically Collective on Mat
5214 
5215    Input Parameters:
5216 .  mat - the matrix
5217 
5218    Level: intermediate
5219 
5220    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.
5221    See the Performance chapter of the users manual for information on preallocating matrices.
5222 
5223    Concepts: matrices^zeroing
5224 
5225 .seealso: MatZeroRows()
5226 @*/
5227 PetscErrorCode  MatZeroEntries(Mat mat)
5228 {
5229   PetscErrorCode ierr;
5230 
5231   PetscFunctionBegin;
5232   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5233   PetscValidType(mat,1);
5234   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5235   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");
5236   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5237   MatCheckPreallocated(mat,1);
5238 
5239   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5240   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5241   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5242   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5243 #if defined(PETSC_HAVE_CUSP)
5244   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5245     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5246   }
5247 #endif
5248   PetscFunctionReturn(0);
5249 }
5250 
5251 #undef __FUNCT__
5252 #define __FUNCT__ "MatZeroRowsColumns"
5253 /*@C
5254    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5255    of a set of rows and columns of a matrix.
5256 
5257    Collective on Mat
5258 
5259    Input Parameters:
5260 +  mat - the matrix
5261 .  numRows - the number of rows to remove
5262 .  rows - the global row indices
5263 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5264 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5265 -  b - optional vector of right hand side, that will be adjusted by provided solution
5266 
5267    Notes:
5268    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5269 
5270    The user can set a value in the diagonal entry (or for the AIJ and
5271    row formats can optionally remove the main diagonal entry from the
5272    nonzero structure as well, by passing 0.0 as the final argument).
5273 
5274    For the parallel case, all processes that share the matrix (i.e.,
5275    those in the communicator used for matrix creation) MUST call this
5276    routine, regardless of whether any rows being zeroed are owned by
5277    them.
5278 
5279    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5280    list only rows local to itself).
5281 
5282    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5283 
5284    Level: intermediate
5285 
5286    Concepts: matrices^zeroing rows
5287 
5288 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5289 @*/
5290 PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5291 {
5292   PetscErrorCode ierr;
5293 
5294   PetscFunctionBegin;
5295   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5296   PetscValidType(mat,1);
5297   if (numRows) PetscValidIntPointer(rows,3);
5298   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5299   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5300   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5301   MatCheckPreallocated(mat,1);
5302 
5303   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5304   ierr = MatView_Private(mat);CHKERRQ(ierr);
5305   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5306 #if defined(PETSC_HAVE_CUSP)
5307   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5308     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5309   }
5310 #endif
5311   PetscFunctionReturn(0);
5312 }
5313 
5314 #undef __FUNCT__
5315 #define __FUNCT__ "MatZeroRowsColumnsIS"
5316 /*@C
5317    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5318    of a set of rows and columns of a matrix.
5319 
5320    Collective on Mat
5321 
5322    Input Parameters:
5323 +  mat - the matrix
5324 .  is - the rows to zero
5325 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5326 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5327 -  b - optional vector of right hand side, that will be adjusted by provided solution
5328 
5329    Notes:
5330    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5331 
5332    The user can set a value in the diagonal entry (or for the AIJ and
5333    row formats can optionally remove the main diagonal entry from the
5334    nonzero structure as well, by passing 0.0 as the final argument).
5335 
5336    For the parallel case, all processes that share the matrix (i.e.,
5337    those in the communicator used for matrix creation) MUST call this
5338    routine, regardless of whether any rows being zeroed are owned by
5339    them.
5340 
5341    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5342    list only rows local to itself).
5343 
5344    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5345 
5346    Level: intermediate
5347 
5348    Concepts: matrices^zeroing rows
5349 
5350 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5351 @*/
5352 PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5353 {
5354   PetscErrorCode ierr;
5355   PetscInt       numRows;
5356   const PetscInt *rows;
5357 
5358   PetscFunctionBegin;
5359   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5360   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5361   PetscValidType(mat,1);
5362   PetscValidType(is,2);
5363   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5364   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5365   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5366   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5367   PetscFunctionReturn(0);
5368 }
5369 
5370 #undef __FUNCT__
5371 #define __FUNCT__ "MatZeroRows"
5372 /*@C
5373    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5374    of a set of rows of a matrix.
5375 
5376    Collective on Mat
5377 
5378    Input Parameters:
5379 +  mat - the matrix
5380 .  numRows - the number of rows to remove
5381 .  rows - the global row indices
5382 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5383 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5384 -  b - optional vector of right hand side, that will be adjusted by provided solution
5385 
5386    Notes:
5387    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5388    but does not release memory.  For the dense and block diagonal
5389    formats this does not alter the nonzero structure.
5390 
5391    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5392    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5393    merely zeroed.
5394 
5395    The user can set a value in the diagonal entry (or for the AIJ and
5396    row formats can optionally remove the main diagonal entry from the
5397    nonzero structure as well, by passing 0.0 as the final argument).
5398 
5399    For the parallel case, all processes that share the matrix (i.e.,
5400    those in the communicator used for matrix creation) MUST call this
5401    routine, regardless of whether any rows being zeroed are owned by
5402    them.
5403 
5404    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5405    list only rows local to itself).
5406 
5407    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5408    owns that are to be zeroed. This saves a global synchronization in the implementation.
5409 
5410    Level: intermediate
5411 
5412    Concepts: matrices^zeroing rows
5413 
5414 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5415 @*/
5416 PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5417 {
5418   PetscErrorCode ierr;
5419 
5420   PetscFunctionBegin;
5421   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5422   PetscValidType(mat,1);
5423   if (numRows) PetscValidIntPointer(rows,3);
5424   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5425   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5426   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5427   MatCheckPreallocated(mat,1);
5428 
5429   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5430   ierr = MatView_Private(mat);CHKERRQ(ierr);
5431   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5432 #if defined(PETSC_HAVE_CUSP)
5433   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5434     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5435   }
5436 #endif
5437   PetscFunctionReturn(0);
5438 }
5439 
5440 #undef __FUNCT__
5441 #define __FUNCT__ "MatZeroRowsIS"
5442 /*@C
5443    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5444    of a set of rows of a matrix.
5445 
5446    Collective on Mat
5447 
5448    Input Parameters:
5449 +  mat - the matrix
5450 .  is - index set of rows to remove
5451 .  diag - value put in all diagonals of eliminated rows
5452 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5453 -  b - optional vector of right hand side, that will be adjusted by provided solution
5454 
5455    Notes:
5456    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5457    but does not release memory.  For the dense and block diagonal
5458    formats this does not alter the nonzero structure.
5459 
5460    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5461    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5462    merely zeroed.
5463 
5464    The user can set a value in the diagonal entry (or for the AIJ and
5465    row formats can optionally remove the main diagonal entry from the
5466    nonzero structure as well, by passing 0.0 as the final argument).
5467 
5468    For the parallel case, all processes that share the matrix (i.e.,
5469    those in the communicator used for matrix creation) MUST call this
5470    routine, regardless of whether any rows being zeroed are owned by
5471    them.
5472 
5473    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5474    list only rows local to itself).
5475 
5476    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5477    owns that are to be zeroed. This saves a global synchronization in the implementation.
5478 
5479    Level: intermediate
5480 
5481    Concepts: matrices^zeroing rows
5482 
5483 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5484 @*/
5485 PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5486 {
5487   PetscInt       numRows;
5488   const PetscInt *rows;
5489   PetscErrorCode ierr;
5490 
5491   PetscFunctionBegin;
5492   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5493   PetscValidType(mat,1);
5494   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5495   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5496   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5497   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5498   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5499   PetscFunctionReturn(0);
5500 }
5501 
5502 #undef __FUNCT__
5503 #define __FUNCT__ "MatZeroRowsStencil"
5504 /*@C
5505    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5506    of a set of rows of a matrix. These rows must be local to the process.
5507 
5508    Collective on Mat
5509 
5510    Input Parameters:
5511 +  mat - the matrix
5512 .  numRows - the number of rows to remove
5513 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5514 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5515 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5516 -  b - optional vector of right hand side, that will be adjusted by provided solution
5517 
5518    Notes:
5519    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5520    but does not release memory.  For the dense and block diagonal
5521    formats this does not alter the nonzero structure.
5522 
5523    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5524    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5525    merely zeroed.
5526 
5527    The user can set a value in the diagonal entry (or for the AIJ and
5528    row formats can optionally remove the main diagonal entry from the
5529    nonzero structure as well, by passing 0.0 as the final argument).
5530 
5531    For the parallel case, all processes that share the matrix (i.e.,
5532    those in the communicator used for matrix creation) MUST call this
5533    routine, regardless of whether any rows being zeroed are owned by
5534    them.
5535 
5536    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5537    list only rows local to itself).
5538 
5539    The grid coordinates are across the entire grid, not just the local portion
5540 
5541    In Fortran idxm and idxn should be declared as
5542 $     MatStencil idxm(4,m)
5543    and the values inserted using
5544 $    idxm(MatStencil_i,1) = i
5545 $    idxm(MatStencil_j,1) = j
5546 $    idxm(MatStencil_k,1) = k
5547 $    idxm(MatStencil_c,1) = c
5548    etc
5549 
5550    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5551    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5552    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5553    DMDA_BOUNDARY_PERIODIC boundary type.
5554 
5555    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
5556    a single value per point) you can skip filling those indices.
5557 
5558    Level: intermediate
5559 
5560    Concepts: matrices^zeroing rows
5561 
5562 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5563 @*/
5564 PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5565 {
5566   PetscInt       dim    = mat->stencil.dim;
5567   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5568   PetscInt      *dims   = mat->stencil.dims+1;
5569   PetscInt      *starts = mat->stencil.starts;
5570   PetscInt      *dxm    = (PetscInt *) rows;
5571   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5572   PetscErrorCode ierr;
5573 
5574   PetscFunctionBegin;
5575   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5576   PetscValidType(mat,1);
5577   if (numRows) PetscValidIntPointer(rows,3);
5578 
5579   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5580   for(i = 0; i < numRows; ++i) {
5581     /* Skip unused dimensions (they are ordered k, j, i, c) */
5582     for(j = 0; j < 3-sdim; ++j) dxm++;
5583     /* Local index in X dir */
5584     tmp = *dxm++ - starts[0];
5585     /* Loop over remaining dimensions */
5586     for(j = 0; j < dim-1; ++j) {
5587       /* If nonlocal, set index to be negative */
5588       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5589       /* Update local index */
5590       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5591     }
5592     /* Skip component slot if necessary */
5593     if (mat->stencil.noc) dxm++;
5594     /* Local row number */
5595     if (tmp >= 0) {
5596       jdxm[numNewRows++] = tmp;
5597     }
5598   }
5599   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5600   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5601   PetscFunctionReturn(0);
5602 }
5603 
5604 #undef __FUNCT__
5605 #define __FUNCT__ "MatZeroRowsColumnsStencil"
5606 /*@C
5607    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5608    of a set of rows and columns of a matrix.
5609 
5610    Collective on Mat
5611 
5612    Input Parameters:
5613 +  mat - the matrix
5614 .  numRows - the number of rows/columns to remove
5615 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5616 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5617 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5618 -  b - optional vector of right hand side, that will be adjusted by provided solution
5619 
5620    Notes:
5621    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5622    but does not release memory.  For the dense and block diagonal
5623    formats this does not alter the nonzero structure.
5624 
5625    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5626    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5627    merely zeroed.
5628 
5629    The user can set a value in the diagonal entry (or for the AIJ and
5630    row formats can optionally remove the main diagonal entry from the
5631    nonzero structure as well, by passing 0.0 as the final argument).
5632 
5633    For the parallel case, all processes that share the matrix (i.e.,
5634    those in the communicator used for matrix creation) MUST call this
5635    routine, regardless of whether any rows being zeroed are owned by
5636    them.
5637 
5638    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5639    list only rows local to itself, but the row/column numbers are given in local numbering).
5640 
5641    The grid coordinates are across the entire grid, not just the local portion
5642 
5643    In Fortran idxm and idxn should be declared as
5644 $     MatStencil idxm(4,m)
5645    and the values inserted using
5646 $    idxm(MatStencil_i,1) = i
5647 $    idxm(MatStencil_j,1) = j
5648 $    idxm(MatStencil_k,1) = k
5649 $    idxm(MatStencil_c,1) = c
5650    etc
5651 
5652    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5653    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5654    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5655    DMDA_BOUNDARY_PERIODIC boundary type.
5656 
5657    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
5658    a single value per point) you can skip filling those indices.
5659 
5660    Level: intermediate
5661 
5662    Concepts: matrices^zeroing rows
5663 
5664 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5665 @*/
5666 PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5667 {
5668   PetscInt       dim    = mat->stencil.dim;
5669   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5670   PetscInt      *dims   = mat->stencil.dims+1;
5671   PetscInt      *starts = mat->stencil.starts;
5672   PetscInt      *dxm    = (PetscInt *) rows;
5673   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5674   PetscErrorCode ierr;
5675 
5676   PetscFunctionBegin;
5677   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5678   PetscValidType(mat,1);
5679   if (numRows) PetscValidIntPointer(rows,3);
5680 
5681   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5682   for(i = 0; i < numRows; ++i) {
5683     /* Skip unused dimensions (they are ordered k, j, i, c) */
5684     for(j = 0; j < 3-sdim; ++j) dxm++;
5685     /* Local index in X dir */
5686     tmp = *dxm++ - starts[0];
5687     /* Loop over remaining dimensions */
5688     for(j = 0; j < dim-1; ++j) {
5689       /* If nonlocal, set index to be negative */
5690       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5691       /* Update local index */
5692       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5693     }
5694     /* Skip component slot if necessary */
5695     if (mat->stencil.noc) dxm++;
5696     /* Local row number */
5697     if (tmp >= 0) {
5698       jdxm[numNewRows++] = tmp;
5699     }
5700   }
5701   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5702   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5703   PetscFunctionReturn(0);
5704 }
5705 
5706 #undef __FUNCT__
5707 #define __FUNCT__ "MatZeroRowsLocal"
5708 /*@C
5709    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5710    of a set of rows of a matrix; using local numbering of rows.
5711 
5712    Collective on Mat
5713 
5714    Input Parameters:
5715 +  mat - the matrix
5716 .  numRows - the number of rows to remove
5717 .  rows - the global row indices
5718 .  diag - value put in all diagonals of eliminated rows
5719 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5720 -  b - optional vector of right hand side, that will be adjusted by provided solution
5721 
5722    Notes:
5723    Before calling MatZeroRowsLocal(), the user must first set the
5724    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5725 
5726    For the AIJ matrix formats this removes the old nonzero structure,
5727    but does not release memory.  For the dense and block diagonal
5728    formats this does not alter the nonzero structure.
5729 
5730    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5731    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5732    merely zeroed.
5733 
5734    The user can set a value in the diagonal entry (or for the AIJ and
5735    row formats can optionally remove the main diagonal entry from the
5736    nonzero structure as well, by passing 0.0 as the final argument).
5737 
5738    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5739    owns that are to be zeroed. This saves a global synchronization in the implementation.
5740 
5741    Level: intermediate
5742 
5743    Concepts: matrices^zeroing
5744 
5745 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5746 @*/
5747 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5748 {
5749   PetscErrorCode ierr;
5750   PetscMPIInt    size;
5751 
5752   PetscFunctionBegin;
5753   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5754   PetscValidType(mat,1);
5755   if (numRows) PetscValidIntPointer(rows,3);
5756   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5757   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5758   MatCheckPreallocated(mat,1);
5759 
5760   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5761   if (mat->ops->zerorowslocal) {
5762     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5763   } else if (size == 1) {
5764     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5765   } else {
5766     IS             is, newis;
5767     const PetscInt *newRows;
5768 
5769     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5770     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5771     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5772     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5773     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5774     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5775     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5776     ierr = ISDestroy(&is);CHKERRQ(ierr);
5777   }
5778   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5779 #if defined(PETSC_HAVE_CUSP)
5780   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5781     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5782   }
5783 #endif
5784   PetscFunctionReturn(0);
5785 }
5786 
5787 #undef __FUNCT__
5788 #define __FUNCT__ "MatZeroRowsLocalIS"
5789 /*@C
5790    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5791    of a set of rows of a matrix; using local numbering of rows.
5792 
5793    Collective on Mat
5794 
5795    Input Parameters:
5796 +  mat - the matrix
5797 .  is - index set of rows to remove
5798 .  diag - value put in all diagonals of eliminated rows
5799 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5800 -  b - optional vector of right hand side, that will be adjusted by provided solution
5801 
5802    Notes:
5803    Before calling MatZeroRowsLocalIS(), the user must first set the
5804    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5805 
5806    For the AIJ matrix formats this removes the old nonzero structure,
5807    but does not release memory.  For the dense and block diagonal
5808    formats this does not alter the nonzero structure.
5809 
5810    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5811    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5812    merely zeroed.
5813 
5814    The user can set a value in the diagonal entry (or for the AIJ and
5815    row formats can optionally remove the main diagonal entry from the
5816    nonzero structure as well, by passing 0.0 as the final argument).
5817 
5818    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5819    owns that are to be zeroed. This saves a global synchronization in the implementation.
5820 
5821    Level: intermediate
5822 
5823    Concepts: matrices^zeroing
5824 
5825 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5826 @*/
5827 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5828 {
5829   PetscErrorCode ierr;
5830   PetscInt       numRows;
5831   const PetscInt *rows;
5832 
5833   PetscFunctionBegin;
5834   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5835   PetscValidType(mat,1);
5836   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5837   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5838   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5839   MatCheckPreallocated(mat,1);
5840 
5841   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5842   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5843   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5844   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5845   PetscFunctionReturn(0);
5846 }
5847 
5848 #undef __FUNCT__
5849 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5850 /*@C
5851    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5852    of a set of rows and columns of a matrix; using local numbering of rows.
5853 
5854    Collective on Mat
5855 
5856    Input Parameters:
5857 +  mat - the matrix
5858 .  numRows - the number of rows to remove
5859 .  rows - the global row indices
5860 .  diag - value put in all diagonals of eliminated rows
5861 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5862 -  b - optional vector of right hand side, that will be adjusted by provided solution
5863 
5864    Notes:
5865    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5866    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5867 
5868    The user can set a value in the diagonal entry (or for the AIJ and
5869    row formats can optionally remove the main diagonal entry from the
5870    nonzero structure as well, by passing 0.0 as the final argument).
5871 
5872    Level: intermediate
5873 
5874    Concepts: matrices^zeroing
5875 
5876 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5877 @*/
5878 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5879 {
5880   PetscErrorCode ierr;
5881   PetscMPIInt    size;
5882 
5883   PetscFunctionBegin;
5884   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5885   PetscValidType(mat,1);
5886   if (numRows) PetscValidIntPointer(rows,3);
5887   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5888   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5889   MatCheckPreallocated(mat,1);
5890 
5891   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5892   if (size == 1) {
5893     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5894   } else {
5895     IS             is, newis;
5896     const PetscInt *newRows;
5897 
5898     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5899     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5900     ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
5901     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5902     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5903     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5904     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5905     ierr = ISDestroy(&is);CHKERRQ(ierr);
5906   }
5907   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5908 #if defined(PETSC_HAVE_CUSP)
5909   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5910     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5911   }
5912 #endif
5913   PetscFunctionReturn(0);
5914 }
5915 
5916 #undef __FUNCT__
5917 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5918 /*@C
5919    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5920    of a set of rows and columns of a matrix; using local numbering of rows.
5921 
5922    Collective on Mat
5923 
5924    Input Parameters:
5925 +  mat - the matrix
5926 .  is - index set of rows to remove
5927 .  diag - value put in all diagonals of eliminated rows
5928 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5929 -  b - optional vector of right hand side, that will be adjusted by provided solution
5930 
5931    Notes:
5932    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5933    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5934 
5935    The user can set a value in the diagonal entry (or for the AIJ and
5936    row formats can optionally remove the main diagonal entry from the
5937    nonzero structure as well, by passing 0.0 as the final argument).
5938 
5939    Level: intermediate
5940 
5941    Concepts: matrices^zeroing
5942 
5943 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5944 @*/
5945 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5946 {
5947   PetscErrorCode ierr;
5948   PetscInt       numRows;
5949   const PetscInt *rows;
5950 
5951   PetscFunctionBegin;
5952   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5953   PetscValidType(mat,1);
5954   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5955   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5956   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5957   MatCheckPreallocated(mat,1);
5958 
5959   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5960   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5961   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5962   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5963   PetscFunctionReturn(0);
5964 }
5965 
5966 #undef __FUNCT__
5967 #define __FUNCT__ "MatGetSize"
5968 /*@
5969    MatGetSize - Returns the numbers of rows and columns in a matrix.
5970 
5971    Not Collective
5972 
5973    Input Parameter:
5974 .  mat - the matrix
5975 
5976    Output Parameters:
5977 +  m - the number of global rows
5978 -  n - the number of global columns
5979 
5980    Note: both output parameters can be PETSC_NULL on input.
5981 
5982    Level: beginner
5983 
5984    Concepts: matrices^size
5985 
5986 .seealso: MatGetLocalSize()
5987 @*/
5988 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5989 {
5990   PetscFunctionBegin;
5991   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5992   if (m) *m = mat->rmap->N;
5993   if (n) *n = mat->cmap->N;
5994   PetscFunctionReturn(0);
5995 }
5996 
5997 #undef __FUNCT__
5998 #define __FUNCT__ "MatGetLocalSize"
5999 /*@
6000    MatGetLocalSize - Returns the number of rows and columns in a matrix
6001    stored locally.  This information may be implementation dependent, so
6002    use with care.
6003 
6004    Not Collective
6005 
6006    Input Parameters:
6007 .  mat - the matrix
6008 
6009    Output Parameters:
6010 +  m - the number of local rows
6011 -  n - the number of local columns
6012 
6013    Note: both output parameters can be PETSC_NULL on input.
6014 
6015    Level: beginner
6016 
6017    Concepts: matrices^local size
6018 
6019 .seealso: MatGetSize()
6020 @*/
6021 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
6022 {
6023   PetscFunctionBegin;
6024   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6025   if (m) PetscValidIntPointer(m,2);
6026   if (n) PetscValidIntPointer(n,3);
6027   if (m) *m = mat->rmap->n;
6028   if (n) *n = mat->cmap->n;
6029   PetscFunctionReturn(0);
6030 }
6031 
6032 #undef __FUNCT__
6033 #define __FUNCT__ "MatGetOwnershipRangeColumn"
6034 /*@
6035    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6036    this processor. (The columns of the "diagonal block")
6037 
6038    Not Collective, unless matrix has not been allocated, then collective on Mat
6039 
6040    Input Parameters:
6041 .  mat - the matrix
6042 
6043    Output Parameters:
6044 +  m - the global index of the first local column
6045 -  n - one more than the global index of the last local column
6046 
6047    Notes: both output parameters can be PETSC_NULL on input.
6048 
6049    Level: developer
6050 
6051    Concepts: matrices^column ownership
6052 
6053 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6054 
6055 @*/
6056 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
6057 {
6058 
6059   PetscFunctionBegin;
6060   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6061   PetscValidType(mat,1);
6062   if (m) PetscValidIntPointer(m,2);
6063   if (n) PetscValidIntPointer(n,3);
6064   MatCheckPreallocated(mat,1);
6065   if (m) *m = mat->cmap->rstart;
6066   if (n) *n = mat->cmap->rend;
6067   PetscFunctionReturn(0);
6068 }
6069 
6070 #undef __FUNCT__
6071 #define __FUNCT__ "MatGetOwnershipRange"
6072 /*@
6073    MatGetOwnershipRange - Returns the range of matrix rows owned by
6074    this processor, assuming that the matrix is laid out with the first
6075    n1 rows on the first processor, the next n2 rows on the second, etc.
6076    For certain parallel layouts this range may not be well defined.
6077 
6078    Not Collective, unless matrix has not been allocated, then collective on Mat
6079 
6080    Input Parameters:
6081 .  mat - the matrix
6082 
6083    Output Parameters:
6084 +  m - the global index of the first local row
6085 -  n - one more than the global index of the last local row
6086 
6087    Note: both output parameters can be PETSC_NULL on input.
6088 
6089    Level: beginner
6090 
6091    Concepts: matrices^row ownership
6092 
6093 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6094 
6095 @*/
6096 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
6097 {
6098 
6099   PetscFunctionBegin;
6100   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6101   PetscValidType(mat,1);
6102   if (m) PetscValidIntPointer(m,2);
6103   if (n) PetscValidIntPointer(n,3);
6104   MatCheckPreallocated(mat,1);
6105   if (m) *m = mat->rmap->rstart;
6106   if (n) *n = mat->rmap->rend;
6107   PetscFunctionReturn(0);
6108 }
6109 
6110 #undef __FUNCT__
6111 #define __FUNCT__ "MatGetOwnershipRanges"
6112 /*@C
6113    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6114    each process
6115 
6116    Not Collective, unless matrix has not been allocated, then collective on Mat
6117 
6118    Input Parameters:
6119 .  mat - the matrix
6120 
6121    Output Parameters:
6122 .  ranges - start of each processors portion plus one more then the total length at the end
6123 
6124    Level: beginner
6125 
6126    Concepts: matrices^row ownership
6127 
6128 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6129 
6130 @*/
6131 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6132 {
6133   PetscErrorCode ierr;
6134 
6135   PetscFunctionBegin;
6136   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6137   PetscValidType(mat,1);
6138   MatCheckPreallocated(mat,1);
6139   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6140   PetscFunctionReturn(0);
6141 }
6142 
6143 #undef __FUNCT__
6144 #define __FUNCT__ "MatGetOwnershipRangesColumn"
6145 /*@C
6146    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6147    this processor. (The columns of the "diagonal blocks" for each process)
6148 
6149    Not Collective, unless matrix has not been allocated, then collective on Mat
6150 
6151    Input Parameters:
6152 .  mat - the matrix
6153 
6154    Output Parameters:
6155 .  ranges - start of each processors portion plus one more then the total length at the end
6156 
6157    Level: beginner
6158 
6159    Concepts: matrices^column ownership
6160 
6161 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6162 
6163 @*/
6164 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6165 {
6166   PetscErrorCode ierr;
6167 
6168   PetscFunctionBegin;
6169   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6170   PetscValidType(mat,1);
6171   MatCheckPreallocated(mat,1);
6172   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6173   PetscFunctionReturn(0);
6174 }
6175 
6176 #undef __FUNCT__
6177 #define __FUNCT__ "MatILUFactorSymbolic"
6178 /*@C
6179    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6180    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6181    to complete the factorization.
6182 
6183    Collective on Mat
6184 
6185    Input Parameters:
6186 +  mat - the matrix
6187 .  row - row permutation
6188 .  column - column permutation
6189 -  info - structure containing
6190 $      levels - number of levels of fill.
6191 $      expected fill - as ratio of original fill.
6192 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6193                 missing diagonal entries)
6194 
6195    Output Parameters:
6196 .  fact - new matrix that has been symbolically factored
6197 
6198    Notes:
6199    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6200    choosing the fill factor for better efficiency.
6201 
6202    Most users should employ the simplified KSP interface for linear solvers
6203    instead of working directly with matrix algebra routines such as this.
6204    See, e.g., KSPCreate().
6205 
6206    Level: developer
6207 
6208   Concepts: matrices^symbolic LU factorization
6209   Concepts: matrices^factorization
6210   Concepts: LU^symbolic factorization
6211 
6212 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6213           MatGetOrdering(), MatFactorInfo
6214 
6215     Developer Note: fortran interface is not autogenerated as the f90
6216     interface defintion cannot be generated correctly [due to MatFactorInfo]
6217 
6218 @*/
6219 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6220 {
6221   PetscErrorCode ierr;
6222 
6223   PetscFunctionBegin;
6224   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6225   PetscValidType(mat,1);
6226   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6227   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6228   PetscValidPointer(info,4);
6229   PetscValidPointer(fact,5);
6230   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6231   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6232   if (!(fact)->ops->ilufactorsymbolic) {
6233     const MatSolverPackage spackage;
6234     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6235     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6236   }
6237   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6238   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6239   MatCheckPreallocated(mat,2);
6240 
6241   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6242   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6243   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6244   PetscFunctionReturn(0);
6245 }
6246 
6247 #undef __FUNCT__
6248 #define __FUNCT__ "MatICCFactorSymbolic"
6249 /*@C
6250    MatICCFactorSymbolic - Performs symbolic incomplete
6251    Cholesky factorization for a symmetric matrix.  Use
6252    MatCholeskyFactorNumeric() to complete the factorization.
6253 
6254    Collective on Mat
6255 
6256    Input Parameters:
6257 +  mat - the matrix
6258 .  perm - row and column permutation
6259 -  info - structure containing
6260 $      levels - number of levels of fill.
6261 $      expected fill - as ratio of original fill.
6262 
6263    Output Parameter:
6264 .  fact - the factored matrix
6265 
6266    Notes:
6267    Most users should employ the KSP interface for linear solvers
6268    instead of working directly with matrix algebra routines such as this.
6269    See, e.g., KSPCreate().
6270 
6271    Level: developer
6272 
6273   Concepts: matrices^symbolic incomplete Cholesky factorization
6274   Concepts: matrices^factorization
6275   Concepts: Cholsky^symbolic factorization
6276 
6277 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6278 
6279     Developer Note: fortran interface is not autogenerated as the f90
6280     interface defintion cannot be generated correctly [due to MatFactorInfo]
6281 
6282 @*/
6283 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6284 {
6285   PetscErrorCode ierr;
6286 
6287   PetscFunctionBegin;
6288   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6289   PetscValidType(mat,1);
6290   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6291   PetscValidPointer(info,3);
6292   PetscValidPointer(fact,4);
6293   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6294   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6295   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6296   if (!(fact)->ops->iccfactorsymbolic) {
6297     const MatSolverPackage spackage;
6298     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6299     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6300   }
6301   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6302   MatCheckPreallocated(mat,2);
6303 
6304   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6305   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6306   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6307   PetscFunctionReturn(0);
6308 }
6309 
6310 #undef __FUNCT__
6311 #define __FUNCT__ "MatGetArray"
6312 /*@C
6313    MatGetArray - Returns a pointer to the element values in the matrix.
6314    The result of this routine is dependent on the underlying matrix data
6315    structure, and may not even work for certain matrix types.  You MUST
6316    call MatRestoreArray() when you no longer need to access the array.
6317 
6318    Not Collective
6319 
6320    Input Parameter:
6321 .  mat - the matrix
6322 
6323    Output Parameter:
6324 .  v - the location of the values
6325 
6326 
6327    Fortran Note:
6328    This routine is used differently from Fortran, e.g.,
6329 .vb
6330         Mat         mat
6331         PetscScalar mat_array(1)
6332         PetscOffset i_mat
6333         PetscErrorCode ierr
6334         call MatGetArray(mat,mat_array,i_mat,ierr)
6335 
6336   C  Access first local entry in matrix; note that array is
6337   C  treated as one dimensional
6338         value = mat_array(i_mat + 1)
6339 
6340         [... other code ...]
6341         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6342 .ve
6343 
6344    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6345    src/mat/examples/tests for details.
6346 
6347    Level: advanced
6348 
6349    Concepts: matrices^access array
6350 
6351 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6352 @*/
6353 PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6354 {
6355   PetscErrorCode ierr;
6356 
6357   PetscFunctionBegin;
6358   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6359   PetscValidType(mat,1);
6360   PetscValidPointer(v,2);
6361   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6362   MatCheckPreallocated(mat,1);
6363   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6364   CHKMEMQ;
6365   PetscFunctionReturn(0);
6366 }
6367 
6368 #undef __FUNCT__
6369 #define __FUNCT__ "MatRestoreArray"
6370 /*@C
6371    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6372 
6373    Not Collective
6374 
6375    Input Parameter:
6376 +  mat - the matrix
6377 -  v - the location of the values
6378 
6379    Fortran Note:
6380    This routine is used differently from Fortran, e.g.,
6381 .vb
6382         Mat         mat
6383         PetscScalar mat_array(1)
6384         PetscOffset i_mat
6385         PetscErrorCode ierr
6386         call MatGetArray(mat,mat_array,i_mat,ierr)
6387 
6388   C  Access first local entry in matrix; note that array is
6389   C  treated as one dimensional
6390         value = mat_array(i_mat + 1)
6391 
6392         [... other code ...]
6393         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6394 .ve
6395 
6396    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6397    src/mat/examples/tests for details
6398 
6399    Level: advanced
6400 
6401 .seealso: MatGetArray(), MatRestoreArrayF90()
6402 @*/
6403 PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6404 {
6405   PetscErrorCode ierr;
6406 
6407   PetscFunctionBegin;
6408   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6409   PetscValidType(mat,1);
6410   PetscValidPointer(v,2);
6411   CHKMEMQ;
6412   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6413   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6414   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6415 #if defined(PETSC_HAVE_CUSP)
6416   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6417     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6418   }
6419 #endif
6420   PetscFunctionReturn(0);
6421 }
6422 
6423 #undef __FUNCT__
6424 #define __FUNCT__ "MatGetSubMatrices"
6425 /*@C
6426    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6427    points to an array of valid matrices, they may be reused to store the new
6428    submatrices.
6429 
6430    Collective on Mat
6431 
6432    Input Parameters:
6433 +  mat - the matrix
6434 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6435 .  irow, icol - index sets of rows and columns to extract
6436 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6437 
6438    Output Parameter:
6439 .  submat - the array of submatrices
6440 
6441    Notes:
6442    MatGetSubMatrices() can extract ONLY sequential submatrices
6443    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6444    to extract a parallel submatrix.
6445 
6446    When extracting submatrices from a parallel matrix, each processor can
6447    form a different submatrix by setting the rows and columns of its
6448    individual index sets according to the local submatrix desired.
6449 
6450    When finished using the submatrices, the user should destroy
6451    them with MatDestroyMatrices().
6452 
6453    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6454    original matrix has not changed from that last call to MatGetSubMatrices().
6455 
6456    This routine creates the matrices in submat; you should NOT create them before
6457    calling it. It also allocates the array of matrix pointers submat.
6458 
6459    For BAIJ matrices the index sets must respect the block structure, that is if they
6460    request one row/column in a block, they must request all rows/columns that are in
6461    that block. For example, if the block size is 2 you cannot request just row 0 and
6462    column 0.
6463 
6464    Fortran Note:
6465    The Fortran interface is slightly different from that given below; it
6466    requires one to pass in  as submat a Mat (integer) array of size at least m.
6467 
6468    Level: advanced
6469 
6470    Concepts: matrices^accessing submatrices
6471    Concepts: submatrices
6472 
6473 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6474 @*/
6475 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6476 {
6477   PetscErrorCode ierr;
6478   PetscInt        i;
6479   PetscBool       eq;
6480 
6481   PetscFunctionBegin;
6482   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6483   PetscValidType(mat,1);
6484   if (n) {
6485     PetscValidPointer(irow,3);
6486     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6487     PetscValidPointer(icol,4);
6488     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6489   }
6490   PetscValidPointer(submat,6);
6491   if (n && scall == MAT_REUSE_MATRIX) {
6492     PetscValidPointer(*submat,6);
6493     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6494   }
6495   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6496   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6497   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6498   MatCheckPreallocated(mat,1);
6499 
6500   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6501   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6502   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6503   for (i=0; i<n; i++) {
6504     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6505       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6506       if (eq) {
6507 	if (mat->symmetric){
6508 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6509 	} else if (mat->hermitian) {
6510 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6511 	} else if (mat->structurally_symmetric) {
6512 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6513 	}
6514       }
6515     }
6516   }
6517   PetscFunctionReturn(0);
6518 }
6519 
6520 #undef __FUNCT__
6521 #define __FUNCT__ "MatGetSubMatricesParallel"
6522 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6523 {
6524   PetscErrorCode ierr;
6525   PetscInt        i;
6526   PetscBool       eq;
6527 
6528   PetscFunctionBegin;
6529   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6530   PetscValidType(mat,1);
6531   if (n) {
6532     PetscValidPointer(irow,3);
6533     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6534     PetscValidPointer(icol,4);
6535     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6536   }
6537   PetscValidPointer(submat,6);
6538   if (n && scall == MAT_REUSE_MATRIX) {
6539     PetscValidPointer(*submat,6);
6540     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6541   }
6542   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6543   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6544   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6545   MatCheckPreallocated(mat,1);
6546 
6547   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6548   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6549   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6550   for (i=0; i<n; i++) {
6551     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6552       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6553       if (eq) {
6554 	if (mat->symmetric){
6555 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6556 	} else if (mat->hermitian) {
6557 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6558 	} else if (mat->structurally_symmetric) {
6559 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6560 	}
6561       }
6562     }
6563   }
6564   PetscFunctionReturn(0);
6565 }
6566 
6567 #undef __FUNCT__
6568 #define __FUNCT__ "MatDestroyMatrices"
6569 /*@C
6570    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6571 
6572    Collective on Mat
6573 
6574    Input Parameters:
6575 +  n - the number of local matrices
6576 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6577                        sequence of MatGetSubMatrices())
6578 
6579    Level: advanced
6580 
6581     Notes: Frees not only the matrices, but also the array that contains the matrices
6582            In Fortran will not free the array.
6583 
6584 .seealso: MatGetSubMatrices()
6585 @*/
6586 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6587 {
6588   PetscErrorCode ierr;
6589   PetscInt       i;
6590 
6591   PetscFunctionBegin;
6592   if (!*mat) PetscFunctionReturn(0);
6593   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6594   PetscValidPointer(mat,2);
6595   for (i=0; i<n; i++) {
6596     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6597   }
6598   /* memory is allocated even if n = 0 */
6599   ierr = PetscFree(*mat);CHKERRQ(ierr);
6600   *mat = PETSC_NULL;
6601   PetscFunctionReturn(0);
6602 }
6603 
6604 #undef __FUNCT__
6605 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6606 /*@C
6607    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6608 
6609    Collective on Mat
6610 
6611    Input Parameters:
6612 .  mat - the matrix
6613 
6614    Output Parameter:
6615 .  matstruct - the sequential matrix with the nonzero structure of mat
6616 
6617   Level: intermediate
6618 
6619 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6620 @*/
6621 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6622 {
6623   PetscErrorCode ierr;
6624 
6625   PetscFunctionBegin;
6626   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6627   PetscValidPointer(matstruct,2);
6628 
6629   PetscValidType(mat,1);
6630   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6631   MatCheckPreallocated(mat,1);
6632 
6633   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6634   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6635   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6636   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6637   PetscFunctionReturn(0);
6638 }
6639 
6640 #undef __FUNCT__
6641 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6642 /*@C
6643    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6644 
6645    Collective on Mat
6646 
6647    Input Parameters:
6648 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6649                        sequence of MatGetSequentialNonzeroStructure())
6650 
6651    Level: advanced
6652 
6653     Notes: Frees not only the matrices, but also the array that contains the matrices
6654 
6655 .seealso: MatGetSeqNonzeroStructure()
6656 @*/
6657 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6658 {
6659   PetscErrorCode ierr;
6660 
6661   PetscFunctionBegin;
6662   PetscValidPointer(mat,1);
6663   ierr = MatDestroy(mat);CHKERRQ(ierr);
6664   PetscFunctionReturn(0);
6665 }
6666 
6667 #undef __FUNCT__
6668 #define __FUNCT__ "MatIncreaseOverlap"
6669 /*@
6670    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6671    replaces the index sets by larger ones that represent submatrices with
6672    additional overlap.
6673 
6674    Collective on Mat
6675 
6676    Input Parameters:
6677 +  mat - the matrix
6678 .  n   - the number of index sets
6679 .  is  - the array of index sets (these index sets will changed during the call)
6680 -  ov  - the additional overlap requested
6681 
6682    Level: developer
6683 
6684    Concepts: overlap
6685    Concepts: ASM^computing overlap
6686 
6687 .seealso: MatGetSubMatrices()
6688 @*/
6689 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6690 {
6691   PetscErrorCode ierr;
6692 
6693   PetscFunctionBegin;
6694   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6695   PetscValidType(mat,1);
6696   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6697   if (n) {
6698     PetscValidPointer(is,3);
6699     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6700   }
6701   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6702   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6703   MatCheckPreallocated(mat,1);
6704 
6705   if (!ov) PetscFunctionReturn(0);
6706   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6707   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6708   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6709   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6710   PetscFunctionReturn(0);
6711 }
6712 
6713 #undef __FUNCT__
6714 #define __FUNCT__ "MatGetBlockSize"
6715 /*@
6716    MatGetBlockSize - Returns the matrix block size; useful especially for the
6717    block row and block diagonal formats.
6718 
6719    Not Collective
6720 
6721    Input Parameter:
6722 .  mat - the matrix
6723 
6724    Output Parameter:
6725 .  bs - block size
6726 
6727    Notes:
6728    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6729 
6730    Level: intermediate
6731 
6732    Concepts: matrices^block size
6733 
6734 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ()
6735 @*/
6736 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6737 {
6738 
6739   PetscFunctionBegin;
6740   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6741   PetscValidType(mat,1);
6742   PetscValidIntPointer(bs,2);
6743   MatCheckPreallocated(mat,1);
6744   *bs = mat->rmap->bs;
6745   PetscFunctionReturn(0);
6746 }
6747 
6748 #undef __FUNCT__
6749 #define __FUNCT__ "MatSetBlockSize"
6750 /*@
6751    MatSetBlockSize - Sets the matrix block size.
6752 
6753    Logically Collective on Mat
6754 
6755    Input Parameters:
6756 +  mat - the matrix
6757 -  bs - block size
6758 
6759    Notes:
6760      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6761 
6762    Level: intermediate
6763 
6764    Concepts: matrices^block size
6765 
6766 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6767 @*/
6768 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6769 {
6770   PetscErrorCode ierr;
6771 
6772   PetscFunctionBegin;
6773   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6774   PetscValidLogicalCollectiveInt(mat,bs,2);
6775   ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
6776   ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
6777   PetscFunctionReturn(0);
6778 }
6779 
6780 #undef __FUNCT__
6781 #define __FUNCT__ "MatGetRowIJ"
6782 /*@C
6783     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6784 
6785    Collective on Mat
6786 
6787     Input Parameters:
6788 +   mat - the matrix
6789 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6790 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6791 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6792                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6793                  always used.
6794 
6795     Output Parameters:
6796 +   n - number of rows in the (possibly compressed) matrix
6797 .   ia - the row pointers [of length n+1]
6798 .   ja - the column indices
6799 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6800            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6801 
6802     Level: developer
6803 
6804     Notes: You CANNOT change any of the ia[] or ja[] values.
6805 
6806            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6807 
6808     Fortran Node
6809 
6810            In Fortran use
6811 $           PetscInt ia(1), ja(1)
6812 $           PetscOffset iia, jja
6813 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6814 $
6815 $          or
6816 $
6817 $           PetscScalar, pointer :: xx_v(:)
6818 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6819 
6820 
6821        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6822 
6823 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6824 @*/
6825 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6826 {
6827   PetscErrorCode ierr;
6828 
6829   PetscFunctionBegin;
6830   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6831   PetscValidType(mat,1);
6832   PetscValidIntPointer(n,4);
6833   if (ia) PetscValidIntPointer(ia,5);
6834   if (ja) PetscValidIntPointer(ja,6);
6835   PetscValidIntPointer(done,7);
6836   MatCheckPreallocated(mat,1);
6837   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6838   else {
6839     *done = PETSC_TRUE;
6840     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6841     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6842     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6843   }
6844   PetscFunctionReturn(0);
6845 }
6846 
6847 #undef __FUNCT__
6848 #define __FUNCT__ "MatGetColumnIJ"
6849 /*@C
6850     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6851 
6852     Collective on Mat
6853 
6854     Input Parameters:
6855 +   mat - the matrix
6856 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6857 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6858                 symmetrized
6859 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6860                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6861                  always used.
6862 
6863     Output Parameters:
6864 +   n - number of columns in the (possibly compressed) matrix
6865 .   ia - the column pointers
6866 .   ja - the row indices
6867 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6868 
6869     Level: developer
6870 
6871 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6872 @*/
6873 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6874 {
6875   PetscErrorCode ierr;
6876 
6877   PetscFunctionBegin;
6878   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6879   PetscValidType(mat,1);
6880   PetscValidIntPointer(n,4);
6881   if (ia) PetscValidIntPointer(ia,5);
6882   if (ja) PetscValidIntPointer(ja,6);
6883   PetscValidIntPointer(done,7);
6884   MatCheckPreallocated(mat,1);
6885   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6886   else {
6887     *done = PETSC_TRUE;
6888     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6889   }
6890   PetscFunctionReturn(0);
6891 }
6892 
6893 #undef __FUNCT__
6894 #define __FUNCT__ "MatRestoreRowIJ"
6895 /*@C
6896     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6897     MatGetRowIJ().
6898 
6899     Collective on Mat
6900 
6901     Input Parameters:
6902 +   mat - the matrix
6903 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6904 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6905                 symmetrized
6906 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6907                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6908                  always used.
6909 
6910     Output Parameters:
6911 +   n - size of (possibly compressed) matrix
6912 .   ia - the row pointers
6913 .   ja - the column indices
6914 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6915 
6916     Level: developer
6917 
6918 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6919 @*/
6920 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6921 {
6922   PetscErrorCode ierr;
6923 
6924   PetscFunctionBegin;
6925   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6926   PetscValidType(mat,1);
6927   if (ia) PetscValidIntPointer(ia,5);
6928   if (ja) PetscValidIntPointer(ja,6);
6929   PetscValidIntPointer(done,7);
6930   MatCheckPreallocated(mat,1);
6931 
6932   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6933   else {
6934     *done = PETSC_TRUE;
6935     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6936   }
6937   PetscFunctionReturn(0);
6938 }
6939 
6940 #undef __FUNCT__
6941 #define __FUNCT__ "MatRestoreColumnIJ"
6942 /*@C
6943     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6944     MatGetColumnIJ().
6945 
6946     Collective on Mat
6947 
6948     Input Parameters:
6949 +   mat - the matrix
6950 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6951 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6952                 symmetrized
6953 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6954                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6955                  always used.
6956 
6957     Output Parameters:
6958 +   n - size of (possibly compressed) matrix
6959 .   ia - the column pointers
6960 .   ja - the row indices
6961 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6962 
6963     Level: developer
6964 
6965 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6966 @*/
6967 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6968 {
6969   PetscErrorCode ierr;
6970 
6971   PetscFunctionBegin;
6972   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6973   PetscValidType(mat,1);
6974   if (ia) PetscValidIntPointer(ia,5);
6975   if (ja) PetscValidIntPointer(ja,6);
6976   PetscValidIntPointer(done,7);
6977   MatCheckPreallocated(mat,1);
6978 
6979   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6980   else {
6981     *done = PETSC_TRUE;
6982     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6983   }
6984   PetscFunctionReturn(0);
6985 }
6986 
6987 #undef __FUNCT__
6988 #define __FUNCT__ "MatColoringPatch"
6989 /*@C
6990     MatColoringPatch -Used inside matrix coloring routines that
6991     use MatGetRowIJ() and/or MatGetColumnIJ().
6992 
6993     Collective on Mat
6994 
6995     Input Parameters:
6996 +   mat - the matrix
6997 .   ncolors - max color value
6998 .   n   - number of entries in colorarray
6999 -   colorarray - array indicating color for each column
7000 
7001     Output Parameters:
7002 .   iscoloring - coloring generated using colorarray information
7003 
7004     Level: developer
7005 
7006 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7007 
7008 @*/
7009 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7010 {
7011   PetscErrorCode ierr;
7012 
7013   PetscFunctionBegin;
7014   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7015   PetscValidType(mat,1);
7016   PetscValidIntPointer(colorarray,4);
7017   PetscValidPointer(iscoloring,5);
7018   MatCheckPreallocated(mat,1);
7019 
7020   if (!mat->ops->coloringpatch){
7021     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7022   } else {
7023     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7024   }
7025   PetscFunctionReturn(0);
7026 }
7027 
7028 
7029 #undef __FUNCT__
7030 #define __FUNCT__ "MatSetUnfactored"
7031 /*@
7032    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7033 
7034    Logically Collective on Mat
7035 
7036    Input Parameter:
7037 .  mat - the factored matrix to be reset
7038 
7039    Notes:
7040    This routine should be used only with factored matrices formed by in-place
7041    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7042    format).  This option can save memory, for example, when solving nonlinear
7043    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7044    ILU(0) preconditioner.
7045 
7046    Note that one can specify in-place ILU(0) factorization by calling
7047 .vb
7048      PCType(pc,PCILU);
7049      PCFactorSeUseInPlace(pc);
7050 .ve
7051    or by using the options -pc_type ilu -pc_factor_in_place
7052 
7053    In-place factorization ILU(0) can also be used as a local
7054    solver for the blocks within the block Jacobi or additive Schwarz
7055    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7056    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7057    local solver options.
7058 
7059    Most users should employ the simplified KSP interface for linear solvers
7060    instead of working directly with matrix algebra routines such as this.
7061    See, e.g., KSPCreate().
7062 
7063    Level: developer
7064 
7065 .seealso: PCFactorSetUseInPlace()
7066 
7067    Concepts: matrices^unfactored
7068 
7069 @*/
7070 PetscErrorCode  MatSetUnfactored(Mat mat)
7071 {
7072   PetscErrorCode ierr;
7073 
7074   PetscFunctionBegin;
7075   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7076   PetscValidType(mat,1);
7077   MatCheckPreallocated(mat,1);
7078   mat->factortype = MAT_FACTOR_NONE;
7079   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7080   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7081   PetscFunctionReturn(0);
7082 }
7083 
7084 /*MC
7085     MatGetArrayF90 - Accesses a matrix array from Fortran90.
7086 
7087     Synopsis:
7088     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7089 
7090     Not collective
7091 
7092     Input Parameter:
7093 .   x - matrix
7094 
7095     Output Parameters:
7096 +   xx_v - the Fortran90 pointer to the array
7097 -   ierr - error code
7098 
7099     Example of Usage:
7100 .vb
7101       PetscScalar, pointer xx_v(:,:)
7102       ....
7103       call MatGetArrayF90(x,xx_v,ierr)
7104       a = xx_v(3)
7105       call MatRestoreArrayF90(x,xx_v,ierr)
7106 .ve
7107 
7108     Notes:
7109     Not yet supported for all F90 compilers
7110 
7111     Level: advanced
7112 
7113 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
7114 
7115     Concepts: matrices^accessing array
7116 
7117 M*/
7118 
7119 /*MC
7120     MatRestoreArrayF90 - Restores a matrix array that has been
7121     accessed with MatGetArrayF90().
7122 
7123     Synopsis:
7124     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7125 
7126     Not collective
7127 
7128     Input Parameters:
7129 +   x - matrix
7130 -   xx_v - the Fortran90 pointer to the array
7131 
7132     Output Parameter:
7133 .   ierr - error code
7134 
7135     Example of Usage:
7136 .vb
7137        PetscScalar, pointer xx_v(:)
7138        ....
7139        call MatGetArrayF90(x,xx_v,ierr)
7140        a = xx_v(3)
7141        call MatRestoreArrayF90(x,xx_v,ierr)
7142 .ve
7143 
7144     Notes:
7145     Not yet supported for all F90 compilers
7146 
7147     Level: advanced
7148 
7149 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7150 
7151 M*/
7152 
7153 
7154 #undef __FUNCT__
7155 #define __FUNCT__ "MatGetSubMatrix"
7156 /*@
7157     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7158                       as the original matrix.
7159 
7160     Collective on Mat
7161 
7162     Input Parameters:
7163 +   mat - the original matrix
7164 .   isrow - parallel IS containing the rows this processor should obtain
7165 .   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.
7166 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7167 
7168     Output Parameter:
7169 .   newmat - the new submatrix, of the same type as the old
7170 
7171     Level: advanced
7172 
7173     Notes:
7174     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7175 
7176     The rows in isrow will be sorted into the same order as the original matrix on each process.
7177 
7178       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7179    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7180    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7181    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7182    you are finished using it.
7183 
7184     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7185     the input matrix.
7186 
7187     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7188 
7189    Example usage:
7190    Consider the following 8x8 matrix with 34 non-zero values, that is
7191    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7192    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7193    as follows:
7194 
7195 .vb
7196             1  2  0  |  0  3  0  |  0  4
7197     Proc0   0  5  6  |  7  0  0  |  8  0
7198             9  0 10  | 11  0  0  | 12  0
7199     -------------------------------------
7200            13  0 14  | 15 16 17  |  0  0
7201     Proc1   0 18  0  | 19 20 21  |  0  0
7202             0  0  0  | 22 23  0  | 24  0
7203     -------------------------------------
7204     Proc2  25 26 27  |  0  0 28  | 29  0
7205            30  0  0  | 31 32 33  |  0 34
7206 .ve
7207 
7208     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7209 
7210 .vb
7211             2  0  |  0  3  0  |  0
7212     Proc0   5  6  |  7  0  0  |  8
7213     -------------------------------
7214     Proc1  18  0  | 19 20 21  |  0
7215     -------------------------------
7216     Proc2  26 27  |  0  0 28  | 29
7217             0  0  | 31 32 33  |  0
7218 .ve
7219 
7220 
7221     Concepts: matrices^submatrices
7222 
7223 .seealso: MatGetSubMatrices()
7224 @*/
7225 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7226 {
7227   PetscErrorCode ierr;
7228   PetscMPIInt    size;
7229   Mat            *local;
7230   IS             iscoltmp;
7231 
7232   PetscFunctionBegin;
7233   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7234   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7235   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7236   PetscValidPointer(newmat,5);
7237   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7238   PetscValidType(mat,1);
7239   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7240   MatCheckPreallocated(mat,1);
7241   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7242 
7243   if (!iscol) {
7244     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7245   } else {
7246     iscoltmp = iscol;
7247   }
7248 
7249   /* if original matrix is on just one processor then use submatrix generated */
7250   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7251     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7252     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7253     PetscFunctionReturn(0);
7254   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7255     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7256     *newmat = *local;
7257     ierr    = PetscFree(local);CHKERRQ(ierr);
7258     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7259     PetscFunctionReturn(0);
7260   } else if (!mat->ops->getsubmatrix) {
7261     /* Create a new matrix type that implements the operation using the full matrix */
7262     switch (cll) {
7263       case MAT_INITIAL_MATRIX:
7264         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7265         break;
7266       case MAT_REUSE_MATRIX:
7267         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7268         break;
7269       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7270     }
7271     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7272     PetscFunctionReturn(0);
7273   }
7274 
7275   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7276   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7277   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7278   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7279   PetscFunctionReturn(0);
7280 }
7281 
7282 #undef __FUNCT__
7283 #define __FUNCT__ "MatStashSetInitialSize"
7284 /*@
7285    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7286    used during the assembly process to store values that belong to
7287    other processors.
7288 
7289    Not Collective
7290 
7291    Input Parameters:
7292 +  mat   - the matrix
7293 .  size  - the initial size of the stash.
7294 -  bsize - the initial size of the block-stash(if used).
7295 
7296    Options Database Keys:
7297 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7298 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7299 
7300    Level: intermediate
7301 
7302    Notes:
7303      The block-stash is used for values set with MatSetValuesBlocked() while
7304      the stash is used for values set with MatSetValues()
7305 
7306      Run with the option -info and look for output of the form
7307      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7308      to determine the appropriate value, MM, to use for size and
7309      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7310      to determine the value, BMM to use for bsize
7311 
7312    Concepts: stash^setting matrix size
7313    Concepts: matrices^stash
7314 
7315 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7316 
7317 @*/
7318 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7319 {
7320   PetscErrorCode ierr;
7321 
7322   PetscFunctionBegin;
7323   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7324   PetscValidType(mat,1);
7325   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7326   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7327   PetscFunctionReturn(0);
7328 }
7329 
7330 #undef __FUNCT__
7331 #define __FUNCT__ "MatInterpolateAdd"
7332 /*@
7333    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7334      the matrix
7335 
7336    Neighbor-wise Collective on Mat
7337 
7338    Input Parameters:
7339 +  mat   - the matrix
7340 .  x,y - the vectors
7341 -  w - where the result is stored
7342 
7343    Level: intermediate
7344 
7345    Notes:
7346     w may be the same vector as y.
7347 
7348     This allows one to use either the restriction or interpolation (its transpose)
7349     matrix to do the interpolation
7350 
7351     Concepts: interpolation
7352 
7353 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7354 
7355 @*/
7356 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7357 {
7358   PetscErrorCode ierr;
7359   PetscInt       M,N,Ny;
7360 
7361   PetscFunctionBegin;
7362   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7363   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7364   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7365   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7366   PetscValidType(A,1);
7367   MatCheckPreallocated(A,1);
7368   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7369   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7370   if (M == Ny) {
7371     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7372   } else {
7373     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7374   }
7375   PetscFunctionReturn(0);
7376 }
7377 
7378 #undef __FUNCT__
7379 #define __FUNCT__ "MatInterpolate"
7380 /*@
7381    MatInterpolate - y = A*x or A'*x depending on the shape of
7382      the matrix
7383 
7384    Neighbor-wise Collective on Mat
7385 
7386    Input Parameters:
7387 +  mat   - the matrix
7388 -  x,y - the vectors
7389 
7390    Level: intermediate
7391 
7392    Notes:
7393     This allows one to use either the restriction or interpolation (its transpose)
7394     matrix to do the interpolation
7395 
7396    Concepts: matrices^interpolation
7397 
7398 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7399 
7400 @*/
7401 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7402 {
7403   PetscErrorCode ierr;
7404   PetscInt       M,N,Ny;
7405 
7406   PetscFunctionBegin;
7407   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7408   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7409   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7410   PetscValidType(A,1);
7411   MatCheckPreallocated(A,1);
7412   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7413   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7414   if (M == Ny) {
7415     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7416   } else {
7417     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7418   }
7419   PetscFunctionReturn(0);
7420 }
7421 
7422 #undef __FUNCT__
7423 #define __FUNCT__ "MatRestrict"
7424 /*@
7425    MatRestrict - y = A*x or A'*x
7426 
7427    Neighbor-wise Collective on Mat
7428 
7429    Input Parameters:
7430 +  mat   - the matrix
7431 -  x,y - the vectors
7432 
7433    Level: intermediate
7434 
7435    Notes:
7436     This allows one to use either the restriction or interpolation (its transpose)
7437     matrix to do the restriction
7438 
7439    Concepts: matrices^restriction
7440 
7441 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7442 
7443 @*/
7444 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7445 {
7446   PetscErrorCode ierr;
7447   PetscInt       M,N,Ny;
7448 
7449   PetscFunctionBegin;
7450   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7451   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7452   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7453   PetscValidType(A,1);
7454   MatCheckPreallocated(A,1);
7455 
7456   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7457   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7458   if (M == Ny) {
7459     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7460   } else {
7461     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7462   }
7463   PetscFunctionReturn(0);
7464 }
7465 
7466 #undef __FUNCT__
7467 #define __FUNCT__ "MatGetNullSpace"
7468 /*@
7469    MatGetNullSpace - retrieves the null space to a matrix.
7470 
7471    Logically Collective on Mat and MatNullSpace
7472 
7473    Input Parameters:
7474 +  mat - the matrix
7475 -  nullsp - the null space object
7476 
7477    Level: developer
7478 
7479    Notes:
7480       This null space is used by solvers. Overwrites any previous null space that may have been attached
7481 
7482    Concepts: null space^attaching to matrix
7483 
7484 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7485 @*/
7486 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7487 {
7488   PetscFunctionBegin;
7489   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7490   PetscValidType(mat,1);
7491   PetscValidPointer(nullsp,2);
7492   *nullsp = mat->nullsp;
7493   PetscFunctionReturn(0);
7494 }
7495 
7496 #undef __FUNCT__
7497 #define __FUNCT__ "MatSetNullSpace"
7498 /*@
7499    MatSetNullSpace - attaches a null space to a matrix.
7500         This null space will be removed from the resulting vector whenever
7501         MatMult() is called
7502 
7503    Logically Collective on Mat and MatNullSpace
7504 
7505    Input Parameters:
7506 +  mat - the matrix
7507 -  nullsp - the null space object
7508 
7509    Level: advanced
7510 
7511    Notes:
7512       This null space is used by solvers. Overwrites any previous null space that may have been attached
7513 
7514    Concepts: null space^attaching to matrix
7515 
7516 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7517 @*/
7518 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7519 {
7520   PetscErrorCode ierr;
7521 
7522   PetscFunctionBegin;
7523   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7524   PetscValidType(mat,1);
7525   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7526   MatCheckPreallocated(mat,1);
7527   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7528   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
7529   mat->nullsp = nullsp;
7530   PetscFunctionReturn(0);
7531 }
7532 
7533 #undef __FUNCT__
7534 #define __FUNCT__ "MatSetNearNullSpace"
7535 /*@
7536    MatSetNearNullSpace - attaches a null space to a matrix.
7537         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7538 
7539    Logically Collective on Mat and MatNullSpace
7540 
7541    Input Parameters:
7542 +  mat - the matrix
7543 -  nullsp - the null space object
7544 
7545    Level: advanced
7546 
7547    Notes:
7548       Overwrites any previous near null space that may have been attached
7549 
7550    Concepts: null space^attaching to matrix
7551 
7552 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7553 @*/
7554 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7555 {
7556   PetscErrorCode ierr;
7557 
7558   PetscFunctionBegin;
7559   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7560   PetscValidType(mat,1);
7561   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7562   MatCheckPreallocated(mat,1);
7563   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7564   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
7565   mat->nearnullsp = nullsp;
7566   PetscFunctionReturn(0);
7567 }
7568 
7569 #undef __FUNCT__
7570 #define __FUNCT__ "MatGetNearNullSpace"
7571 /*@
7572    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7573 
7574    Not Collective
7575 
7576    Input Parameters:
7577 .  mat - the matrix
7578 
7579    Output Parameters:
7580 .  nullsp - the null space object, PETSC_NULL if not set
7581 
7582    Level: developer
7583 
7584    Concepts: null space^attaching to matrix
7585 
7586 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7587 @*/
7588 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7589 {
7590 
7591   PetscFunctionBegin;
7592   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7593   PetscValidType(mat,1);
7594   PetscValidPointer(nullsp,2);
7595   MatCheckPreallocated(mat,1);
7596   *nullsp = mat->nearnullsp;
7597   PetscFunctionReturn(0);
7598 }
7599 
7600 #undef __FUNCT__
7601 #define __FUNCT__ "MatICCFactor"
7602 /*@C
7603    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7604 
7605    Collective on Mat
7606 
7607    Input Parameters:
7608 +  mat - the matrix
7609 .  row - row/column permutation
7610 .  fill - expected fill factor >= 1.0
7611 -  level - level of fill, for ICC(k)
7612 
7613    Notes:
7614    Probably really in-place only when level of fill is zero, otherwise allocates
7615    new space to store factored matrix and deletes previous memory.
7616 
7617    Most users should employ the simplified KSP interface for linear solvers
7618    instead of working directly with matrix algebra routines such as this.
7619    See, e.g., KSPCreate().
7620 
7621    Level: developer
7622 
7623    Concepts: matrices^incomplete Cholesky factorization
7624    Concepts: Cholesky factorization
7625 
7626 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7627 
7628     Developer Note: fortran interface is not autogenerated as the f90
7629     interface defintion cannot be generated correctly [due to MatFactorInfo]
7630 
7631 @*/
7632 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7633 {
7634   PetscErrorCode ierr;
7635 
7636   PetscFunctionBegin;
7637   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7638   PetscValidType(mat,1);
7639   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7640   PetscValidPointer(info,3);
7641   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7642   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7643   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7644   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7645   MatCheckPreallocated(mat,1);
7646   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7647   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7648   PetscFunctionReturn(0);
7649 }
7650 
7651 #undef __FUNCT__
7652 #define __FUNCT__ "MatSetValuesAdic"
7653 /*@
7654    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7655 
7656    Not Collective
7657 
7658    Input Parameters:
7659 +  mat - the matrix
7660 -  v - the values compute with ADIC
7661 
7662    Level: developer
7663 
7664    Notes:
7665      Must call MatSetColoring() before using this routine. Also this matrix must already
7666      have its nonzero pattern determined.
7667 
7668 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7669           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7670 @*/
7671 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7672 {
7673   PetscErrorCode ierr;
7674 
7675   PetscFunctionBegin;
7676   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7677   PetscValidType(mat,1);
7678   PetscValidPointer(mat,2);
7679 
7680   if (!mat->assembled) {
7681     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7682   }
7683   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7684   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7685   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7686   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7687   ierr = MatView_Private(mat);CHKERRQ(ierr);
7688   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7689   PetscFunctionReturn(0);
7690 }
7691 
7692 
7693 #undef __FUNCT__
7694 #define __FUNCT__ "MatSetColoring"
7695 /*@
7696    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7697 
7698    Not Collective
7699 
7700    Input Parameters:
7701 +  mat - the matrix
7702 -  coloring - the coloring
7703 
7704    Level: developer
7705 
7706 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7707           MatSetValues(), MatSetValuesAdic()
7708 @*/
7709 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7710 {
7711   PetscErrorCode ierr;
7712 
7713   PetscFunctionBegin;
7714   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7715   PetscValidType(mat,1);
7716   PetscValidPointer(coloring,2);
7717 
7718   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7719   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7720   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7721   PetscFunctionReturn(0);
7722 }
7723 
7724 #undef __FUNCT__
7725 #define __FUNCT__ "MatSetValuesAdifor"
7726 /*@
7727    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7728 
7729    Not Collective
7730 
7731    Input Parameters:
7732 +  mat - the matrix
7733 .  nl - leading dimension of v
7734 -  v - the values compute with ADIFOR
7735 
7736    Level: developer
7737 
7738    Notes:
7739      Must call MatSetColoring() before using this routine. Also this matrix must already
7740      have its nonzero pattern determined.
7741 
7742 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7743           MatSetValues(), MatSetColoring()
7744 @*/
7745 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7746 {
7747   PetscErrorCode ierr;
7748 
7749   PetscFunctionBegin;
7750   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7751   PetscValidType(mat,1);
7752   PetscValidPointer(v,3);
7753 
7754   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7755   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7756   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7757   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7758   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7759   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7760   PetscFunctionReturn(0);
7761 }
7762 
7763 #undef __FUNCT__
7764 #define __FUNCT__ "MatDiagonalScaleLocal"
7765 /*@
7766    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7767          ghosted ones.
7768 
7769    Not Collective
7770 
7771    Input Parameters:
7772 +  mat - the matrix
7773 -  diag = the diagonal values, including ghost ones
7774 
7775    Level: developer
7776 
7777    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7778 
7779 .seealso: MatDiagonalScale()
7780 @*/
7781 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7782 {
7783   PetscErrorCode ierr;
7784   PetscMPIInt    size;
7785 
7786   PetscFunctionBegin;
7787   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7788   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7789   PetscValidType(mat,1);
7790 
7791   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7792   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7793   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7794   if (size == 1) {
7795     PetscInt n,m;
7796     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7797     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7798     if (m == n) {
7799       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7800     } else {
7801       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7802     }
7803   } else {
7804     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7805   }
7806   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7807   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7808   PetscFunctionReturn(0);
7809 }
7810 
7811 #undef __FUNCT__
7812 #define __FUNCT__ "MatGetInertia"
7813 /*@
7814    MatGetInertia - Gets the inertia from a factored matrix
7815 
7816    Collective on Mat
7817 
7818    Input Parameter:
7819 .  mat - the matrix
7820 
7821    Output Parameters:
7822 +   nneg - number of negative eigenvalues
7823 .   nzero - number of zero eigenvalues
7824 -   npos - number of positive eigenvalues
7825 
7826    Level: advanced
7827 
7828    Notes: Matrix must have been factored by MatCholeskyFactor()
7829 
7830 
7831 @*/
7832 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7833 {
7834   PetscErrorCode ierr;
7835 
7836   PetscFunctionBegin;
7837   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7838   PetscValidType(mat,1);
7839   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7840   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7841   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7842   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7843   PetscFunctionReturn(0);
7844 }
7845 
7846 /* ----------------------------------------------------------------*/
7847 #undef __FUNCT__
7848 #define __FUNCT__ "MatSolves"
7849 /*@C
7850    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7851 
7852    Neighbor-wise Collective on Mat and Vecs
7853 
7854    Input Parameters:
7855 +  mat - the factored matrix
7856 -  b - the right-hand-side vectors
7857 
7858    Output Parameter:
7859 .  x - the result vectors
7860 
7861    Notes:
7862    The vectors b and x cannot be the same.  I.e., one cannot
7863    call MatSolves(A,x,x).
7864 
7865    Notes:
7866    Most users should employ the simplified KSP interface for linear solvers
7867    instead of working directly with matrix algebra routines such as this.
7868    See, e.g., KSPCreate().
7869 
7870    Level: developer
7871 
7872    Concepts: matrices^triangular solves
7873 
7874 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7875 @*/
7876 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7877 {
7878   PetscErrorCode ierr;
7879 
7880   PetscFunctionBegin;
7881   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7882   PetscValidType(mat,1);
7883   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7884   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7885   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7886 
7887   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7888   MatCheckPreallocated(mat,1);
7889   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7890   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7891   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7892   PetscFunctionReturn(0);
7893 }
7894 
7895 #undef __FUNCT__
7896 #define __FUNCT__ "MatIsSymmetric"
7897 /*@
7898    MatIsSymmetric - Test whether a matrix is symmetric
7899 
7900    Collective on Mat
7901 
7902    Input Parameter:
7903 +  A - the matrix to test
7904 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7905 
7906    Output Parameters:
7907 .  flg - the result
7908 
7909    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7910 
7911    Level: intermediate
7912 
7913    Concepts: matrix^symmetry
7914 
7915 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7916 @*/
7917 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7918 {
7919   PetscErrorCode ierr;
7920 
7921   PetscFunctionBegin;
7922   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7923   PetscValidPointer(flg,2);
7924 
7925   if (!A->symmetric_set) {
7926     if (!A->ops->issymmetric) {
7927       const MatType mattype;
7928       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7929       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7930     }
7931     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7932     if (!tol) {
7933       A->symmetric_set = PETSC_TRUE;
7934       A->symmetric = *flg;
7935       if (A->symmetric) {
7936 	A->structurally_symmetric_set = PETSC_TRUE;
7937 	A->structurally_symmetric     = PETSC_TRUE;
7938       }
7939     }
7940   } else if (A->symmetric) {
7941     *flg = PETSC_TRUE;
7942   } else if (!tol) {
7943     *flg = PETSC_FALSE;
7944   } else {
7945     if (!A->ops->issymmetric) {
7946       const MatType mattype;
7947       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7948       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7949     }
7950     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7951   }
7952   PetscFunctionReturn(0);
7953 }
7954 
7955 #undef __FUNCT__
7956 #define __FUNCT__ "MatIsHermitian"
7957 /*@
7958    MatIsHermitian - Test whether a matrix is Hermitian
7959 
7960    Collective on Mat
7961 
7962    Input Parameter:
7963 +  A - the matrix to test
7964 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7965 
7966    Output Parameters:
7967 .  flg - the result
7968 
7969    Level: intermediate
7970 
7971    Concepts: matrix^symmetry
7972 
7973 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7974           MatIsSymmetricKnown(), MatIsSymmetric()
7975 @*/
7976 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7977 {
7978   PetscErrorCode ierr;
7979 
7980   PetscFunctionBegin;
7981   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7982   PetscValidPointer(flg,2);
7983 
7984   if (!A->hermitian_set) {
7985     if (!A->ops->ishermitian) {
7986       const MatType mattype;
7987       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7988       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7989     }
7990     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7991     if (!tol) {
7992       A->hermitian_set = PETSC_TRUE;
7993       A->hermitian = *flg;
7994       if (A->hermitian) {
7995 	A->structurally_symmetric_set = PETSC_TRUE;
7996 	A->structurally_symmetric     = PETSC_TRUE;
7997       }
7998     }
7999   } else if (A->hermitian) {
8000     *flg = PETSC_TRUE;
8001   } else if (!tol) {
8002     *flg = PETSC_FALSE;
8003   } else {
8004     if (!A->ops->ishermitian) {
8005       const MatType mattype;
8006       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8007       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8008     }
8009     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8010   }
8011   PetscFunctionReturn(0);
8012 }
8013 
8014 #undef __FUNCT__
8015 #define __FUNCT__ "MatIsSymmetricKnown"
8016 /*@
8017    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8018 
8019    Not Collective
8020 
8021    Input Parameter:
8022 .  A - the matrix to check
8023 
8024    Output Parameters:
8025 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8026 -  flg - the result
8027 
8028    Level: advanced
8029 
8030    Concepts: matrix^symmetry
8031 
8032    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8033          if you want it explicitly checked
8034 
8035 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8036 @*/
8037 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8038 {
8039   PetscFunctionBegin;
8040   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8041   PetscValidPointer(set,2);
8042   PetscValidPointer(flg,3);
8043   if (A->symmetric_set) {
8044     *set = PETSC_TRUE;
8045     *flg = A->symmetric;
8046   } else {
8047     *set = PETSC_FALSE;
8048   }
8049   PetscFunctionReturn(0);
8050 }
8051 
8052 #undef __FUNCT__
8053 #define __FUNCT__ "MatIsHermitianKnown"
8054 /*@
8055    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8056 
8057    Not Collective
8058 
8059    Input Parameter:
8060 .  A - the matrix to check
8061 
8062    Output Parameters:
8063 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8064 -  flg - the result
8065 
8066    Level: advanced
8067 
8068    Concepts: matrix^symmetry
8069 
8070    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8071          if you want it explicitly checked
8072 
8073 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8074 @*/
8075 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8076 {
8077   PetscFunctionBegin;
8078   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8079   PetscValidPointer(set,2);
8080   PetscValidPointer(flg,3);
8081   if (A->hermitian_set) {
8082     *set = PETSC_TRUE;
8083     *flg = A->hermitian;
8084   } else {
8085     *set = PETSC_FALSE;
8086   }
8087   PetscFunctionReturn(0);
8088 }
8089 
8090 #undef __FUNCT__
8091 #define __FUNCT__ "MatIsStructurallySymmetric"
8092 /*@
8093    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8094 
8095    Collective on Mat
8096 
8097    Input Parameter:
8098 .  A - the matrix to test
8099 
8100    Output Parameters:
8101 .  flg - the result
8102 
8103    Level: intermediate
8104 
8105    Concepts: matrix^symmetry
8106 
8107 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8108 @*/
8109 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8110 {
8111   PetscErrorCode ierr;
8112 
8113   PetscFunctionBegin;
8114   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8115   PetscValidPointer(flg,2);
8116   if (!A->structurally_symmetric_set) {
8117     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8118     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8119     A->structurally_symmetric_set = PETSC_TRUE;
8120   }
8121   *flg = A->structurally_symmetric;
8122   PetscFunctionReturn(0);
8123 }
8124 
8125 #undef __FUNCT__
8126 #define __FUNCT__ "MatStashGetInfo"
8127 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8128 /*@
8129    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8130        to be communicated to other processors during the MatAssemblyBegin/End() process
8131 
8132     Not collective
8133 
8134    Input Parameter:
8135 .   vec - the vector
8136 
8137    Output Parameters:
8138 +   nstash   - the size of the stash
8139 .   reallocs - the number of additional mallocs incurred.
8140 .   bnstash   - the size of the block stash
8141 -   breallocs - the number of additional mallocs incurred.in the block stash
8142 
8143    Level: advanced
8144 
8145 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8146 
8147 @*/
8148 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8149 {
8150   PetscErrorCode ierr;
8151   PetscFunctionBegin;
8152   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8153   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8154   PetscFunctionReturn(0);
8155 }
8156 
8157 #undef __FUNCT__
8158 #define __FUNCT__ "MatGetVecs"
8159 /*@C
8160    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8161      parallel layout
8162 
8163    Collective on Mat
8164 
8165    Input Parameter:
8166 .  mat - the matrix
8167 
8168    Output Parameter:
8169 +   right - (optional) vector that the matrix can be multiplied against
8170 -   left - (optional) vector that the matrix vector product can be stored in
8171 
8172   Level: advanced
8173 
8174 .seealso: MatCreate()
8175 @*/
8176 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8177 {
8178   PetscErrorCode ierr;
8179 
8180   PetscFunctionBegin;
8181   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8182   PetscValidType(mat,1);
8183   MatCheckPreallocated(mat,1);
8184   if (mat->ops->getvecs) {
8185     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8186   } else {
8187     PetscMPIInt size;
8188     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
8189     if (right) {
8190       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
8191       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8192       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
8193       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8194       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8195     }
8196     if (left) {
8197       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
8198       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8199       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
8200       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8201       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8202     }
8203   }
8204   PetscFunctionReturn(0);
8205 }
8206 
8207 #undef __FUNCT__
8208 #define __FUNCT__ "MatFactorInfoInitialize"
8209 /*@C
8210    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8211      with default values.
8212 
8213    Not Collective
8214 
8215    Input Parameters:
8216 .    info - the MatFactorInfo data structure
8217 
8218 
8219    Notes: The solvers are generally used through the KSP and PC objects, for example
8220           PCLU, PCILU, PCCHOLESKY, PCICC
8221 
8222    Level: developer
8223 
8224 .seealso: MatFactorInfo
8225 
8226     Developer Note: fortran interface is not autogenerated as the f90
8227     interface defintion cannot be generated correctly [due to MatFactorInfo]
8228 
8229 @*/
8230 
8231 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8232 {
8233   PetscErrorCode ierr;
8234 
8235   PetscFunctionBegin;
8236   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8237   PetscFunctionReturn(0);
8238 }
8239 
8240 #undef __FUNCT__
8241 #define __FUNCT__ "MatPtAP"
8242 /*@
8243    MatPtAP - Creates the matrix product C = P^T * A * P
8244 
8245    Neighbor-wise Collective on Mat
8246 
8247    Input Parameters:
8248 +  A - the matrix
8249 .  P - the projection matrix
8250 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8251 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8252 
8253    Output Parameters:
8254 .  C - the product matrix
8255 
8256    Notes:
8257    C will be created and must be destroyed by the user with MatDestroy().
8258 
8259    This routine is currently only implemented for pairs of AIJ matrices and classes
8260    which inherit from AIJ.
8261 
8262    Level: intermediate
8263 
8264 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8265 @*/
8266 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8267 {
8268   PetscErrorCode ierr;
8269 
8270   PetscFunctionBegin;
8271   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8272   PetscValidType(A,1);
8273   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8274   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8275   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8276   PetscValidType(P,2);
8277   MatCheckPreallocated(P,2);
8278   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8279   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8280   PetscValidPointer(C,3);
8281   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);
8282   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8283   MatCheckPreallocated(A,1);
8284 
8285   if (!A->ops->ptap) {
8286     const MatType mattype;
8287     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8288     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8289   }
8290   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8291   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8292   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8293   PetscFunctionReturn(0);
8294 }
8295 
8296 #undef __FUNCT__
8297 #define __FUNCT__ "MatPtAPNumeric"
8298 /*@
8299    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8300 
8301    Neighbor-wise Collective on Mat
8302 
8303    Input Parameters:
8304 +  A - the matrix
8305 -  P - the projection matrix
8306 
8307    Output Parameters:
8308 .  C - the product matrix
8309 
8310    Notes:
8311    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8312    the user using MatDeatroy().
8313 
8314    This routine is currently only implemented for pairs of AIJ matrices and classes
8315    which inherit from AIJ.  C will be of type MATAIJ.
8316 
8317    Level: intermediate
8318 
8319 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8320 @*/
8321 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8322 {
8323   PetscErrorCode ierr;
8324 
8325   PetscFunctionBegin;
8326   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8327   PetscValidType(A,1);
8328   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8329   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8330   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8331   PetscValidType(P,2);
8332   MatCheckPreallocated(P,2);
8333   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8334   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8335   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8336   PetscValidType(C,3);
8337   MatCheckPreallocated(C,3);
8338   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8339   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);
8340   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8341   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8342   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);
8343   MatCheckPreallocated(A,1);
8344 
8345   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8346   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8347   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8348   PetscFunctionReturn(0);
8349 }
8350 
8351 #undef __FUNCT__
8352 #define __FUNCT__ "MatPtAPSymbolic"
8353 /*@
8354    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8355 
8356    Neighbor-wise Collective on Mat
8357 
8358    Input Parameters:
8359 +  A - the matrix
8360 -  P - the projection matrix
8361 
8362    Output Parameters:
8363 .  C - the (i,j) structure of the product matrix
8364 
8365    Notes:
8366    C will be created and must be destroyed by the user with MatDestroy().
8367 
8368    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8369    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8370    this (i,j) structure by calling MatPtAPNumeric().
8371 
8372    Level: intermediate
8373 
8374 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8375 @*/
8376 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8377 {
8378   PetscErrorCode ierr;
8379 
8380   PetscFunctionBegin;
8381   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8382   PetscValidType(A,1);
8383   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8384   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8385   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8386   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8387   PetscValidType(P,2);
8388   MatCheckPreallocated(P,2);
8389   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8390   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8391   PetscValidPointer(C,3);
8392 
8393   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);
8394   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);
8395   MatCheckPreallocated(A,1);
8396   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8397   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8398   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8399 
8400   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
8401 
8402   PetscFunctionReturn(0);
8403 }
8404 
8405 #undef __FUNCT__
8406 #define __FUNCT__ "MatRARt"
8407 /*@
8408    MatRARt - Creates the matrix product C = R * A * R^T
8409 
8410    Neighbor-wise Collective on Mat
8411 
8412    Input Parameters:
8413 +  A - the matrix
8414 .  R - the projection matrix
8415 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8416 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8417 
8418    Output Parameters:
8419 .  C - the product matrix
8420 
8421    Notes:
8422    C will be created and must be destroyed by the user with MatDestroy().
8423 
8424    This routine is currently only implemented for pairs of AIJ matrices and classes
8425    which inherit from AIJ.
8426 
8427    Level: intermediate
8428 
8429 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8430 @*/
8431 PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8432 {
8433   PetscErrorCode ierr;
8434 
8435   PetscFunctionBegin;
8436   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8437   PetscValidType(A,1);
8438   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8439   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8440   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8441   PetscValidType(R,2);
8442   MatCheckPreallocated(R,2);
8443   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8444   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8445   PetscValidPointer(C,3);
8446   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);
8447   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8448   MatCheckPreallocated(A,1);
8449 
8450   if (!A->ops->rart) {
8451     const MatType mattype;
8452     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8453     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8454   }
8455   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8456   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
8457   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8458   PetscFunctionReturn(0);
8459 }
8460 
8461 #undef __FUNCT__
8462 #define __FUNCT__ "MatRARtNumeric"
8463 /*@
8464    MatRARtNumeric - Computes the matrix product C = R * A * R^T
8465 
8466    Neighbor-wise Collective on Mat
8467 
8468    Input Parameters:
8469 +  A - the matrix
8470 -  R - the projection matrix
8471 
8472    Output Parameters:
8473 .  C - the product matrix
8474 
8475    Notes:
8476    C must have been created by calling MatRARtSymbolic and must be destroyed by
8477    the user using MatDeatroy().
8478 
8479    This routine is currently only implemented for pairs of AIJ matrices and classes
8480    which inherit from AIJ.  C will be of type MATAIJ.
8481 
8482    Level: intermediate
8483 
8484 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8485 @*/
8486 PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8487 {
8488   PetscErrorCode ierr;
8489 
8490   PetscFunctionBegin;
8491   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8492   PetscValidType(A,1);
8493   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8494   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8495   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8496   PetscValidType(R,2);
8497   MatCheckPreallocated(R,2);
8498   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8499   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8500   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8501   PetscValidType(C,3);
8502   MatCheckPreallocated(C,3);
8503   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8504   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);
8505   if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8506   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8507   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);
8508   MatCheckPreallocated(A,1);
8509 
8510   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8511   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
8512   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8513   PetscFunctionReturn(0);
8514 }
8515 
8516 #undef __FUNCT__
8517 #define __FUNCT__ "MatRARtSymbolic"
8518 /*@
8519    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8520 
8521    Neighbor-wise Collective on Mat
8522 
8523    Input Parameters:
8524 +  A - the matrix
8525 -  R - the projection matrix
8526 
8527    Output Parameters:
8528 .  C - the (i,j) structure of the product matrix
8529 
8530    Notes:
8531    C will be created and must be destroyed by the user with MatDestroy().
8532 
8533    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8534    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8535    this (i,j) structure by calling MatRARtNumeric().
8536 
8537    Level: intermediate
8538 
8539 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8540 @*/
8541 PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8542 {
8543   PetscErrorCode ierr;
8544 
8545   PetscFunctionBegin;
8546   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8547   PetscValidType(A,1);
8548   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8549   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8550   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8551   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8552   PetscValidType(R,2);
8553   MatCheckPreallocated(R,2);
8554   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8555   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8556   PetscValidPointer(C,3);
8557 
8558   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);
8559   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);
8560   MatCheckPreallocated(A,1);
8561   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8562   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
8563   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8564 
8565   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8566   PetscFunctionReturn(0);
8567 }
8568 
8569 extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);
8570 
8571 #undef __FUNCT__
8572 #define __FUNCT__ "MatMatMult"
8573 /*@
8574    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8575 
8576    Neighbor-wise Collective on Mat
8577 
8578    Input Parameters:
8579 +  A - the left matrix
8580 .  B - the right matrix
8581 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8582 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8583           if the result is a dense matrix this is irrelevent
8584 
8585    Output Parameters:
8586 .  C - the product matrix
8587 
8588    Notes:
8589    Unless scall is MAT_REUSE_MATRIX C will be created.
8590 
8591    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8592 
8593    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8594    actually needed.
8595 
8596    If you have many matrices with the same non-zero structure to multiply, you
8597    should either
8598 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8599 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8600 
8601    Level: intermediate
8602 
8603 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8604 @*/
8605 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8606 {
8607   PetscErrorCode ierr;
8608   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8609   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8610   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8611 
8612   PetscFunctionBegin;
8613   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8614   PetscValidType(A,1);
8615   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8616   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8617   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8618   PetscValidType(B,2);
8619   MatCheckPreallocated(B,2);
8620   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8621   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8622   PetscValidPointer(C,3);
8623   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);
8624   if (scall == MAT_REUSE_MATRIX){
8625     PetscValidPointer(*C,5);
8626     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8627     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8628     ierr = (*(*C)->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8629     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8630   }
8631   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8632   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8633   MatCheckPreallocated(A,1);
8634 
8635   fA = A->ops->matmult;
8636   fB = B->ops->matmult;
8637   if (fB == fA) {
8638     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8639     mult = fB;
8640   } else {
8641     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8642     char  multname[256];
8643     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8644     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8645     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8646     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8647     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8648     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8649     if(!mult){
8650       /* dual dispatch using MatQueryOp */
8651       ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8652       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);
8653     }
8654   }
8655   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8656   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8657   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8658   PetscFunctionReturn(0);
8659 }
8660 
8661 #undef __FUNCT__
8662 #define __FUNCT__ "MatMatMultSymbolic"
8663 /*@
8664    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8665    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8666 
8667    Neighbor-wise Collective on Mat
8668 
8669    Input Parameters:
8670 +  A - the left matrix
8671 .  B - the right matrix
8672 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8673       if C is a dense matrix this is irrelevent
8674 
8675    Output Parameters:
8676 .  C - the product matrix
8677 
8678    Notes:
8679    Unless scall is MAT_REUSE_MATRIX C will be created.
8680 
8681    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8682    actually needed.
8683 
8684    This routine is currently implemented for
8685     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8686     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8687     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8688 
8689    Level: intermediate
8690 
8691    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8692      We should incorporate them into PETSc.
8693 
8694 .seealso: MatMatMult(), MatMatMultNumeric()
8695 @*/
8696 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8697 {
8698   PetscErrorCode ierr;
8699   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8700   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8701   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8702 
8703   PetscFunctionBegin;
8704   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8705   PetscValidType(A,1);
8706   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8707   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8708 
8709   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8710   PetscValidType(B,2);
8711   MatCheckPreallocated(B,2);
8712   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8713   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8714   PetscValidPointer(C,3);
8715 
8716   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);
8717   if (fill == PETSC_DEFAULT) fill = 2.0;
8718   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8719   MatCheckPreallocated(A,1);
8720 
8721   Asymbolic = A->ops->matmultsymbolic;
8722   Bsymbolic = B->ops->matmultsymbolic;
8723   if (Asymbolic == Bsymbolic){
8724     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8725     symbolic = Bsymbolic;
8726   } else { /* dispatch based on the type of A and B */
8727     char  symbolicname[256];
8728     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8729     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8730     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8731     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8732     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8733     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8734     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);
8735   }
8736   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8737   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8738   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8739   PetscFunctionReturn(0);
8740 }
8741 
8742 #undef __FUNCT__
8743 #define __FUNCT__ "MatMatMultNumeric"
8744 /*@
8745    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8746    Call this routine after first calling MatMatMultSymbolic().
8747 
8748    Neighbor-wise Collective on Mat
8749 
8750    Input Parameters:
8751 +  A - the left matrix
8752 -  B - the right matrix
8753 
8754    Output Parameters:
8755 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8756 
8757    Notes:
8758    C must have been created with MatMatMultSymbolic().
8759 
8760    This routine is currently implemented for
8761     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8762     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8763     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8764 
8765    Level: intermediate
8766 
8767 .seealso: MatMatMult(), MatMatMultSymbolic()
8768 @*/
8769 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8770 {
8771   PetscErrorCode ierr;
8772   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8773   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8774   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8775 
8776   PetscFunctionBegin;
8777   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8778   PetscValidType(A,1);
8779   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8780   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8781 
8782   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8783   PetscValidType(B,2);
8784   MatCheckPreallocated(B,2);
8785   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8786   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8787 
8788   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8789   PetscValidType(C,3);
8790   MatCheckPreallocated(C,3);
8791   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8792   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8793 
8794   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);
8795   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);
8796   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);
8797   MatCheckPreallocated(A,1);
8798 
8799   Anumeric = A->ops->matmultnumeric;
8800   Bnumeric = B->ops->matmultnumeric;
8801   if (Anumeric == Bnumeric){
8802     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8803     numeric = Bnumeric;
8804   } else {
8805     char  numericname[256];
8806     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8807     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8808     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8809     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8810     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8811     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8812     if (!numeric)
8813       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);
8814   }
8815   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8816   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8817   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8818   PetscFunctionReturn(0);
8819 }
8820 
8821 #undef __FUNCT__
8822 #define __FUNCT__ "MatMatTransposeMult"
8823 /*@
8824    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8825 
8826    Neighbor-wise Collective on Mat
8827 
8828    Input Parameters:
8829 +  A - the left matrix
8830 .  B - the right matrix
8831 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8832 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8833 
8834    Output Parameters:
8835 .  C - the product matrix
8836 
8837    Notes:
8838    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8839 
8840    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8841 
8842   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8843    actually needed.
8844 
8845    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
8846 
8847    Level: intermediate
8848 
8849 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8850 @*/
8851 PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8852 {
8853   PetscErrorCode ierr;
8854   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8855   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8856 
8857   PetscFunctionBegin;
8858   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8859   PetscValidType(A,1);
8860   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8861   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8862   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8863   PetscValidType(B,2);
8864   MatCheckPreallocated(B,2);
8865   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8866   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8867   PetscValidPointer(C,3);
8868   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);
8869   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8870   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8871   MatCheckPreallocated(A,1);
8872 
8873   fA = A->ops->mattransposemult;
8874   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8875   fB = B->ops->mattransposemult;
8876   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8877   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);
8878 
8879   if (scall == MAT_INITIAL_MATRIX){
8880     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8881     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
8882     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8883   }
8884   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8885   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
8886   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8887   PetscFunctionReturn(0);
8888 }
8889 
8890 #undef __FUNCT__
8891 #define __FUNCT__ "MatTransposeMatMult"
8892 /*@
8893    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8894 
8895    Neighbor-wise Collective on Mat
8896 
8897    Input Parameters:
8898 +  A - the left matrix
8899 .  B - the right matrix
8900 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8901 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8902 
8903    Output Parameters:
8904 .  C - the product matrix
8905 
8906    Notes:
8907    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8908 
8909    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8910 
8911   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8912    actually needed.
8913 
8914    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8915    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8916 
8917    Level: intermediate
8918 
8919 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8920 @*/
8921 PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8922 {
8923   PetscErrorCode ierr;
8924   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8925   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8926   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
8927 
8928   PetscFunctionBegin;
8929   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8930   PetscValidType(A,1);
8931   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8932   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8933   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8934   PetscValidType(B,2);
8935   MatCheckPreallocated(B,2);
8936   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8937   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8938   PetscValidPointer(C,3);
8939   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);
8940   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8941   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8942   MatCheckPreallocated(A,1);
8943 
8944   fA = A->ops->transposematmult;
8945   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8946   fB = B->ops->transposematmult;
8947   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8948   if (fB==fA) {
8949     transposematmult = fA;
8950   }
8951   else {
8952     /* dual dispatch using MatQueryOp */
8953     ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8954     if(!transposematmult)
8955       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);
8956   }
8957   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8958   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8959   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8960   PetscFunctionReturn(0);
8961 }
8962 
8963 #undef __FUNCT__
8964 #define __FUNCT__ "MatGetRedundantMatrix"
8965 /*@C
8966    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8967 
8968    Collective on Mat
8969 
8970    Input Parameters:
8971 +  mat - the matrix
8972 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8973 .  subcomm - MPI communicator split from the communicator where mat resides in
8974 .  mlocal_red - number of local rows of the redundant matrix
8975 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8976 
8977    Output Parameter:
8978 .  matredundant - redundant matrix
8979 
8980    Notes:
8981    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8982    original matrix has not changed from that last call to MatGetRedundantMatrix().
8983 
8984    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8985    calling it.
8986 
8987    Only MPIAIJ matrix is supported.
8988 
8989    Level: advanced
8990 
8991    Concepts: subcommunicator
8992    Concepts: duplicate matrix
8993 
8994 .seealso: MatDestroy()
8995 @*/
8996 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8997 {
8998   PetscErrorCode ierr;
8999 
9000   PetscFunctionBegin;
9001   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9002   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9003     PetscValidPointer(*matredundant,6);
9004     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
9005   }
9006   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9007   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9008   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9009   MatCheckPreallocated(mat,1);
9010 
9011   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9012   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
9013   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9014   PetscFunctionReturn(0);
9015 }
9016 
9017 #undef __FUNCT__
9018 #define __FUNCT__ "MatGetMultiProcBlock"
9019 /*@C
9020    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9021    a given 'mat' object. Each submatrix can span multiple procs.
9022 
9023    Collective on Mat
9024 
9025    Input Parameters:
9026 +  mat - the matrix
9027 .  subcomm - the subcommunicator obtained by com_split(comm)
9028 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9029 
9030    Output Parameter:
9031 .  subMat - 'parallel submatrices each spans a given subcomm
9032 
9033   Notes:
9034   The submatrix partition across processors is dicated by 'subComm' a
9035   communicator obtained by com_split(comm). The comm_split
9036   is not restriced to be grouped with consequitive original ranks.
9037 
9038   Due the comm_split() usage, the parallel layout of the submatrices
9039   map directly to the layout of the original matrix [wrt the local
9040   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9041   into the 'DiagonalMat' of the subMat, hence it is used directly from
9042   the subMat. However the offDiagMat looses some columns - and this is
9043   reconstructed with MatSetValues()
9044 
9045   Level: advanced
9046 
9047   Concepts: subcommunicator
9048   Concepts: submatrices
9049 
9050 .seealso: MatGetSubMatrices()
9051 @*/
9052 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9053 {
9054   PetscErrorCode ierr;
9055   PetscMPIInt    commsize,subCommSize;
9056 
9057   PetscFunctionBegin;
9058   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
9059   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9060   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9061 
9062   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9063   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9064   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9065   PetscFunctionReturn(0);
9066 }
9067 
9068 #undef __FUNCT__
9069 #define __FUNCT__ "MatGetLocalSubMatrix"
9070 /*@
9071    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9072 
9073    Not Collective
9074 
9075    Input Arguments:
9076    mat - matrix to extract local submatrix from
9077    isrow - local row indices for submatrix
9078    iscol - local column indices for submatrix
9079 
9080    Output Arguments:
9081    submat - the submatrix
9082 
9083    Level: intermediate
9084 
9085    Notes:
9086    The submat should be returned with MatRestoreLocalSubMatrix().
9087 
9088    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9089    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9090 
9091    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9092    MatSetValuesBlockedLocal() will also be implemented.
9093 
9094 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9095 @*/
9096 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9097 {
9098   PetscErrorCode ierr;
9099 
9100   PetscFunctionBegin;
9101   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9102   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9103   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9104   PetscCheckSameComm(isrow,2,iscol,3);
9105   PetscValidPointer(submat,4);
9106 
9107   if (mat->ops->getlocalsubmatrix) {
9108     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9109   } else {
9110     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9111   }
9112   PetscFunctionReturn(0);
9113 }
9114 
9115 #undef __FUNCT__
9116 #define __FUNCT__ "MatRestoreLocalSubMatrix"
9117 /*@
9118    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9119 
9120    Not Collective
9121 
9122    Input Arguments:
9123    mat - matrix to extract local submatrix from
9124    isrow - local row indices for submatrix
9125    iscol - local column indices for submatrix
9126    submat - the submatrix
9127 
9128    Level: intermediate
9129 
9130 .seealso: MatGetLocalSubMatrix()
9131 @*/
9132 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9133 {
9134   PetscErrorCode ierr;
9135 
9136   PetscFunctionBegin;
9137   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9138   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9139   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9140   PetscCheckSameComm(isrow,2,iscol,3);
9141   PetscValidPointer(submat,4);
9142   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
9143 
9144   if (mat->ops->restorelocalsubmatrix) {
9145     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9146   } else {
9147     ierr = MatDestroy(submat);CHKERRQ(ierr);
9148   }
9149   *submat = PETSC_NULL;
9150   PetscFunctionReturn(0);
9151 }
9152 
9153 /* --------------------------------------------------------*/
9154 #undef __FUNCT__
9155 #define __FUNCT__ "MatFindZeroDiagonals"
9156 /*@
9157    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9158 
9159    Collective on Mat
9160 
9161    Input Parameter:
9162 .  mat - the matrix
9163 
9164    Output Parameter:
9165 .  is - if any rows have zero diagonals this contains the list of them
9166 
9167    Level: developer
9168 
9169    Concepts: matrix-vector product
9170 
9171 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9172 @*/
9173 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9174 {
9175   PetscErrorCode ierr;
9176 
9177   PetscFunctionBegin;
9178   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9179   PetscValidType(mat,1);
9180   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9181   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9182 
9183   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9184   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
9185   PetscFunctionReturn(0);
9186 }
9187 
9188 #undef __FUNCT__
9189 #define __FUNCT__ "MatInvertBlockDiagonal"
9190 /*@
9191   MatInvertBlockDiagonal - Inverts the block diagonal entries.
9192 
9193   Collective on Mat
9194 
9195   Input Parameters:
9196 . mat - the matrix
9197 
9198   Output Parameters:
9199 . values - the block inverses in column major order (FORTRAN-like)
9200 
9201   Level: advanced
9202 @*/
9203 PetscErrorCode  MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
9204 {
9205   PetscErrorCode ierr;
9206 
9207   PetscFunctionBegin;
9208   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9209   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9210   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9211   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9212   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9213   PetscFunctionReturn(0);
9214 }
9215 
9216 #undef __FUNCT__
9217 #define __FUNCT__ "MatTransposeColoringDestroy"
9218 /*@C
9219     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9220     via MatTransposeColoringCreate().
9221 
9222     Collective on MatTransposeColoring
9223 
9224     Input Parameter:
9225 .   c - coloring context
9226 
9227     Level: intermediate
9228 
9229 .seealso: MatTransposeColoringCreate()
9230 @*/
9231 PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9232 {
9233   PetscErrorCode       ierr;
9234   MatTransposeColoring matcolor=*c;
9235 
9236   PetscFunctionBegin;
9237   if (!matcolor) PetscFunctionReturn(0);
9238   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
9239 
9240   ierr = PetscFree(matcolor->ncolumns);CHKERRQ(ierr);
9241   ierr = PetscFree(matcolor->nrows);CHKERRQ(ierr);
9242   ierr = PetscFree(matcolor->colorforrow);CHKERRQ(ierr);
9243   ierr = PetscFree2(matcolor->rows,matcolor->columnsforspidx);CHKERRQ(ierr);
9244   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
9245   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
9246   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
9247   PetscFunctionReturn(0);
9248 }
9249 
9250 #undef __FUNCT__
9251 #define __FUNCT__ "MatTransColoringApplySpToDen"
9252 /*@C
9253     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9254     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9255     MatTransposeColoring to sparse B.
9256 
9257     Collective on MatTransposeColoring
9258 
9259     Input Parameters:
9260 +   B - sparse matrix B
9261 .   Btdense - symbolic dense matrix B^T
9262 -   coloring - coloring context created with MatTransposeColoringCreate()
9263 
9264     Output Parameter:
9265 .   Btdense - dense matrix B^T
9266 
9267     Options Database Keys:
9268 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9269 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9270 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
9271 
9272     Level: intermediate
9273 
9274 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9275 
9276 .keywords: coloring
9277 @*/
9278 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9279 {
9280   PetscErrorCode ierr;
9281 
9282   PetscFunctionBegin;
9283   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
9284   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
9285   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
9286 
9287   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9288   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
9289   PetscFunctionReturn(0);
9290 }
9291 
9292 #undef __FUNCT__
9293 #define __FUNCT__ "MatTransColoringApplyDenToSp"
9294 /*@C
9295     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9296     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9297     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9298     Csp from Cden.
9299 
9300     Collective on MatTransposeColoring
9301 
9302     Input Parameters:
9303 +   coloring - coloring context created with MatTransposeColoringCreate()
9304 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
9305 
9306     Output Parameter:
9307 .   Csp - sparse matrix
9308 
9309     Options Database Keys:
9310 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9311 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9312 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9313 
9314     Level: intermediate
9315 
9316 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9317 
9318 .keywords: coloring
9319 @*/
9320 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9321 {
9322   PetscErrorCode ierr;
9323 
9324   PetscFunctionBegin;
9325   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
9326   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
9327   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
9328 
9329   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9330   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
9331   PetscFunctionReturn(0);
9332 }
9333 
9334 #undef __FUNCT__
9335 #define __FUNCT__ "MatTransposeColoringCreate"
9336 /*@C
9337    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9338 
9339    Collective on Mat
9340 
9341    Input Parameters:
9342 +  mat - the matrix product C
9343 -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9344 
9345     Output Parameter:
9346 .   color - the new coloring context
9347 
9348     Level: intermediate
9349 
9350 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9351            MatTransColoringApplyDen()ToSp, MatTransposeColoringView(),
9352 @*/
9353 PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9354 {
9355   MatTransposeColoring  c;
9356   MPI_Comm              comm;
9357   PetscErrorCode        ierr;
9358 
9359   PetscFunctionBegin;
9360   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9361   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9362   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);
9363 
9364   c->ctype = iscoloring->ctype;
9365   if (mat->ops->transposecoloringcreate) {
9366     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
9367   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");
9368 
9369   *color = c;
9370   ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9371   PetscFunctionReturn(0);
9372 }
9373