xref: /petsc/src/mat/interface/matrix.c (revision 5ec1a3fa3a66d5e31f30db08e2b361315eb0c3c4)
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.
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    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5143 
5144    Level: intermediate
5145 
5146    Concepts: matrices^setting options
5147 
5148 @*/
5149 PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5150 {
5151   PetscErrorCode ierr;
5152 
5153   PetscFunctionBegin;
5154   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5155   PetscValidType(mat,1);
5156   PetscValidLogicalCollectiveEnum(mat,op,2);
5157   PetscValidLogicalCollectiveBool(mat,flg,3);
5158 
5159   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5160   if (!((PetscObject)mat)->type_name) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5161 
5162   switch (op) {
5163   case MAT_NO_OFF_PROC_ENTRIES:
5164     mat->nooffprocentries                = flg;
5165     PetscFunctionReturn(0);
5166     break;
5167   case MAT_NO_OFF_PROC_ZERO_ROWS:
5168     mat->nooffproczerorows               = flg;
5169     PetscFunctionReturn(0);
5170     break;
5171   case MAT_SPD:
5172     mat->spd_set                         = PETSC_TRUE;
5173     mat->spd                             = flg;
5174     if (flg) {
5175       mat->symmetric                     = PETSC_TRUE;
5176       mat->structurally_symmetric        = PETSC_TRUE;
5177       mat->symmetric_set                 = PETSC_TRUE;
5178       mat->structurally_symmetric_set    = PETSC_TRUE;
5179     }
5180     break;
5181   case MAT_SYMMETRIC:
5182     mat->symmetric                       = flg;
5183     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5184     mat->symmetric_set                   = PETSC_TRUE;
5185     mat->structurally_symmetric_set      = flg;
5186     break;
5187   case MAT_HERMITIAN:
5188     mat->hermitian                       = flg;
5189     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5190     mat->hermitian_set                   = PETSC_TRUE;
5191     mat->structurally_symmetric_set      = flg;
5192     break;
5193   case MAT_STRUCTURALLY_SYMMETRIC:
5194     mat->structurally_symmetric          = flg;
5195     mat->structurally_symmetric_set      = PETSC_TRUE;
5196     break;
5197   case MAT_SYMMETRY_ETERNAL:
5198     mat->symmetric_eternal               = flg;
5199     break;
5200   default:
5201     break;
5202   }
5203   if (mat->ops->setoption) {
5204     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5205   }
5206   PetscFunctionReturn(0);
5207 }
5208 
5209 #undef __FUNCT__
5210 #define __FUNCT__ "MatZeroEntries"
5211 /*@
5212    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5213    this routine retains the old nonzero structure.
5214 
5215    Logically Collective on Mat
5216 
5217    Input Parameters:
5218 .  mat - the matrix
5219 
5220    Level: intermediate
5221 
5222    Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase.
5223    See the Performance chapter of the users manual for information on preallocating matrices.
5224 
5225    Concepts: matrices^zeroing
5226 
5227 .seealso: MatZeroRows()
5228 @*/
5229 PetscErrorCode  MatZeroEntries(Mat mat)
5230 {
5231   PetscErrorCode ierr;
5232 
5233   PetscFunctionBegin;
5234   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5235   PetscValidType(mat,1);
5236   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5237   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5238   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5239   MatCheckPreallocated(mat,1);
5240 
5241   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5242   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5243   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5244   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5245 #if defined(PETSC_HAVE_CUSP)
5246   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5247     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5248   }
5249 #endif
5250   PetscFunctionReturn(0);
5251 }
5252 
5253 #undef __FUNCT__
5254 #define __FUNCT__ "MatZeroRowsColumns"
5255 /*@C
5256    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5257    of a set of rows and columns of a matrix.
5258 
5259    Collective on Mat
5260 
5261    Input Parameters:
5262 +  mat - the matrix
5263 .  numRows - the number of rows to remove
5264 .  rows - the global row indices
5265 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5266 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5267 -  b - optional vector of right hand side, that will be adjusted by provided solution
5268 
5269    Notes:
5270    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5271 
5272    The user can set a value in the diagonal entry (or for the AIJ and
5273    row formats can optionally remove the main diagonal entry from the
5274    nonzero structure as well, by passing 0.0 as the final argument).
5275 
5276    For the parallel case, all processes that share the matrix (i.e.,
5277    those in the communicator used for matrix creation) MUST call this
5278    routine, regardless of whether any rows being zeroed are owned by
5279    them.
5280 
5281    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5282    list only rows local to itself).
5283 
5284    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5285 
5286    Level: intermediate
5287 
5288    Concepts: matrices^zeroing rows
5289 
5290 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5291 @*/
5292 PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5293 {
5294   PetscErrorCode ierr;
5295 
5296   PetscFunctionBegin;
5297   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5298   PetscValidType(mat,1);
5299   if (numRows) PetscValidIntPointer(rows,3);
5300   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5301   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5302   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5303   MatCheckPreallocated(mat,1);
5304 
5305   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5306   ierr = MatView_Private(mat);CHKERRQ(ierr);
5307   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5308 #if defined(PETSC_HAVE_CUSP)
5309   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5310     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5311   }
5312 #endif
5313   PetscFunctionReturn(0);
5314 }
5315 
5316 #undef __FUNCT__
5317 #define __FUNCT__ "MatZeroRowsColumnsIS"
5318 /*@C
5319    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5320    of a set of rows and columns of a matrix.
5321 
5322    Collective on Mat
5323 
5324    Input Parameters:
5325 +  mat - the matrix
5326 .  is - the rows to zero
5327 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5328 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5329 -  b - optional vector of right hand side, that will be adjusted by provided solution
5330 
5331    Notes:
5332    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5333 
5334    The user can set a value in the diagonal entry (or for the AIJ and
5335    row formats can optionally remove the main diagonal entry from the
5336    nonzero structure as well, by passing 0.0 as the final argument).
5337 
5338    For the parallel case, all processes that share the matrix (i.e.,
5339    those in the communicator used for matrix creation) MUST call this
5340    routine, regardless of whether any rows being zeroed are owned by
5341    them.
5342 
5343    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5344    list only rows local to itself).
5345 
5346    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5347 
5348    Level: intermediate
5349 
5350    Concepts: matrices^zeroing rows
5351 
5352 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5353 @*/
5354 PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5355 {
5356   PetscErrorCode ierr;
5357   PetscInt       numRows;
5358   const PetscInt *rows;
5359 
5360   PetscFunctionBegin;
5361   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5362   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5363   PetscValidType(mat,1);
5364   PetscValidType(is,2);
5365   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5366   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5367   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5368   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5369   PetscFunctionReturn(0);
5370 }
5371 
5372 #undef __FUNCT__
5373 #define __FUNCT__ "MatZeroRows"
5374 /*@C
5375    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5376    of a set of rows of a matrix.
5377 
5378    Collective on Mat
5379 
5380    Input Parameters:
5381 +  mat - the matrix
5382 .  numRows - the number of rows to remove
5383 .  rows - the global row indices
5384 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5385 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5386 -  b - optional vector of right hand side, that will be adjusted by provided solution
5387 
5388    Notes:
5389    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5390    but does not release memory.  For the dense and block diagonal
5391    formats this does not alter the nonzero structure.
5392 
5393    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5394    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5395    merely zeroed.
5396 
5397    The user can set a value in the diagonal entry (or for the AIJ and
5398    row formats can optionally remove the main diagonal entry from the
5399    nonzero structure as well, by passing 0.0 as the final argument).
5400 
5401    For the parallel case, all processes that share the matrix (i.e.,
5402    those in the communicator used for matrix creation) MUST call this
5403    routine, regardless of whether any rows being zeroed are owned by
5404    them.
5405 
5406    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5407    list only rows local to itself).
5408 
5409    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5410    owns that are to be zeroed. This saves a global synchronization in the implementation.
5411 
5412    Level: intermediate
5413 
5414    Concepts: matrices^zeroing rows
5415 
5416 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5417 @*/
5418 PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5419 {
5420   PetscErrorCode ierr;
5421 
5422   PetscFunctionBegin;
5423   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5424   PetscValidType(mat,1);
5425   if (numRows) PetscValidIntPointer(rows,3);
5426   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5427   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5428   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5429   MatCheckPreallocated(mat,1);
5430 
5431   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5432   ierr = MatView_Private(mat);CHKERRQ(ierr);
5433   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5434 #if defined(PETSC_HAVE_CUSP)
5435   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5436     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5437   }
5438 #endif
5439   PetscFunctionReturn(0);
5440 }
5441 
5442 #undef __FUNCT__
5443 #define __FUNCT__ "MatZeroRowsIS"
5444 /*@C
5445    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5446    of a set of rows of a matrix.
5447 
5448    Collective on Mat
5449 
5450    Input Parameters:
5451 +  mat - the matrix
5452 .  is - index set of rows to remove
5453 .  diag - value put in all diagonals of eliminated rows
5454 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5455 -  b - optional vector of right hand side, that will be adjusted by provided solution
5456 
5457    Notes:
5458    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5459    but does not release memory.  For the dense and block diagonal
5460    formats this does not alter the nonzero structure.
5461 
5462    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5463    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5464    merely zeroed.
5465 
5466    The user can set a value in the diagonal entry (or for the AIJ and
5467    row formats can optionally remove the main diagonal entry from the
5468    nonzero structure as well, by passing 0.0 as the final argument).
5469 
5470    For the parallel case, all processes that share the matrix (i.e.,
5471    those in the communicator used for matrix creation) MUST call this
5472    routine, regardless of whether any rows being zeroed are owned by
5473    them.
5474 
5475    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5476    list only rows local to itself).
5477 
5478    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5479    owns that are to be zeroed. This saves a global synchronization in the implementation.
5480 
5481    Level: intermediate
5482 
5483    Concepts: matrices^zeroing rows
5484 
5485 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5486 @*/
5487 PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5488 {
5489   PetscInt       numRows;
5490   const PetscInt *rows;
5491   PetscErrorCode ierr;
5492 
5493   PetscFunctionBegin;
5494   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5495   PetscValidType(mat,1);
5496   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5497   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5498   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5499   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5500   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5501   PetscFunctionReturn(0);
5502 }
5503 
5504 #undef __FUNCT__
5505 #define __FUNCT__ "MatZeroRowsStencil"
5506 /*@C
5507    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5508    of a set of rows of a matrix. These rows must be local to the process.
5509 
5510    Collective on Mat
5511 
5512    Input Parameters:
5513 +  mat - the matrix
5514 .  numRows - the number of rows to remove
5515 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5516 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5517 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5518 -  b - optional vector of right hand side, that will be adjusted by provided solution
5519 
5520    Notes:
5521    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5522    but does not release memory.  For the dense and block diagonal
5523    formats this does not alter the nonzero structure.
5524 
5525    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5526    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5527    merely zeroed.
5528 
5529    The user can set a value in the diagonal entry (or for the AIJ and
5530    row formats can optionally remove the main diagonal entry from the
5531    nonzero structure as well, by passing 0.0 as the final argument).
5532 
5533    For the parallel case, all processes that share the matrix (i.e.,
5534    those in the communicator used for matrix creation) MUST call this
5535    routine, regardless of whether any rows being zeroed are owned by
5536    them.
5537 
5538    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5539    list only rows local to itself).
5540 
5541    The grid coordinates are across the entire grid, not just the local portion
5542 
5543    In Fortran idxm and idxn should be declared as
5544 $     MatStencil idxm(4,m)
5545    and the values inserted using
5546 $    idxm(MatStencil_i,1) = i
5547 $    idxm(MatStencil_j,1) = j
5548 $    idxm(MatStencil_k,1) = k
5549 $    idxm(MatStencil_c,1) = c
5550    etc
5551 
5552    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5553    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5554    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5555    DMDA_BOUNDARY_PERIODIC boundary type.
5556 
5557    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
5558    a single value per point) you can skip filling those indices.
5559 
5560    Level: intermediate
5561 
5562    Concepts: matrices^zeroing rows
5563 
5564 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5565 @*/
5566 PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5567 {
5568   PetscInt       dim    = mat->stencil.dim;
5569   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5570   PetscInt      *dims   = mat->stencil.dims+1;
5571   PetscInt      *starts = mat->stencil.starts;
5572   PetscInt      *dxm    = (PetscInt *) rows;
5573   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5574   PetscErrorCode ierr;
5575 
5576   PetscFunctionBegin;
5577   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5578   PetscValidType(mat,1);
5579   if (numRows) PetscValidIntPointer(rows,3);
5580 
5581   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5582   for(i = 0; i < numRows; ++i) {
5583     /* Skip unused dimensions (they are ordered k, j, i, c) */
5584     for(j = 0; j < 3-sdim; ++j) dxm++;
5585     /* Local index in X dir */
5586     tmp = *dxm++ - starts[0];
5587     /* Loop over remaining dimensions */
5588     for(j = 0; j < dim-1; ++j) {
5589       /* If nonlocal, set index to be negative */
5590       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5591       /* Update local index */
5592       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5593     }
5594     /* Skip component slot if necessary */
5595     if (mat->stencil.noc) dxm++;
5596     /* Local row number */
5597     if (tmp >= 0) {
5598       jdxm[numNewRows++] = tmp;
5599     }
5600   }
5601   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5602   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5603   PetscFunctionReturn(0);
5604 }
5605 
5606 #undef __FUNCT__
5607 #define __FUNCT__ "MatZeroRowsColumnsStencil"
5608 /*@C
5609    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5610    of a set of rows and columns of a matrix.
5611 
5612    Collective on Mat
5613 
5614    Input Parameters:
5615 +  mat - the matrix
5616 .  numRows - the number of rows/columns to remove
5617 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5618 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5619 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5620 -  b - optional vector of right hand side, that will be adjusted by provided solution
5621 
5622    Notes:
5623    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5624    but does not release memory.  For the dense and block diagonal
5625    formats this does not alter the nonzero structure.
5626 
5627    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5628    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5629    merely zeroed.
5630 
5631    The user can set a value in the diagonal entry (or for the AIJ and
5632    row formats can optionally remove the main diagonal entry from the
5633    nonzero structure as well, by passing 0.0 as the final argument).
5634 
5635    For the parallel case, all processes that share the matrix (i.e.,
5636    those in the communicator used for matrix creation) MUST call this
5637    routine, regardless of whether any rows being zeroed are owned by
5638    them.
5639 
5640    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5641    list only rows local to itself, but the row/column numbers are given in local numbering).
5642 
5643    The grid coordinates are across the entire grid, not just the local portion
5644 
5645    In Fortran idxm and idxn should be declared as
5646 $     MatStencil idxm(4,m)
5647    and the values inserted using
5648 $    idxm(MatStencil_i,1) = i
5649 $    idxm(MatStencil_j,1) = j
5650 $    idxm(MatStencil_k,1) = k
5651 $    idxm(MatStencil_c,1) = c
5652    etc
5653 
5654    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5655    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5656    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5657    DMDA_BOUNDARY_PERIODIC boundary type.
5658 
5659    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
5660    a single value per point) you can skip filling those indices.
5661 
5662    Level: intermediate
5663 
5664    Concepts: matrices^zeroing rows
5665 
5666 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5667 @*/
5668 PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5669 {
5670   PetscInt       dim    = mat->stencil.dim;
5671   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5672   PetscInt      *dims   = mat->stencil.dims+1;
5673   PetscInt      *starts = mat->stencil.starts;
5674   PetscInt      *dxm    = (PetscInt *) rows;
5675   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5676   PetscErrorCode ierr;
5677 
5678   PetscFunctionBegin;
5679   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5680   PetscValidType(mat,1);
5681   if (numRows) PetscValidIntPointer(rows,3);
5682 
5683   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5684   for(i = 0; i < numRows; ++i) {
5685     /* Skip unused dimensions (they are ordered k, j, i, c) */
5686     for(j = 0; j < 3-sdim; ++j) dxm++;
5687     /* Local index in X dir */
5688     tmp = *dxm++ - starts[0];
5689     /* Loop over remaining dimensions */
5690     for(j = 0; j < dim-1; ++j) {
5691       /* If nonlocal, set index to be negative */
5692       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5693       /* Update local index */
5694       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5695     }
5696     /* Skip component slot if necessary */
5697     if (mat->stencil.noc) dxm++;
5698     /* Local row number */
5699     if (tmp >= 0) {
5700       jdxm[numNewRows++] = tmp;
5701     }
5702   }
5703   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5704   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5705   PetscFunctionReturn(0);
5706 }
5707 
5708 #undef __FUNCT__
5709 #define __FUNCT__ "MatZeroRowsLocal"
5710 /*@C
5711    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5712    of a set of rows of a matrix; using local numbering of rows.
5713 
5714    Collective on Mat
5715 
5716    Input Parameters:
5717 +  mat - the matrix
5718 .  numRows - the number of rows to remove
5719 .  rows - the global row indices
5720 .  diag - value put in all diagonals of eliminated rows
5721 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5722 -  b - optional vector of right hand side, that will be adjusted by provided solution
5723 
5724    Notes:
5725    Before calling MatZeroRowsLocal(), the user must first set the
5726    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5727 
5728    For the AIJ matrix formats this removes the old nonzero structure,
5729    but does not release memory.  For the dense and block diagonal
5730    formats this does not alter the nonzero structure.
5731 
5732    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5733    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5734    merely zeroed.
5735 
5736    The user can set a value in the diagonal entry (or for the AIJ and
5737    row formats can optionally remove the main diagonal entry from the
5738    nonzero structure as well, by passing 0.0 as the final argument).
5739 
5740    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5741    owns that are to be zeroed. This saves a global synchronization in the implementation.
5742 
5743    Level: intermediate
5744 
5745    Concepts: matrices^zeroing
5746 
5747 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5748 @*/
5749 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5750 {
5751   PetscErrorCode ierr;
5752   PetscMPIInt    size;
5753 
5754   PetscFunctionBegin;
5755   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5756   PetscValidType(mat,1);
5757   if (numRows) PetscValidIntPointer(rows,3);
5758   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5759   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5760   MatCheckPreallocated(mat,1);
5761 
5762   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5763   if (mat->ops->zerorowslocal) {
5764     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5765   } else if (size == 1) {
5766     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5767   } else {
5768     IS             is, newis;
5769     const PetscInt *newRows;
5770 
5771     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5772     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5773     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5774     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5775     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5776     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5777     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5778     ierr = ISDestroy(&is);CHKERRQ(ierr);
5779   }
5780   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5781 #if defined(PETSC_HAVE_CUSP)
5782   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5783     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5784   }
5785 #endif
5786   PetscFunctionReturn(0);
5787 }
5788 
5789 #undef __FUNCT__
5790 #define __FUNCT__ "MatZeroRowsLocalIS"
5791 /*@C
5792    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5793    of a set of rows of a matrix; using local numbering of rows.
5794 
5795    Collective on Mat
5796 
5797    Input Parameters:
5798 +  mat - the matrix
5799 .  is - index set of rows to remove
5800 .  diag - value put in all diagonals of eliminated rows
5801 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5802 -  b - optional vector of right hand side, that will be adjusted by provided solution
5803 
5804    Notes:
5805    Before calling MatZeroRowsLocalIS(), the user must first set the
5806    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5807 
5808    For the AIJ matrix formats this removes the old nonzero structure,
5809    but does not release memory.  For the dense and block diagonal
5810    formats this does not alter the nonzero structure.
5811 
5812    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5813    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5814    merely zeroed.
5815 
5816    The user can set a value in the diagonal entry (or for the AIJ and
5817    row formats can optionally remove the main diagonal entry from the
5818    nonzero structure as well, by passing 0.0 as the final argument).
5819 
5820    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5821    owns that are to be zeroed. This saves a global synchronization in the implementation.
5822 
5823    Level: intermediate
5824 
5825    Concepts: matrices^zeroing
5826 
5827 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5828 @*/
5829 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5830 {
5831   PetscErrorCode ierr;
5832   PetscInt       numRows;
5833   const PetscInt *rows;
5834 
5835   PetscFunctionBegin;
5836   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5837   PetscValidType(mat,1);
5838   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5839   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5840   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5841   MatCheckPreallocated(mat,1);
5842 
5843   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5844   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5845   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5846   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5847   PetscFunctionReturn(0);
5848 }
5849 
5850 #undef __FUNCT__
5851 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5852 /*@C
5853    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5854    of a set of rows and columns of a matrix; using local numbering of rows.
5855 
5856    Collective on Mat
5857 
5858    Input Parameters:
5859 +  mat - the matrix
5860 .  numRows - the number of rows to remove
5861 .  rows - the global row indices
5862 .  diag - value put in all diagonals of eliminated rows
5863 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5864 -  b - optional vector of right hand side, that will be adjusted by provided solution
5865 
5866    Notes:
5867    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5868    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5869 
5870    The user can set a value in the diagonal entry (or for the AIJ and
5871    row formats can optionally remove the main diagonal entry from the
5872    nonzero structure as well, by passing 0.0 as the final argument).
5873 
5874    Level: intermediate
5875 
5876    Concepts: matrices^zeroing
5877 
5878 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5879 @*/
5880 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5881 {
5882   PetscErrorCode ierr;
5883   PetscMPIInt    size;
5884 
5885   PetscFunctionBegin;
5886   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5887   PetscValidType(mat,1);
5888   if (numRows) PetscValidIntPointer(rows,3);
5889   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5890   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5891   MatCheckPreallocated(mat,1);
5892 
5893   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5894   if (size == 1) {
5895     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5896   } else {
5897     IS             is, newis;
5898     const PetscInt *newRows;
5899 
5900     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5901     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5902     ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
5903     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5904     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5905     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5906     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5907     ierr = ISDestroy(&is);CHKERRQ(ierr);
5908   }
5909   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5910 #if defined(PETSC_HAVE_CUSP)
5911   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5912     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5913   }
5914 #endif
5915   PetscFunctionReturn(0);
5916 }
5917 
5918 #undef __FUNCT__
5919 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5920 /*@C
5921    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5922    of a set of rows and columns of a matrix; using local numbering of rows.
5923 
5924    Collective on Mat
5925 
5926    Input Parameters:
5927 +  mat - the matrix
5928 .  is - index set of rows to remove
5929 .  diag - value put in all diagonals of eliminated rows
5930 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5931 -  b - optional vector of right hand side, that will be adjusted by provided solution
5932 
5933    Notes:
5934    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5935    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5936 
5937    The user can set a value in the diagonal entry (or for the AIJ and
5938    row formats can optionally remove the main diagonal entry from the
5939    nonzero structure as well, by passing 0.0 as the final argument).
5940 
5941    Level: intermediate
5942 
5943    Concepts: matrices^zeroing
5944 
5945 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5946 @*/
5947 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5948 {
5949   PetscErrorCode ierr;
5950   PetscInt       numRows;
5951   const PetscInt *rows;
5952 
5953   PetscFunctionBegin;
5954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5955   PetscValidType(mat,1);
5956   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5957   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5958   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5959   MatCheckPreallocated(mat,1);
5960 
5961   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5962   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5963   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5964   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5965   PetscFunctionReturn(0);
5966 }
5967 
5968 #undef __FUNCT__
5969 #define __FUNCT__ "MatGetSize"
5970 /*@
5971    MatGetSize - Returns the numbers of rows and columns in a matrix.
5972 
5973    Not Collective
5974 
5975    Input Parameter:
5976 .  mat - the matrix
5977 
5978    Output Parameters:
5979 +  m - the number of global rows
5980 -  n - the number of global columns
5981 
5982    Note: both output parameters can be PETSC_NULL on input.
5983 
5984    Level: beginner
5985 
5986    Concepts: matrices^size
5987 
5988 .seealso: MatGetLocalSize()
5989 @*/
5990 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5991 {
5992   PetscFunctionBegin;
5993   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5994   if (m) *m = mat->rmap->N;
5995   if (n) *n = mat->cmap->N;
5996   PetscFunctionReturn(0);
5997 }
5998 
5999 #undef __FUNCT__
6000 #define __FUNCT__ "MatGetLocalSize"
6001 /*@
6002    MatGetLocalSize - Returns the number of rows and columns in a matrix
6003    stored locally.  This information may be implementation dependent, so
6004    use with care.
6005 
6006    Not Collective
6007 
6008    Input Parameters:
6009 .  mat - the matrix
6010 
6011    Output Parameters:
6012 +  m - the number of local rows
6013 -  n - the number of local columns
6014 
6015    Note: both output parameters can be PETSC_NULL on input.
6016 
6017    Level: beginner
6018 
6019    Concepts: matrices^local size
6020 
6021 .seealso: MatGetSize()
6022 @*/
6023 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
6024 {
6025   PetscFunctionBegin;
6026   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6027   if (m) PetscValidIntPointer(m,2);
6028   if (n) PetscValidIntPointer(n,3);
6029   if (m) *m = mat->rmap->n;
6030   if (n) *n = mat->cmap->n;
6031   PetscFunctionReturn(0);
6032 }
6033 
6034 #undef __FUNCT__
6035 #define __FUNCT__ "MatGetOwnershipRangeColumn"
6036 /*@
6037    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6038    this processor. (The columns of the "diagonal block")
6039 
6040    Not Collective, unless matrix has not been allocated, then collective on Mat
6041 
6042    Input Parameters:
6043 .  mat - the matrix
6044 
6045    Output Parameters:
6046 +  m - the global index of the first local column
6047 -  n - one more than the global index of the last local column
6048 
6049    Notes: both output parameters can be PETSC_NULL on input.
6050 
6051    Level: developer
6052 
6053    Concepts: matrices^column ownership
6054 
6055 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6056 
6057 @*/
6058 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
6059 {
6060 
6061   PetscFunctionBegin;
6062   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6063   PetscValidType(mat,1);
6064   if (m) PetscValidIntPointer(m,2);
6065   if (n) PetscValidIntPointer(n,3);
6066   MatCheckPreallocated(mat,1);
6067   if (m) *m = mat->cmap->rstart;
6068   if (n) *n = mat->cmap->rend;
6069   PetscFunctionReturn(0);
6070 }
6071 
6072 #undef __FUNCT__
6073 #define __FUNCT__ "MatGetOwnershipRange"
6074 /*@
6075    MatGetOwnershipRange - Returns the range of matrix rows owned by
6076    this processor, assuming that the matrix is laid out with the first
6077    n1 rows on the first processor, the next n2 rows on the second, etc.
6078    For certain parallel layouts this range may not be well defined.
6079 
6080    Not Collective, unless matrix has not been allocated, then collective on Mat
6081 
6082    Input Parameters:
6083 .  mat - the matrix
6084 
6085    Output Parameters:
6086 +  m - the global index of the first local row
6087 -  n - one more than the global index of the last local row
6088 
6089    Note: both output parameters can be PETSC_NULL on input.
6090 
6091    Level: beginner
6092 
6093    Concepts: matrices^row ownership
6094 
6095 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6096 
6097 @*/
6098 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
6099 {
6100 
6101   PetscFunctionBegin;
6102   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6103   PetscValidType(mat,1);
6104   if (m) PetscValidIntPointer(m,2);
6105   if (n) PetscValidIntPointer(n,3);
6106   MatCheckPreallocated(mat,1);
6107   if (m) *m = mat->rmap->rstart;
6108   if (n) *n = mat->rmap->rend;
6109   PetscFunctionReturn(0);
6110 }
6111 
6112 #undef __FUNCT__
6113 #define __FUNCT__ "MatGetOwnershipRanges"
6114 /*@C
6115    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6116    each process
6117 
6118    Not Collective, unless matrix has not been allocated, then collective on Mat
6119 
6120    Input Parameters:
6121 .  mat - the matrix
6122 
6123    Output Parameters:
6124 .  ranges - start of each processors portion plus one more then the total length at the end
6125 
6126    Level: beginner
6127 
6128    Concepts: matrices^row ownership
6129 
6130 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6131 
6132 @*/
6133 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6134 {
6135   PetscErrorCode ierr;
6136 
6137   PetscFunctionBegin;
6138   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6139   PetscValidType(mat,1);
6140   MatCheckPreallocated(mat,1);
6141   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6142   PetscFunctionReturn(0);
6143 }
6144 
6145 #undef __FUNCT__
6146 #define __FUNCT__ "MatGetOwnershipRangesColumn"
6147 /*@C
6148    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6149    this processor. (The columns of the "diagonal blocks" for each process)
6150 
6151    Not Collective, unless matrix has not been allocated, then collective on Mat
6152 
6153    Input Parameters:
6154 .  mat - the matrix
6155 
6156    Output Parameters:
6157 .  ranges - start of each processors portion plus one more then the total length at the end
6158 
6159    Level: beginner
6160 
6161    Concepts: matrices^column ownership
6162 
6163 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6164 
6165 @*/
6166 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6167 {
6168   PetscErrorCode ierr;
6169 
6170   PetscFunctionBegin;
6171   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6172   PetscValidType(mat,1);
6173   MatCheckPreallocated(mat,1);
6174   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6175   PetscFunctionReturn(0);
6176 }
6177 
6178 #undef __FUNCT__
6179 #define __FUNCT__ "MatILUFactorSymbolic"
6180 /*@C
6181    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6182    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6183    to complete the factorization.
6184 
6185    Collective on Mat
6186 
6187    Input Parameters:
6188 +  mat - the matrix
6189 .  row - row permutation
6190 .  column - column permutation
6191 -  info - structure containing
6192 $      levels - number of levels of fill.
6193 $      expected fill - as ratio of original fill.
6194 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6195                 missing diagonal entries)
6196 
6197    Output Parameters:
6198 .  fact - new matrix that has been symbolically factored
6199 
6200    Notes:
6201    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6202    choosing the fill factor for better efficiency.
6203 
6204    Most users should employ the simplified KSP interface for linear solvers
6205    instead of working directly with matrix algebra routines such as this.
6206    See, e.g., KSPCreate().
6207 
6208    Level: developer
6209 
6210   Concepts: matrices^symbolic LU factorization
6211   Concepts: matrices^factorization
6212   Concepts: LU^symbolic factorization
6213 
6214 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6215           MatGetOrdering(), MatFactorInfo
6216 
6217     Developer Note: fortran interface is not autogenerated as the f90
6218     interface defintion cannot be generated correctly [due to MatFactorInfo]
6219 
6220 @*/
6221 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6222 {
6223   PetscErrorCode ierr;
6224 
6225   PetscFunctionBegin;
6226   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6227   PetscValidType(mat,1);
6228   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6229   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6230   PetscValidPointer(info,4);
6231   PetscValidPointer(fact,5);
6232   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6233   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6234   if (!(fact)->ops->ilufactorsymbolic) {
6235     const MatSolverPackage spackage;
6236     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6237     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6238   }
6239   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6240   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6241   MatCheckPreallocated(mat,2);
6242 
6243   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6244   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6245   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6246   PetscFunctionReturn(0);
6247 }
6248 
6249 #undef __FUNCT__
6250 #define __FUNCT__ "MatICCFactorSymbolic"
6251 /*@C
6252    MatICCFactorSymbolic - Performs symbolic incomplete
6253    Cholesky factorization for a symmetric matrix.  Use
6254    MatCholeskyFactorNumeric() to complete the factorization.
6255 
6256    Collective on Mat
6257 
6258    Input Parameters:
6259 +  mat - the matrix
6260 .  perm - row and column permutation
6261 -  info - structure containing
6262 $      levels - number of levels of fill.
6263 $      expected fill - as ratio of original fill.
6264 
6265    Output Parameter:
6266 .  fact - the factored matrix
6267 
6268    Notes:
6269    Most users should employ the KSP interface for linear solvers
6270    instead of working directly with matrix algebra routines such as this.
6271    See, e.g., KSPCreate().
6272 
6273    Level: developer
6274 
6275   Concepts: matrices^symbolic incomplete Cholesky factorization
6276   Concepts: matrices^factorization
6277   Concepts: Cholsky^symbolic factorization
6278 
6279 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6280 
6281     Developer Note: fortran interface is not autogenerated as the f90
6282     interface defintion cannot be generated correctly [due to MatFactorInfo]
6283 
6284 @*/
6285 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6286 {
6287   PetscErrorCode ierr;
6288 
6289   PetscFunctionBegin;
6290   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6291   PetscValidType(mat,1);
6292   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6293   PetscValidPointer(info,3);
6294   PetscValidPointer(fact,4);
6295   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6296   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6297   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6298   if (!(fact)->ops->iccfactorsymbolic) {
6299     const MatSolverPackage spackage;
6300     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6301     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6302   }
6303   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6304   MatCheckPreallocated(mat,2);
6305 
6306   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6307   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6308   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6309   PetscFunctionReturn(0);
6310 }
6311 
6312 #undef __FUNCT__
6313 #define __FUNCT__ "MatGetArray"
6314 /*@C
6315    MatGetArray - Returns a pointer to the element values in the matrix.
6316    The result of this routine is dependent on the underlying matrix data
6317    structure, and may not even work for certain matrix types.  You MUST
6318    call MatRestoreArray() when you no longer need to access the array.
6319 
6320    Not Collective
6321 
6322    Input Parameter:
6323 .  mat - the matrix
6324 
6325    Output Parameter:
6326 .  v - the location of the values
6327 
6328 
6329    Fortran Note:
6330    This routine is used differently from Fortran, e.g.,
6331 .vb
6332         Mat         mat
6333         PetscScalar mat_array(1)
6334         PetscOffset i_mat
6335         PetscErrorCode ierr
6336         call MatGetArray(mat,mat_array,i_mat,ierr)
6337 
6338   C  Access first local entry in matrix; note that array is
6339   C  treated as one dimensional
6340         value = mat_array(i_mat + 1)
6341 
6342         [... other code ...]
6343         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6344 .ve
6345 
6346    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6347    src/mat/examples/tests for details.
6348 
6349    Level: advanced
6350 
6351    Concepts: matrices^access array
6352 
6353 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6354 @*/
6355 PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6356 {
6357   PetscErrorCode ierr;
6358 
6359   PetscFunctionBegin;
6360   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6361   PetscValidType(mat,1);
6362   PetscValidPointer(v,2);
6363   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6364   MatCheckPreallocated(mat,1);
6365   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6366   CHKMEMQ;
6367   PetscFunctionReturn(0);
6368 }
6369 
6370 #undef __FUNCT__
6371 #define __FUNCT__ "MatRestoreArray"
6372 /*@C
6373    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6374 
6375    Not Collective
6376 
6377    Input Parameter:
6378 +  mat - the matrix
6379 -  v - the location of the values
6380 
6381    Fortran Note:
6382    This routine is used differently from Fortran, e.g.,
6383 .vb
6384         Mat         mat
6385         PetscScalar mat_array(1)
6386         PetscOffset i_mat
6387         PetscErrorCode ierr
6388         call MatGetArray(mat,mat_array,i_mat,ierr)
6389 
6390   C  Access first local entry in matrix; note that array is
6391   C  treated as one dimensional
6392         value = mat_array(i_mat + 1)
6393 
6394         [... other code ...]
6395         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6396 .ve
6397 
6398    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6399    src/mat/examples/tests for details
6400 
6401    Level: advanced
6402 
6403 .seealso: MatGetArray(), MatRestoreArrayF90()
6404 @*/
6405 PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6406 {
6407   PetscErrorCode ierr;
6408 
6409   PetscFunctionBegin;
6410   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6411   PetscValidType(mat,1);
6412   PetscValidPointer(v,2);
6413   CHKMEMQ;
6414   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6415   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6416   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6417 #if defined(PETSC_HAVE_CUSP)
6418   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6419     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6420   }
6421 #endif
6422   PetscFunctionReturn(0);
6423 }
6424 
6425 #undef __FUNCT__
6426 #define __FUNCT__ "MatGetSubMatrices"
6427 /*@C
6428    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6429    points to an array of valid matrices, they may be reused to store the new
6430    submatrices.
6431 
6432    Collective on Mat
6433 
6434    Input Parameters:
6435 +  mat - the matrix
6436 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6437 .  irow, icol - index sets of rows and columns to extract
6438 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6439 
6440    Output Parameter:
6441 .  submat - the array of submatrices
6442 
6443    Notes:
6444    MatGetSubMatrices() can extract ONLY sequential submatrices
6445    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6446    to extract a parallel submatrix.
6447 
6448    When extracting submatrices from a parallel matrix, each processor can
6449    form a different submatrix by setting the rows and columns of its
6450    individual index sets according to the local submatrix desired.
6451 
6452    When finished using the submatrices, the user should destroy
6453    them with MatDestroyMatrices().
6454 
6455    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6456    original matrix has not changed from that last call to MatGetSubMatrices().
6457 
6458    This routine creates the matrices in submat; you should NOT create them before
6459    calling it. It also allocates the array of matrix pointers submat.
6460 
6461    For BAIJ matrices the index sets must respect the block structure, that is if they
6462    request one row/column in a block, they must request all rows/columns that are in
6463    that block. For example, if the block size is 2 you cannot request just row 0 and
6464    column 0.
6465 
6466    Fortran Note:
6467    The Fortran interface is slightly different from that given below; it
6468    requires one to pass in  as submat a Mat (integer) array of size at least m.
6469 
6470    Level: advanced
6471 
6472    Concepts: matrices^accessing submatrices
6473    Concepts: submatrices
6474 
6475 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6476 @*/
6477 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6478 {
6479   PetscErrorCode ierr;
6480   PetscInt        i;
6481   PetscBool       eq;
6482 
6483   PetscFunctionBegin;
6484   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6485   PetscValidType(mat,1);
6486   if (n) {
6487     PetscValidPointer(irow,3);
6488     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6489     PetscValidPointer(icol,4);
6490     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6491   }
6492   PetscValidPointer(submat,6);
6493   if (n && scall == MAT_REUSE_MATRIX) {
6494     PetscValidPointer(*submat,6);
6495     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6496   }
6497   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6498   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6499   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6500   MatCheckPreallocated(mat,1);
6501 
6502   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6503   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6504   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6505   for (i=0; i<n; i++) {
6506     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6507       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6508       if (eq) {
6509 	if (mat->symmetric){
6510 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6511 	} else if (mat->hermitian) {
6512 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6513 	} else if (mat->structurally_symmetric) {
6514 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6515 	}
6516       }
6517     }
6518   }
6519   PetscFunctionReturn(0);
6520 }
6521 
6522 #undef __FUNCT__
6523 #define __FUNCT__ "MatGetSubMatricesParallel"
6524 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6525 {
6526   PetscErrorCode ierr;
6527   PetscInt        i;
6528   PetscBool       eq;
6529 
6530   PetscFunctionBegin;
6531   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6532   PetscValidType(mat,1);
6533   if (n) {
6534     PetscValidPointer(irow,3);
6535     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6536     PetscValidPointer(icol,4);
6537     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6538   }
6539   PetscValidPointer(submat,6);
6540   if (n && scall == MAT_REUSE_MATRIX) {
6541     PetscValidPointer(*submat,6);
6542     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6543   }
6544   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6545   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6546   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6547   MatCheckPreallocated(mat,1);
6548 
6549   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6550   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6551   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6552   for (i=0; i<n; i++) {
6553     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6554       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6555       if (eq) {
6556 	if (mat->symmetric){
6557 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6558 	} else if (mat->hermitian) {
6559 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6560 	} else if (mat->structurally_symmetric) {
6561 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6562 	}
6563       }
6564     }
6565   }
6566   PetscFunctionReturn(0);
6567 }
6568 
6569 #undef __FUNCT__
6570 #define __FUNCT__ "MatDestroyMatrices"
6571 /*@C
6572    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6573 
6574    Collective on Mat
6575 
6576    Input Parameters:
6577 +  n - the number of local matrices
6578 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6579                        sequence of MatGetSubMatrices())
6580 
6581    Level: advanced
6582 
6583     Notes: Frees not only the matrices, but also the array that contains the matrices
6584            In Fortran will not free the array.
6585 
6586 .seealso: MatGetSubMatrices()
6587 @*/
6588 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6589 {
6590   PetscErrorCode ierr;
6591   PetscInt       i;
6592 
6593   PetscFunctionBegin;
6594   if (!*mat) PetscFunctionReturn(0);
6595   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6596   PetscValidPointer(mat,2);
6597   for (i=0; i<n; i++) {
6598     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6599   }
6600   /* memory is allocated even if n = 0 */
6601   ierr = PetscFree(*mat);CHKERRQ(ierr);
6602   *mat = PETSC_NULL;
6603   PetscFunctionReturn(0);
6604 }
6605 
6606 #undef __FUNCT__
6607 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6608 /*@C
6609    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6610 
6611    Collective on Mat
6612 
6613    Input Parameters:
6614 .  mat - the matrix
6615 
6616    Output Parameter:
6617 .  matstruct - the sequential matrix with the nonzero structure of mat
6618 
6619   Level: intermediate
6620 
6621 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6622 @*/
6623 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6624 {
6625   PetscErrorCode ierr;
6626 
6627   PetscFunctionBegin;
6628   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6629   PetscValidPointer(matstruct,2);
6630 
6631   PetscValidType(mat,1);
6632   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6633   MatCheckPreallocated(mat,1);
6634 
6635   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6636   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6637   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6638   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6639   PetscFunctionReturn(0);
6640 }
6641 
6642 #undef __FUNCT__
6643 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6644 /*@C
6645    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6646 
6647    Collective on Mat
6648 
6649    Input Parameters:
6650 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6651                        sequence of MatGetSequentialNonzeroStructure())
6652 
6653    Level: advanced
6654 
6655     Notes: Frees not only the matrices, but also the array that contains the matrices
6656 
6657 .seealso: MatGetSeqNonzeroStructure()
6658 @*/
6659 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6660 {
6661   PetscErrorCode ierr;
6662 
6663   PetscFunctionBegin;
6664   PetscValidPointer(mat,1);
6665   ierr = MatDestroy(mat);CHKERRQ(ierr);
6666   PetscFunctionReturn(0);
6667 }
6668 
6669 #undef __FUNCT__
6670 #define __FUNCT__ "MatIncreaseOverlap"
6671 /*@
6672    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6673    replaces the index sets by larger ones that represent submatrices with
6674    additional overlap.
6675 
6676    Collective on Mat
6677 
6678    Input Parameters:
6679 +  mat - the matrix
6680 .  n   - the number of index sets
6681 .  is  - the array of index sets (these index sets will changed during the call)
6682 -  ov  - the additional overlap requested
6683 
6684    Level: developer
6685 
6686    Concepts: overlap
6687    Concepts: ASM^computing overlap
6688 
6689 .seealso: MatGetSubMatrices()
6690 @*/
6691 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6692 {
6693   PetscErrorCode ierr;
6694 
6695   PetscFunctionBegin;
6696   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6697   PetscValidType(mat,1);
6698   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6699   if (n) {
6700     PetscValidPointer(is,3);
6701     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6702   }
6703   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6704   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6705   MatCheckPreallocated(mat,1);
6706 
6707   if (!ov) PetscFunctionReturn(0);
6708   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6709   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6710   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6711   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6712   PetscFunctionReturn(0);
6713 }
6714 
6715 #undef __FUNCT__
6716 #define __FUNCT__ "MatGetBlockSize"
6717 /*@
6718    MatGetBlockSize - Returns the matrix block size; useful especially for the
6719    block row and block diagonal formats.
6720 
6721    Not Collective
6722 
6723    Input Parameter:
6724 .  mat - the matrix
6725 
6726    Output Parameter:
6727 .  bs - block size
6728 
6729    Notes:
6730    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6731 
6732    Level: intermediate
6733 
6734    Concepts: matrices^block size
6735 
6736 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ()
6737 @*/
6738 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6739 {
6740 
6741   PetscFunctionBegin;
6742   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6743   PetscValidType(mat,1);
6744   PetscValidIntPointer(bs,2);
6745   MatCheckPreallocated(mat,1);
6746   *bs = mat->rmap->bs;
6747   PetscFunctionReturn(0);
6748 }
6749 
6750 #undef __FUNCT__
6751 #define __FUNCT__ "MatSetBlockSize"
6752 /*@
6753    MatSetBlockSize - Sets the matrix block size.
6754 
6755    Logically Collective on Mat
6756 
6757    Input Parameters:
6758 +  mat - the matrix
6759 -  bs - block size
6760 
6761    Notes:
6762      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6763 
6764    Level: intermediate
6765 
6766    Concepts: matrices^block size
6767 
6768 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6769 @*/
6770 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6771 {
6772   PetscErrorCode ierr;
6773 
6774   PetscFunctionBegin;
6775   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6776   PetscValidLogicalCollectiveInt(mat,bs,2);
6777   ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
6778   ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
6779   PetscFunctionReturn(0);
6780 }
6781 
6782 #undef __FUNCT__
6783 #define __FUNCT__ "MatGetRowIJ"
6784 /*@C
6785     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6786 
6787    Collective on Mat
6788 
6789     Input Parameters:
6790 +   mat - the matrix
6791 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6792 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6793 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6794                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6795                  always used.
6796 
6797     Output Parameters:
6798 +   n - number of rows in the (possibly compressed) matrix
6799 .   ia - the row pointers [of length n+1]
6800 .   ja - the column indices
6801 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6802            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6803 
6804     Level: developer
6805 
6806     Notes: You CANNOT change any of the ia[] or ja[] values.
6807 
6808            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6809 
6810     Fortran Node
6811 
6812            In Fortran use
6813 $           PetscInt ia(1), ja(1)
6814 $           PetscOffset iia, jja
6815 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6816 $
6817 $          or
6818 $
6819 $           PetscScalar, pointer :: xx_v(:)
6820 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6821 
6822 
6823        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6824 
6825 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6826 @*/
6827 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6828 {
6829   PetscErrorCode ierr;
6830 
6831   PetscFunctionBegin;
6832   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6833   PetscValidType(mat,1);
6834   PetscValidIntPointer(n,4);
6835   if (ia) PetscValidIntPointer(ia,5);
6836   if (ja) PetscValidIntPointer(ja,6);
6837   PetscValidIntPointer(done,7);
6838   MatCheckPreallocated(mat,1);
6839   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6840   else {
6841     *done = PETSC_TRUE;
6842     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6843     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6844     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6845   }
6846   PetscFunctionReturn(0);
6847 }
6848 
6849 #undef __FUNCT__
6850 #define __FUNCT__ "MatGetColumnIJ"
6851 /*@C
6852     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6853 
6854     Collective on Mat
6855 
6856     Input Parameters:
6857 +   mat - the matrix
6858 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6859 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6860                 symmetrized
6861 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6862                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6863                  always used.
6864 
6865     Output Parameters:
6866 +   n - number of columns in the (possibly compressed) matrix
6867 .   ia - the column pointers
6868 .   ja - the row indices
6869 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6870 
6871     Level: developer
6872 
6873 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6874 @*/
6875 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6876 {
6877   PetscErrorCode ierr;
6878 
6879   PetscFunctionBegin;
6880   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6881   PetscValidType(mat,1);
6882   PetscValidIntPointer(n,4);
6883   if (ia) PetscValidIntPointer(ia,5);
6884   if (ja) PetscValidIntPointer(ja,6);
6885   PetscValidIntPointer(done,7);
6886   MatCheckPreallocated(mat,1);
6887   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6888   else {
6889     *done = PETSC_TRUE;
6890     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6891   }
6892   PetscFunctionReturn(0);
6893 }
6894 
6895 #undef __FUNCT__
6896 #define __FUNCT__ "MatRestoreRowIJ"
6897 /*@C
6898     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6899     MatGetRowIJ().
6900 
6901     Collective on Mat
6902 
6903     Input Parameters:
6904 +   mat - the matrix
6905 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6906 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6907                 symmetrized
6908 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6909                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6910                  always used.
6911 
6912     Output Parameters:
6913 +   n - size of (possibly compressed) matrix
6914 .   ia - the row pointers
6915 .   ja - the column indices
6916 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6917 
6918     Level: developer
6919 
6920 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6921 @*/
6922 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6923 {
6924   PetscErrorCode ierr;
6925 
6926   PetscFunctionBegin;
6927   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6928   PetscValidType(mat,1);
6929   if (ia) PetscValidIntPointer(ia,5);
6930   if (ja) PetscValidIntPointer(ja,6);
6931   PetscValidIntPointer(done,7);
6932   MatCheckPreallocated(mat,1);
6933 
6934   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6935   else {
6936     *done = PETSC_TRUE;
6937     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6938   }
6939   PetscFunctionReturn(0);
6940 }
6941 
6942 #undef __FUNCT__
6943 #define __FUNCT__ "MatRestoreColumnIJ"
6944 /*@C
6945     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6946     MatGetColumnIJ().
6947 
6948     Collective on Mat
6949 
6950     Input Parameters:
6951 +   mat - the matrix
6952 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6953 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6954                 symmetrized
6955 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6956                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6957                  always used.
6958 
6959     Output Parameters:
6960 +   n - size of (possibly compressed) matrix
6961 .   ia - the column pointers
6962 .   ja - the row indices
6963 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6964 
6965     Level: developer
6966 
6967 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6968 @*/
6969 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6970 {
6971   PetscErrorCode ierr;
6972 
6973   PetscFunctionBegin;
6974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6975   PetscValidType(mat,1);
6976   if (ia) PetscValidIntPointer(ia,5);
6977   if (ja) PetscValidIntPointer(ja,6);
6978   PetscValidIntPointer(done,7);
6979   MatCheckPreallocated(mat,1);
6980 
6981   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6982   else {
6983     *done = PETSC_TRUE;
6984     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6985   }
6986   PetscFunctionReturn(0);
6987 }
6988 
6989 #undef __FUNCT__
6990 #define __FUNCT__ "MatColoringPatch"
6991 /*@C
6992     MatColoringPatch -Used inside matrix coloring routines that
6993     use MatGetRowIJ() and/or MatGetColumnIJ().
6994 
6995     Collective on Mat
6996 
6997     Input Parameters:
6998 +   mat - the matrix
6999 .   ncolors - max color value
7000 .   n   - number of entries in colorarray
7001 -   colorarray - array indicating color for each column
7002 
7003     Output Parameters:
7004 .   iscoloring - coloring generated using colorarray information
7005 
7006     Level: developer
7007 
7008 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7009 
7010 @*/
7011 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7012 {
7013   PetscErrorCode ierr;
7014 
7015   PetscFunctionBegin;
7016   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7017   PetscValidType(mat,1);
7018   PetscValidIntPointer(colorarray,4);
7019   PetscValidPointer(iscoloring,5);
7020   MatCheckPreallocated(mat,1);
7021 
7022   if (!mat->ops->coloringpatch){
7023     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7024   } else {
7025     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7026   }
7027   PetscFunctionReturn(0);
7028 }
7029 
7030 
7031 #undef __FUNCT__
7032 #define __FUNCT__ "MatSetUnfactored"
7033 /*@
7034    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7035 
7036    Logically Collective on Mat
7037 
7038    Input Parameter:
7039 .  mat - the factored matrix to be reset
7040 
7041    Notes:
7042    This routine should be used only with factored matrices formed by in-place
7043    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7044    format).  This option can save memory, for example, when solving nonlinear
7045    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7046    ILU(0) preconditioner.
7047 
7048    Note that one can specify in-place ILU(0) factorization by calling
7049 .vb
7050      PCType(pc,PCILU);
7051      PCFactorSeUseInPlace(pc);
7052 .ve
7053    or by using the options -pc_type ilu -pc_factor_in_place
7054 
7055    In-place factorization ILU(0) can also be used as a local
7056    solver for the blocks within the block Jacobi or additive Schwarz
7057    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7058    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7059    local solver options.
7060 
7061    Most users should employ the simplified KSP interface for linear solvers
7062    instead of working directly with matrix algebra routines such as this.
7063    See, e.g., KSPCreate().
7064 
7065    Level: developer
7066 
7067 .seealso: PCFactorSetUseInPlace()
7068 
7069    Concepts: matrices^unfactored
7070 
7071 @*/
7072 PetscErrorCode  MatSetUnfactored(Mat mat)
7073 {
7074   PetscErrorCode ierr;
7075 
7076   PetscFunctionBegin;
7077   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7078   PetscValidType(mat,1);
7079   MatCheckPreallocated(mat,1);
7080   mat->factortype = MAT_FACTOR_NONE;
7081   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7082   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7083   PetscFunctionReturn(0);
7084 }
7085 
7086 /*MC
7087     MatGetArrayF90 - Accesses a matrix array from Fortran90.
7088 
7089     Synopsis:
7090     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7091 
7092     Not collective
7093 
7094     Input Parameter:
7095 .   x - matrix
7096 
7097     Output Parameters:
7098 +   xx_v - the Fortran90 pointer to the array
7099 -   ierr - error code
7100 
7101     Example of Usage:
7102 .vb
7103       PetscScalar, pointer xx_v(:,:)
7104       ....
7105       call MatGetArrayF90(x,xx_v,ierr)
7106       a = xx_v(3)
7107       call MatRestoreArrayF90(x,xx_v,ierr)
7108 .ve
7109 
7110     Notes:
7111     Not yet supported for all F90 compilers
7112 
7113     Level: advanced
7114 
7115 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
7116 
7117     Concepts: matrices^accessing array
7118 
7119 M*/
7120 
7121 /*MC
7122     MatRestoreArrayF90 - Restores a matrix array that has been
7123     accessed with MatGetArrayF90().
7124 
7125     Synopsis:
7126     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7127 
7128     Not collective
7129 
7130     Input Parameters:
7131 +   x - matrix
7132 -   xx_v - the Fortran90 pointer to the array
7133 
7134     Output Parameter:
7135 .   ierr - error code
7136 
7137     Example of Usage:
7138 .vb
7139        PetscScalar, pointer xx_v(:)
7140        ....
7141        call MatGetArrayF90(x,xx_v,ierr)
7142        a = xx_v(3)
7143        call MatRestoreArrayF90(x,xx_v,ierr)
7144 .ve
7145 
7146     Notes:
7147     Not yet supported for all F90 compilers
7148 
7149     Level: advanced
7150 
7151 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7152 
7153 M*/
7154 
7155 
7156 #undef __FUNCT__
7157 #define __FUNCT__ "MatGetSubMatrix"
7158 /*@
7159     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7160                       as the original matrix.
7161 
7162     Collective on Mat
7163 
7164     Input Parameters:
7165 +   mat - the original matrix
7166 .   isrow - parallel IS containing the rows this processor should obtain
7167 .   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.
7168 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7169 
7170     Output Parameter:
7171 .   newmat - the new submatrix, of the same type as the old
7172 
7173     Level: advanced
7174 
7175     Notes:
7176     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7177 
7178     The rows in isrow will be sorted into the same order as the original matrix on each process.
7179 
7180       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7181    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7182    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7183    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7184    you are finished using it.
7185 
7186     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7187     the input matrix.
7188 
7189     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7190 
7191    Example usage:
7192    Consider the following 8x8 matrix with 34 non-zero values, that is
7193    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7194    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7195    as follows:
7196 
7197 .vb
7198             1  2  0  |  0  3  0  |  0  4
7199     Proc0   0  5  6  |  7  0  0  |  8  0
7200             9  0 10  | 11  0  0  | 12  0
7201     -------------------------------------
7202            13  0 14  | 15 16 17  |  0  0
7203     Proc1   0 18  0  | 19 20 21  |  0  0
7204             0  0  0  | 22 23  0  | 24  0
7205     -------------------------------------
7206     Proc2  25 26 27  |  0  0 28  | 29  0
7207            30  0  0  | 31 32 33  |  0 34
7208 .ve
7209 
7210     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7211 
7212 .vb
7213             2  0  |  0  3  0  |  0
7214     Proc0   5  6  |  7  0  0  |  8
7215     -------------------------------
7216     Proc1  18  0  | 19 20 21  |  0
7217     -------------------------------
7218     Proc2  26 27  |  0  0 28  | 29
7219             0  0  | 31 32 33  |  0
7220 .ve
7221 
7222 
7223     Concepts: matrices^submatrices
7224 
7225 .seealso: MatGetSubMatrices()
7226 @*/
7227 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7228 {
7229   PetscErrorCode ierr;
7230   PetscMPIInt    size;
7231   Mat            *local;
7232   IS             iscoltmp;
7233 
7234   PetscFunctionBegin;
7235   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7236   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7237   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7238   PetscValidPointer(newmat,5);
7239   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7240   PetscValidType(mat,1);
7241   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7242   MatCheckPreallocated(mat,1);
7243   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7244 
7245   if (!iscol) {
7246     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7247   } else {
7248     iscoltmp = iscol;
7249   }
7250 
7251   /* if original matrix is on just one processor then use submatrix generated */
7252   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7253     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7254     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7255     PetscFunctionReturn(0);
7256   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7257     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7258     *newmat = *local;
7259     ierr    = PetscFree(local);CHKERRQ(ierr);
7260     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7261     PetscFunctionReturn(0);
7262   } else if (!mat->ops->getsubmatrix) {
7263     /* Create a new matrix type that implements the operation using the full matrix */
7264     switch (cll) {
7265       case MAT_INITIAL_MATRIX:
7266         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7267         break;
7268       case MAT_REUSE_MATRIX:
7269         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7270         break;
7271       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7272     }
7273     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7274     PetscFunctionReturn(0);
7275   }
7276 
7277   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7278   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7279   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7280   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7281   PetscFunctionReturn(0);
7282 }
7283 
7284 #undef __FUNCT__
7285 #define __FUNCT__ "MatStashSetInitialSize"
7286 /*@
7287    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7288    used during the assembly process to store values that belong to
7289    other processors.
7290 
7291    Not Collective
7292 
7293    Input Parameters:
7294 +  mat   - the matrix
7295 .  size  - the initial size of the stash.
7296 -  bsize - the initial size of the block-stash(if used).
7297 
7298    Options Database Keys:
7299 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7300 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7301 
7302    Level: intermediate
7303 
7304    Notes:
7305      The block-stash is used for values set with MatSetValuesBlocked() while
7306      the stash is used for values set with MatSetValues()
7307 
7308      Run with the option -info and look for output of the form
7309      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7310      to determine the appropriate value, MM, to use for size and
7311      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7312      to determine the value, BMM to use for bsize
7313 
7314    Concepts: stash^setting matrix size
7315    Concepts: matrices^stash
7316 
7317 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7318 
7319 @*/
7320 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7321 {
7322   PetscErrorCode ierr;
7323 
7324   PetscFunctionBegin;
7325   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7326   PetscValidType(mat,1);
7327   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7328   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7329   PetscFunctionReturn(0);
7330 }
7331 
7332 #undef __FUNCT__
7333 #define __FUNCT__ "MatInterpolateAdd"
7334 /*@
7335    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7336      the matrix
7337 
7338    Neighbor-wise Collective on Mat
7339 
7340    Input Parameters:
7341 +  mat   - the matrix
7342 .  x,y - the vectors
7343 -  w - where the result is stored
7344 
7345    Level: intermediate
7346 
7347    Notes:
7348     w may be the same vector as y.
7349 
7350     This allows one to use either the restriction or interpolation (its transpose)
7351     matrix to do the interpolation
7352 
7353     Concepts: interpolation
7354 
7355 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7356 
7357 @*/
7358 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7359 {
7360   PetscErrorCode ierr;
7361   PetscInt       M,N,Ny;
7362 
7363   PetscFunctionBegin;
7364   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7365   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7366   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7367   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7368   PetscValidType(A,1);
7369   MatCheckPreallocated(A,1);
7370   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7371   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7372   if (M == Ny) {
7373     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7374   } else {
7375     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7376   }
7377   PetscFunctionReturn(0);
7378 }
7379 
7380 #undef __FUNCT__
7381 #define __FUNCT__ "MatInterpolate"
7382 /*@
7383    MatInterpolate - y = A*x or A'*x depending on the shape of
7384      the matrix
7385 
7386    Neighbor-wise Collective on Mat
7387 
7388    Input Parameters:
7389 +  mat   - the matrix
7390 -  x,y - the vectors
7391 
7392    Level: intermediate
7393 
7394    Notes:
7395     This allows one to use either the restriction or interpolation (its transpose)
7396     matrix to do the interpolation
7397 
7398    Concepts: matrices^interpolation
7399 
7400 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7401 
7402 @*/
7403 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7404 {
7405   PetscErrorCode ierr;
7406   PetscInt       M,N,Ny;
7407 
7408   PetscFunctionBegin;
7409   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7410   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7411   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7412   PetscValidType(A,1);
7413   MatCheckPreallocated(A,1);
7414   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7415   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7416   if (M == Ny) {
7417     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7418   } else {
7419     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7420   }
7421   PetscFunctionReturn(0);
7422 }
7423 
7424 #undef __FUNCT__
7425 #define __FUNCT__ "MatRestrict"
7426 /*@
7427    MatRestrict - y = A*x or A'*x
7428 
7429    Neighbor-wise Collective on Mat
7430 
7431    Input Parameters:
7432 +  mat   - the matrix
7433 -  x,y - the vectors
7434 
7435    Level: intermediate
7436 
7437    Notes:
7438     This allows one to use either the restriction or interpolation (its transpose)
7439     matrix to do the restriction
7440 
7441    Concepts: matrices^restriction
7442 
7443 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7444 
7445 @*/
7446 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7447 {
7448   PetscErrorCode ierr;
7449   PetscInt       M,N,Ny;
7450 
7451   PetscFunctionBegin;
7452   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7453   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7454   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7455   PetscValidType(A,1);
7456   MatCheckPreallocated(A,1);
7457 
7458   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7459   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7460   if (M == Ny) {
7461     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7462   } else {
7463     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7464   }
7465   PetscFunctionReturn(0);
7466 }
7467 
7468 #undef __FUNCT__
7469 #define __FUNCT__ "MatGetNullSpace"
7470 /*@
7471    MatGetNullSpace - retrieves the null space to a matrix.
7472 
7473    Logically Collective on Mat and MatNullSpace
7474 
7475    Input Parameters:
7476 +  mat - the matrix
7477 -  nullsp - the null space object
7478 
7479    Level: developer
7480 
7481    Notes:
7482       This null space is used by solvers. Overwrites any previous null space that may have been attached
7483 
7484    Concepts: null space^attaching to matrix
7485 
7486 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7487 @*/
7488 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7489 {
7490   PetscFunctionBegin;
7491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7492   PetscValidType(mat,1);
7493   PetscValidPointer(nullsp,2);
7494   *nullsp = mat->nullsp;
7495   PetscFunctionReturn(0);
7496 }
7497 
7498 #undef __FUNCT__
7499 #define __FUNCT__ "MatSetNullSpace"
7500 /*@
7501    MatSetNullSpace - attaches a null space to a matrix.
7502         This null space will be removed from the resulting vector whenever
7503         MatMult() is called
7504 
7505    Logically Collective on Mat and MatNullSpace
7506 
7507    Input Parameters:
7508 +  mat - the matrix
7509 -  nullsp - the null space object
7510 
7511    Level: advanced
7512 
7513    Notes:
7514       This null space is used by solvers. Overwrites any previous null space that may have been attached
7515 
7516    Concepts: null space^attaching to matrix
7517 
7518 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7519 @*/
7520 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7521 {
7522   PetscErrorCode ierr;
7523 
7524   PetscFunctionBegin;
7525   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7526   PetscValidType(mat,1);
7527   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7528   MatCheckPreallocated(mat,1);
7529   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7530   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
7531   mat->nullsp = nullsp;
7532   PetscFunctionReturn(0);
7533 }
7534 
7535 #undef __FUNCT__
7536 #define __FUNCT__ "MatSetNearNullSpace"
7537 /*@
7538    MatSetNearNullSpace - attaches a null space to a matrix.
7539         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7540 
7541    Logically Collective on Mat and MatNullSpace
7542 
7543    Input Parameters:
7544 +  mat - the matrix
7545 -  nullsp - the null space object
7546 
7547    Level: advanced
7548 
7549    Notes:
7550       Overwrites any previous near null space that may have been attached
7551 
7552    Concepts: null space^attaching to matrix
7553 
7554 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7555 @*/
7556 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7557 {
7558   PetscErrorCode ierr;
7559 
7560   PetscFunctionBegin;
7561   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7562   PetscValidType(mat,1);
7563   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7564   MatCheckPreallocated(mat,1);
7565   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7566   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
7567   mat->nearnullsp = nullsp;
7568   PetscFunctionReturn(0);
7569 }
7570 
7571 #undef __FUNCT__
7572 #define __FUNCT__ "MatGetNearNullSpace"
7573 /*@
7574    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7575 
7576    Not Collective
7577 
7578    Input Parameters:
7579 .  mat - the matrix
7580 
7581    Output Parameters:
7582 .  nullsp - the null space object, PETSC_NULL if not set
7583 
7584    Level: developer
7585 
7586    Concepts: null space^attaching to matrix
7587 
7588 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7589 @*/
7590 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7591 {
7592 
7593   PetscFunctionBegin;
7594   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7595   PetscValidType(mat,1);
7596   PetscValidPointer(nullsp,2);
7597   MatCheckPreallocated(mat,1);
7598   *nullsp = mat->nearnullsp;
7599   PetscFunctionReturn(0);
7600 }
7601 
7602 #undef __FUNCT__
7603 #define __FUNCT__ "MatICCFactor"
7604 /*@C
7605    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7606 
7607    Collective on Mat
7608 
7609    Input Parameters:
7610 +  mat - the matrix
7611 .  row - row/column permutation
7612 .  fill - expected fill factor >= 1.0
7613 -  level - level of fill, for ICC(k)
7614 
7615    Notes:
7616    Probably really in-place only when level of fill is zero, otherwise allocates
7617    new space to store factored matrix and deletes previous memory.
7618 
7619    Most users should employ the simplified KSP interface for linear solvers
7620    instead of working directly with matrix algebra routines such as this.
7621    See, e.g., KSPCreate().
7622 
7623    Level: developer
7624 
7625    Concepts: matrices^incomplete Cholesky factorization
7626    Concepts: Cholesky factorization
7627 
7628 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7629 
7630     Developer Note: fortran interface is not autogenerated as the f90
7631     interface defintion cannot be generated correctly [due to MatFactorInfo]
7632 
7633 @*/
7634 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7635 {
7636   PetscErrorCode ierr;
7637 
7638   PetscFunctionBegin;
7639   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7640   PetscValidType(mat,1);
7641   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7642   PetscValidPointer(info,3);
7643   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7644   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7645   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7646   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7647   MatCheckPreallocated(mat,1);
7648   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7649   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7650   PetscFunctionReturn(0);
7651 }
7652 
7653 #undef __FUNCT__
7654 #define __FUNCT__ "MatSetValuesAdic"
7655 /*@
7656    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7657 
7658    Not Collective
7659 
7660    Input Parameters:
7661 +  mat - the matrix
7662 -  v - the values compute with ADIC
7663 
7664    Level: developer
7665 
7666    Notes:
7667      Must call MatSetColoring() before using this routine. Also this matrix must already
7668      have its nonzero pattern determined.
7669 
7670 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7671           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7672 @*/
7673 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7674 {
7675   PetscErrorCode ierr;
7676 
7677   PetscFunctionBegin;
7678   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7679   PetscValidType(mat,1);
7680   PetscValidPointer(mat,2);
7681 
7682   if (!mat->assembled) {
7683     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7684   }
7685   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7686   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7687   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7688   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7689   ierr = MatView_Private(mat);CHKERRQ(ierr);
7690   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7691   PetscFunctionReturn(0);
7692 }
7693 
7694 
7695 #undef __FUNCT__
7696 #define __FUNCT__ "MatSetColoring"
7697 /*@
7698    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7699 
7700    Not Collective
7701 
7702    Input Parameters:
7703 +  mat - the matrix
7704 -  coloring - the coloring
7705 
7706    Level: developer
7707 
7708 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7709           MatSetValues(), MatSetValuesAdic()
7710 @*/
7711 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7712 {
7713   PetscErrorCode ierr;
7714 
7715   PetscFunctionBegin;
7716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7717   PetscValidType(mat,1);
7718   PetscValidPointer(coloring,2);
7719 
7720   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7721   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7722   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7723   PetscFunctionReturn(0);
7724 }
7725 
7726 #undef __FUNCT__
7727 #define __FUNCT__ "MatSetValuesAdifor"
7728 /*@
7729    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7730 
7731    Not Collective
7732 
7733    Input Parameters:
7734 +  mat - the matrix
7735 .  nl - leading dimension of v
7736 -  v - the values compute with ADIFOR
7737 
7738    Level: developer
7739 
7740    Notes:
7741      Must call MatSetColoring() before using this routine. Also this matrix must already
7742      have its nonzero pattern determined.
7743 
7744 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7745           MatSetValues(), MatSetColoring()
7746 @*/
7747 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7748 {
7749   PetscErrorCode ierr;
7750 
7751   PetscFunctionBegin;
7752   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7753   PetscValidType(mat,1);
7754   PetscValidPointer(v,3);
7755 
7756   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7757   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7758   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7759   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7760   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7761   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7762   PetscFunctionReturn(0);
7763 }
7764 
7765 #undef __FUNCT__
7766 #define __FUNCT__ "MatDiagonalScaleLocal"
7767 /*@
7768    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7769          ghosted ones.
7770 
7771    Not Collective
7772 
7773    Input Parameters:
7774 +  mat - the matrix
7775 -  diag = the diagonal values, including ghost ones
7776 
7777    Level: developer
7778 
7779    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7780 
7781 .seealso: MatDiagonalScale()
7782 @*/
7783 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7784 {
7785   PetscErrorCode ierr;
7786   PetscMPIInt    size;
7787 
7788   PetscFunctionBegin;
7789   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7790   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7791   PetscValidType(mat,1);
7792 
7793   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7794   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7795   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7796   if (size == 1) {
7797     PetscInt n,m;
7798     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7799     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7800     if (m == n) {
7801       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7802     } else {
7803       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7804     }
7805   } else {
7806     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7807   }
7808   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7809   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7810   PetscFunctionReturn(0);
7811 }
7812 
7813 #undef __FUNCT__
7814 #define __FUNCT__ "MatGetInertia"
7815 /*@
7816    MatGetInertia - Gets the inertia from a factored matrix
7817 
7818    Collective on Mat
7819 
7820    Input Parameter:
7821 .  mat - the matrix
7822 
7823    Output Parameters:
7824 +   nneg - number of negative eigenvalues
7825 .   nzero - number of zero eigenvalues
7826 -   npos - number of positive eigenvalues
7827 
7828    Level: advanced
7829 
7830    Notes: Matrix must have been factored by MatCholeskyFactor()
7831 
7832 
7833 @*/
7834 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7835 {
7836   PetscErrorCode ierr;
7837 
7838   PetscFunctionBegin;
7839   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7840   PetscValidType(mat,1);
7841   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7842   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7843   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7844   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7845   PetscFunctionReturn(0);
7846 }
7847 
7848 /* ----------------------------------------------------------------*/
7849 #undef __FUNCT__
7850 #define __FUNCT__ "MatSolves"
7851 /*@C
7852    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7853 
7854    Neighbor-wise Collective on Mat and Vecs
7855 
7856    Input Parameters:
7857 +  mat - the factored matrix
7858 -  b - the right-hand-side vectors
7859 
7860    Output Parameter:
7861 .  x - the result vectors
7862 
7863    Notes:
7864    The vectors b and x cannot be the same.  I.e., one cannot
7865    call MatSolves(A,x,x).
7866 
7867    Notes:
7868    Most users should employ the simplified KSP interface for linear solvers
7869    instead of working directly with matrix algebra routines such as this.
7870    See, e.g., KSPCreate().
7871 
7872    Level: developer
7873 
7874    Concepts: matrices^triangular solves
7875 
7876 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7877 @*/
7878 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7879 {
7880   PetscErrorCode ierr;
7881 
7882   PetscFunctionBegin;
7883   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7884   PetscValidType(mat,1);
7885   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7886   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7887   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7888 
7889   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7890   MatCheckPreallocated(mat,1);
7891   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7892   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7893   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7894   PetscFunctionReturn(0);
7895 }
7896 
7897 #undef __FUNCT__
7898 #define __FUNCT__ "MatIsSymmetric"
7899 /*@
7900    MatIsSymmetric - Test whether a matrix is symmetric
7901 
7902    Collective on Mat
7903 
7904    Input Parameter:
7905 +  A - the matrix to test
7906 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7907 
7908    Output Parameters:
7909 .  flg - the result
7910 
7911    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7912 
7913    Level: intermediate
7914 
7915    Concepts: matrix^symmetry
7916 
7917 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7918 @*/
7919 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7920 {
7921   PetscErrorCode ierr;
7922 
7923   PetscFunctionBegin;
7924   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7925   PetscValidPointer(flg,2);
7926 
7927   if (!A->symmetric_set) {
7928     if (!A->ops->issymmetric) {
7929       const MatType mattype;
7930       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7931       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7932     }
7933     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7934     if (!tol) {
7935       A->symmetric_set = PETSC_TRUE;
7936       A->symmetric = *flg;
7937       if (A->symmetric) {
7938 	A->structurally_symmetric_set = PETSC_TRUE;
7939 	A->structurally_symmetric     = PETSC_TRUE;
7940       }
7941     }
7942   } else if (A->symmetric) {
7943     *flg = PETSC_TRUE;
7944   } else if (!tol) {
7945     *flg = PETSC_FALSE;
7946   } else {
7947     if (!A->ops->issymmetric) {
7948       const MatType mattype;
7949       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7950       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7951     }
7952     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7953   }
7954   PetscFunctionReturn(0);
7955 }
7956 
7957 #undef __FUNCT__
7958 #define __FUNCT__ "MatIsHermitian"
7959 /*@
7960    MatIsHermitian - Test whether a matrix is Hermitian
7961 
7962    Collective on Mat
7963 
7964    Input Parameter:
7965 +  A - the matrix to test
7966 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7967 
7968    Output Parameters:
7969 .  flg - the result
7970 
7971    Level: intermediate
7972 
7973    Concepts: matrix^symmetry
7974 
7975 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7976           MatIsSymmetricKnown(), MatIsSymmetric()
7977 @*/
7978 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7979 {
7980   PetscErrorCode ierr;
7981 
7982   PetscFunctionBegin;
7983   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7984   PetscValidPointer(flg,2);
7985 
7986   if (!A->hermitian_set) {
7987     if (!A->ops->ishermitian) {
7988       const MatType mattype;
7989       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7990       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7991     }
7992     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7993     if (!tol) {
7994       A->hermitian_set = PETSC_TRUE;
7995       A->hermitian = *flg;
7996       if (A->hermitian) {
7997 	A->structurally_symmetric_set = PETSC_TRUE;
7998 	A->structurally_symmetric     = PETSC_TRUE;
7999       }
8000     }
8001   } else if (A->hermitian) {
8002     *flg = PETSC_TRUE;
8003   } else if (!tol) {
8004     *flg = PETSC_FALSE;
8005   } else {
8006     if (!A->ops->ishermitian) {
8007       const MatType mattype;
8008       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8009       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8010     }
8011     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8012   }
8013   PetscFunctionReturn(0);
8014 }
8015 
8016 #undef __FUNCT__
8017 #define __FUNCT__ "MatIsSymmetricKnown"
8018 /*@
8019    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8020 
8021    Not Collective
8022 
8023    Input Parameter:
8024 .  A - the matrix to check
8025 
8026    Output Parameters:
8027 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8028 -  flg - the result
8029 
8030    Level: advanced
8031 
8032    Concepts: matrix^symmetry
8033 
8034    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8035          if you want it explicitly checked
8036 
8037 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8038 @*/
8039 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8040 {
8041   PetscFunctionBegin;
8042   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8043   PetscValidPointer(set,2);
8044   PetscValidPointer(flg,3);
8045   if (A->symmetric_set) {
8046     *set = PETSC_TRUE;
8047     *flg = A->symmetric;
8048   } else {
8049     *set = PETSC_FALSE;
8050   }
8051   PetscFunctionReturn(0);
8052 }
8053 
8054 #undef __FUNCT__
8055 #define __FUNCT__ "MatIsHermitianKnown"
8056 /*@
8057    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8058 
8059    Not Collective
8060 
8061    Input Parameter:
8062 .  A - the matrix to check
8063 
8064    Output Parameters:
8065 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8066 -  flg - the result
8067 
8068    Level: advanced
8069 
8070    Concepts: matrix^symmetry
8071 
8072    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8073          if you want it explicitly checked
8074 
8075 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8076 @*/
8077 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8078 {
8079   PetscFunctionBegin;
8080   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8081   PetscValidPointer(set,2);
8082   PetscValidPointer(flg,3);
8083   if (A->hermitian_set) {
8084     *set = PETSC_TRUE;
8085     *flg = A->hermitian;
8086   } else {
8087     *set = PETSC_FALSE;
8088   }
8089   PetscFunctionReturn(0);
8090 }
8091 
8092 #undef __FUNCT__
8093 #define __FUNCT__ "MatIsStructurallySymmetric"
8094 /*@
8095    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8096 
8097    Collective on Mat
8098 
8099    Input Parameter:
8100 .  A - the matrix to test
8101 
8102    Output Parameters:
8103 .  flg - the result
8104 
8105    Level: intermediate
8106 
8107    Concepts: matrix^symmetry
8108 
8109 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8110 @*/
8111 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8112 {
8113   PetscErrorCode ierr;
8114 
8115   PetscFunctionBegin;
8116   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8117   PetscValidPointer(flg,2);
8118   if (!A->structurally_symmetric_set) {
8119     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8120     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8121     A->structurally_symmetric_set = PETSC_TRUE;
8122   }
8123   *flg = A->structurally_symmetric;
8124   PetscFunctionReturn(0);
8125 }
8126 
8127 #undef __FUNCT__
8128 #define __FUNCT__ "MatStashGetInfo"
8129 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8130 /*@
8131    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8132        to be communicated to other processors during the MatAssemblyBegin/End() process
8133 
8134     Not collective
8135 
8136    Input Parameter:
8137 .   vec - the vector
8138 
8139    Output Parameters:
8140 +   nstash   - the size of the stash
8141 .   reallocs - the number of additional mallocs incurred.
8142 .   bnstash   - the size of the block stash
8143 -   breallocs - the number of additional mallocs incurred.in the block stash
8144 
8145    Level: advanced
8146 
8147 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8148 
8149 @*/
8150 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8151 {
8152   PetscErrorCode ierr;
8153   PetscFunctionBegin;
8154   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8155   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8156   PetscFunctionReturn(0);
8157 }
8158 
8159 #undef __FUNCT__
8160 #define __FUNCT__ "MatGetVecs"
8161 /*@C
8162    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8163      parallel layout
8164 
8165    Collective on Mat
8166 
8167    Input Parameter:
8168 .  mat - the matrix
8169 
8170    Output Parameter:
8171 +   right - (optional) vector that the matrix can be multiplied against
8172 -   left - (optional) vector that the matrix vector product can be stored in
8173 
8174   Level: advanced
8175 
8176 .seealso: MatCreate()
8177 @*/
8178 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8179 {
8180   PetscErrorCode ierr;
8181 
8182   PetscFunctionBegin;
8183   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8184   PetscValidType(mat,1);
8185   MatCheckPreallocated(mat,1);
8186   if (mat->ops->getvecs) {
8187     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8188   } else {
8189     PetscMPIInt size;
8190     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
8191     if (right) {
8192       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
8193       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8194       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
8195       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8196       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8197     }
8198     if (left) {
8199       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
8200       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8201       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
8202       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8203       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8204     }
8205   }
8206   PetscFunctionReturn(0);
8207 }
8208 
8209 #undef __FUNCT__
8210 #define __FUNCT__ "MatFactorInfoInitialize"
8211 /*@C
8212    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8213      with default values.
8214 
8215    Not Collective
8216 
8217    Input Parameters:
8218 .    info - the MatFactorInfo data structure
8219 
8220 
8221    Notes: The solvers are generally used through the KSP and PC objects, for example
8222           PCLU, PCILU, PCCHOLESKY, PCICC
8223 
8224    Level: developer
8225 
8226 .seealso: MatFactorInfo
8227 
8228     Developer Note: fortran interface is not autogenerated as the f90
8229     interface defintion cannot be generated correctly [due to MatFactorInfo]
8230 
8231 @*/
8232 
8233 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8234 {
8235   PetscErrorCode ierr;
8236 
8237   PetscFunctionBegin;
8238   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8239   PetscFunctionReturn(0);
8240 }
8241 
8242 #undef __FUNCT__
8243 #define __FUNCT__ "MatPtAP"
8244 /*@
8245    MatPtAP - Creates the matrix product C = P^T * A * P
8246 
8247    Neighbor-wise Collective on Mat
8248 
8249    Input Parameters:
8250 +  A - the matrix
8251 .  P - the projection matrix
8252 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8253 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8254 
8255    Output Parameters:
8256 .  C - the product matrix
8257 
8258    Notes:
8259    C will be created and must be destroyed by the user with MatDestroy().
8260 
8261    This routine is currently only implemented for pairs of AIJ matrices and classes
8262    which inherit from AIJ.
8263 
8264    Level: intermediate
8265 
8266 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8267 @*/
8268 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8269 {
8270   PetscErrorCode ierr;
8271 
8272   PetscFunctionBegin;
8273   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8274   PetscValidType(A,1);
8275   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8276   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8277   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8278   PetscValidType(P,2);
8279   MatCheckPreallocated(P,2);
8280   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8281   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8282   PetscValidPointer(C,3);
8283   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);
8284   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8285   MatCheckPreallocated(A,1);
8286 
8287   if (!A->ops->ptap) {
8288     const MatType mattype;
8289     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8290     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8291   }
8292   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8293   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8294   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8295   PetscFunctionReturn(0);
8296 }
8297 
8298 #undef __FUNCT__
8299 #define __FUNCT__ "MatPtAPNumeric"
8300 /*@
8301    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8302 
8303    Neighbor-wise Collective on Mat
8304 
8305    Input Parameters:
8306 +  A - the matrix
8307 -  P - the projection matrix
8308 
8309    Output Parameters:
8310 .  C - the product matrix
8311 
8312    Notes:
8313    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8314    the user using MatDeatroy().
8315 
8316    This routine is currently only implemented for pairs of AIJ matrices and classes
8317    which inherit from AIJ.  C will be of type MATAIJ.
8318 
8319    Level: intermediate
8320 
8321 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8322 @*/
8323 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8324 {
8325   PetscErrorCode ierr;
8326 
8327   PetscFunctionBegin;
8328   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8329   PetscValidType(A,1);
8330   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8331   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8332   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8333   PetscValidType(P,2);
8334   MatCheckPreallocated(P,2);
8335   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8336   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8337   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8338   PetscValidType(C,3);
8339   MatCheckPreallocated(C,3);
8340   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8341   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);
8342   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);
8343   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);
8344   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);
8345   MatCheckPreallocated(A,1);
8346 
8347   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8348   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8349   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8350   PetscFunctionReturn(0);
8351 }
8352 
8353 #undef __FUNCT__
8354 #define __FUNCT__ "MatPtAPSymbolic"
8355 /*@
8356    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8357 
8358    Neighbor-wise Collective on Mat
8359 
8360    Input Parameters:
8361 +  A - the matrix
8362 -  P - the projection matrix
8363 
8364    Output Parameters:
8365 .  C - the (i,j) structure of the product matrix
8366 
8367    Notes:
8368    C will be created and must be destroyed by the user with MatDestroy().
8369 
8370    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8371    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8372    this (i,j) structure by calling MatPtAPNumeric().
8373 
8374    Level: intermediate
8375 
8376 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8377 @*/
8378 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8379 {
8380   PetscErrorCode ierr;
8381 
8382   PetscFunctionBegin;
8383   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8384   PetscValidType(A,1);
8385   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8386   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8387   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8388   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8389   PetscValidType(P,2);
8390   MatCheckPreallocated(P,2);
8391   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8392   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8393   PetscValidPointer(C,3);
8394 
8395   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);
8396   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);
8397   MatCheckPreallocated(A,1);
8398   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8399   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8400   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8401 
8402   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
8403 
8404   PetscFunctionReturn(0);
8405 }
8406 
8407 #undef __FUNCT__
8408 #define __FUNCT__ "MatRARt"
8409 /*@
8410    MatRARt - Creates the matrix product C = R * A * R^T
8411 
8412    Neighbor-wise Collective on Mat
8413 
8414    Input Parameters:
8415 +  A - the matrix
8416 .  R - the projection matrix
8417 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8418 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8419 
8420    Output Parameters:
8421 .  C - the product matrix
8422 
8423    Notes:
8424    C will be created and must be destroyed by the user with MatDestroy().
8425 
8426    This routine is currently only implemented for pairs of AIJ matrices and classes
8427    which inherit from AIJ.
8428 
8429    Level: intermediate
8430 
8431 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8432 @*/
8433 PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8434 {
8435   PetscErrorCode ierr;
8436 
8437   PetscFunctionBegin;
8438   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8439   PetscValidType(A,1);
8440   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8441   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8442   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8443   PetscValidType(R,2);
8444   MatCheckPreallocated(R,2);
8445   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8446   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8447   PetscValidPointer(C,3);
8448   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);
8449   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8450   MatCheckPreallocated(A,1);
8451 
8452   if (!A->ops->rart) {
8453     const MatType mattype;
8454     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8455     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8456   }
8457   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8458   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
8459   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8460   PetscFunctionReturn(0);
8461 }
8462 
8463 #undef __FUNCT__
8464 #define __FUNCT__ "MatRARtNumeric"
8465 /*@
8466    MatRARtNumeric - Computes the matrix product C = R * A * R^T
8467 
8468    Neighbor-wise Collective on Mat
8469 
8470    Input Parameters:
8471 +  A - the matrix
8472 -  R - the projection matrix
8473 
8474    Output Parameters:
8475 .  C - the product matrix
8476 
8477    Notes:
8478    C must have been created by calling MatRARtSymbolic and must be destroyed by
8479    the user using MatDeatroy().
8480 
8481    This routine is currently only implemented for pairs of AIJ matrices and classes
8482    which inherit from AIJ.  C will be of type MATAIJ.
8483 
8484    Level: intermediate
8485 
8486 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8487 @*/
8488 PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8489 {
8490   PetscErrorCode ierr;
8491 
8492   PetscFunctionBegin;
8493   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8494   PetscValidType(A,1);
8495   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8496   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8497   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8498   PetscValidType(R,2);
8499   MatCheckPreallocated(R,2);
8500   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8501   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8502   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8503   PetscValidType(C,3);
8504   MatCheckPreallocated(C,3);
8505   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8506   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);
8507   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);
8508   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);
8509   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);
8510   MatCheckPreallocated(A,1);
8511 
8512   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8513   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
8514   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8515   PetscFunctionReturn(0);
8516 }
8517 
8518 #undef __FUNCT__
8519 #define __FUNCT__ "MatRARtSymbolic"
8520 /*@
8521    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8522 
8523    Neighbor-wise Collective on Mat
8524 
8525    Input Parameters:
8526 +  A - the matrix
8527 -  R - the projection matrix
8528 
8529    Output Parameters:
8530 .  C - the (i,j) structure of the product matrix
8531 
8532    Notes:
8533    C will be created and must be destroyed by the user with MatDestroy().
8534 
8535    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8536    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8537    this (i,j) structure by calling MatRARtNumeric().
8538 
8539    Level: intermediate
8540 
8541 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8542 @*/
8543 PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8544 {
8545   PetscErrorCode ierr;
8546 
8547   PetscFunctionBegin;
8548   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8549   PetscValidType(A,1);
8550   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8551   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8552   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8553   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8554   PetscValidType(R,2);
8555   MatCheckPreallocated(R,2);
8556   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8557   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8558   PetscValidPointer(C,3);
8559 
8560   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);
8561   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);
8562   MatCheckPreallocated(A,1);
8563   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8564   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
8565   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8566 
8567   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8568   PetscFunctionReturn(0);
8569 }
8570 
8571 extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);
8572 
8573 #undef __FUNCT__
8574 #define __FUNCT__ "MatMatMult"
8575 /*@
8576    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8577 
8578    Neighbor-wise Collective on Mat
8579 
8580    Input Parameters:
8581 +  A - the left matrix
8582 .  B - the right matrix
8583 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8584 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8585           if the result is a dense matrix this is irrelevent
8586 
8587    Output Parameters:
8588 .  C - the product matrix
8589 
8590    Notes:
8591    Unless scall is MAT_REUSE_MATRIX C will be created.
8592 
8593    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8594 
8595    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8596    actually needed.
8597 
8598    If you have many matrices with the same non-zero structure to multiply, you
8599    should either
8600 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8601 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8602 
8603    Level: intermediate
8604 
8605 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8606 @*/
8607 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8608 {
8609   PetscErrorCode ierr;
8610   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8611   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8612   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8613 
8614   PetscFunctionBegin;
8615   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8616   PetscValidType(A,1);
8617   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8618   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8619   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8620   PetscValidType(B,2);
8621   MatCheckPreallocated(B,2);
8622   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8623   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8624   PetscValidPointer(C,3);
8625   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);
8626   if (scall == MAT_REUSE_MATRIX){
8627     PetscValidPointer(*C,5);
8628     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8629     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8630     ierr = (*(*C)->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8631     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8632   }
8633   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8634   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8635   MatCheckPreallocated(A,1);
8636 
8637   fA = A->ops->matmult;
8638   fB = B->ops->matmult;
8639   if (fB == fA) {
8640     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8641     mult = fB;
8642   } else {
8643     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8644     char  multname[256];
8645     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8646     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8647     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8648     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8649     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8650     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8651     if(!mult){
8652       /* dual dispatch using MatQueryOp */
8653       ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8654       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);
8655     }
8656   }
8657   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8658   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8659   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8660   PetscFunctionReturn(0);
8661 }
8662 
8663 #undef __FUNCT__
8664 #define __FUNCT__ "MatMatMultSymbolic"
8665 /*@
8666    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8667    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8668 
8669    Neighbor-wise Collective on Mat
8670 
8671    Input Parameters:
8672 +  A - the left matrix
8673 .  B - the right matrix
8674 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8675       if C is a dense matrix this is irrelevent
8676 
8677    Output Parameters:
8678 .  C - the product matrix
8679 
8680    Notes:
8681    Unless scall is MAT_REUSE_MATRIX C will be created.
8682 
8683    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8684    actually needed.
8685 
8686    This routine is currently implemented for
8687     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8688     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8689     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8690 
8691    Level: intermediate
8692 
8693    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8694      We should incorporate them into PETSc.
8695 
8696 .seealso: MatMatMult(), MatMatMultNumeric()
8697 @*/
8698 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8699 {
8700   PetscErrorCode ierr;
8701   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8702   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8703   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8704 
8705   PetscFunctionBegin;
8706   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8707   PetscValidType(A,1);
8708   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8709   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8710 
8711   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8712   PetscValidType(B,2);
8713   MatCheckPreallocated(B,2);
8714   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8715   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8716   PetscValidPointer(C,3);
8717 
8718   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);
8719   if (fill == PETSC_DEFAULT) fill = 2.0;
8720   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8721   MatCheckPreallocated(A,1);
8722 
8723   Asymbolic = A->ops->matmultsymbolic;
8724   Bsymbolic = B->ops->matmultsymbolic;
8725   if (Asymbolic == Bsymbolic){
8726     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8727     symbolic = Bsymbolic;
8728   } else { /* dispatch based on the type of A and B */
8729     char  symbolicname[256];
8730     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8731     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8732     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8733     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8734     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8735     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8736     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);
8737   }
8738   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8739   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8740   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8741   PetscFunctionReturn(0);
8742 }
8743 
8744 #undef __FUNCT__
8745 #define __FUNCT__ "MatMatMultNumeric"
8746 /*@
8747    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8748    Call this routine after first calling MatMatMultSymbolic().
8749 
8750    Neighbor-wise Collective on Mat
8751 
8752    Input Parameters:
8753 +  A - the left matrix
8754 -  B - the right matrix
8755 
8756    Output Parameters:
8757 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8758 
8759    Notes:
8760    C must have been created with MatMatMultSymbolic().
8761 
8762    This routine is currently implemented for
8763     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8764     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8765     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8766 
8767    Level: intermediate
8768 
8769 .seealso: MatMatMult(), MatMatMultSymbolic()
8770 @*/
8771 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8772 {
8773   PetscErrorCode ierr;
8774   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8775   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8776   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8777 
8778   PetscFunctionBegin;
8779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8780   PetscValidType(A,1);
8781   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8782   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8783 
8784   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8785   PetscValidType(B,2);
8786   MatCheckPreallocated(B,2);
8787   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8788   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8789 
8790   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8791   PetscValidType(C,3);
8792   MatCheckPreallocated(C,3);
8793   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8794   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8795 
8796   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);
8797   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);
8798   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);
8799   MatCheckPreallocated(A,1);
8800 
8801   Anumeric = A->ops->matmultnumeric;
8802   Bnumeric = B->ops->matmultnumeric;
8803   if (Anumeric == Bnumeric){
8804     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8805     numeric = Bnumeric;
8806   } else {
8807     char  numericname[256];
8808     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8809     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8810     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8811     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8812     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8813     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8814     if (!numeric)
8815       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);
8816   }
8817   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8818   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8819   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8820   PetscFunctionReturn(0);
8821 }
8822 
8823 #undef __FUNCT__
8824 #define __FUNCT__ "MatMatTransposeMult"
8825 /*@
8826    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8827 
8828    Neighbor-wise Collective on Mat
8829 
8830    Input Parameters:
8831 +  A - the left matrix
8832 .  B - the right matrix
8833 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8834 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8835 
8836    Output Parameters:
8837 .  C - the product matrix
8838 
8839    Notes:
8840    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8841 
8842    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8843 
8844   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8845    actually needed.
8846 
8847    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
8848 
8849    Level: intermediate
8850 
8851 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8852 @*/
8853 PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8854 {
8855   PetscErrorCode ierr;
8856   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8857   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8858 
8859   PetscFunctionBegin;
8860   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8861   PetscValidType(A,1);
8862   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8863   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8864   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8865   PetscValidType(B,2);
8866   MatCheckPreallocated(B,2);
8867   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8868   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8869   PetscValidPointer(C,3);
8870   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);
8871   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8872   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8873   MatCheckPreallocated(A,1);
8874 
8875   fA = A->ops->mattransposemult;
8876   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8877   fB = B->ops->mattransposemult;
8878   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8879   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);
8880 
8881   if (scall == MAT_INITIAL_MATRIX){
8882     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8883     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
8884     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8885   }
8886   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8887   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
8888   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8889   PetscFunctionReturn(0);
8890 }
8891 
8892 #undef __FUNCT__
8893 #define __FUNCT__ "MatTransposeMatMult"
8894 /*@
8895    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8896 
8897    Neighbor-wise Collective on Mat
8898 
8899    Input Parameters:
8900 +  A - the left matrix
8901 .  B - the right matrix
8902 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8903 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8904 
8905    Output Parameters:
8906 .  C - the product matrix
8907 
8908    Notes:
8909    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8910 
8911    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8912 
8913   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8914    actually needed.
8915 
8916    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8917    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
8918 
8919    Level: intermediate
8920 
8921 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8922 @*/
8923 PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8924 {
8925   PetscErrorCode ierr;
8926   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8927   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8928   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
8929 
8930   PetscFunctionBegin;
8931   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8932   PetscValidType(A,1);
8933   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8934   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8935   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8936   PetscValidType(B,2);
8937   MatCheckPreallocated(B,2);
8938   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8939   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8940   PetscValidPointer(C,3);
8941   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);
8942   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8943   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8944   MatCheckPreallocated(A,1);
8945 
8946   fA = A->ops->transposematmult;
8947   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8948   fB = B->ops->transposematmult;
8949   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8950   if (fB==fA) {
8951     transposematmult = fA;
8952   }
8953   else {
8954     /* dual dispatch using MatQueryOp */
8955     ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8956     if(!transposematmult)
8957       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);
8958   }
8959   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8960   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8961   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8962   PetscFunctionReturn(0);
8963 }
8964 
8965 #undef __FUNCT__
8966 #define __FUNCT__ "MatGetRedundantMatrix"
8967 /*@C
8968    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8969 
8970    Collective on Mat
8971 
8972    Input Parameters:
8973 +  mat - the matrix
8974 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8975 .  subcomm - MPI communicator split from the communicator where mat resides in
8976 .  mlocal_red - number of local rows of the redundant matrix
8977 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8978 
8979    Output Parameter:
8980 .  matredundant - redundant matrix
8981 
8982    Notes:
8983    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8984    original matrix has not changed from that last call to MatGetRedundantMatrix().
8985 
8986    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8987    calling it.
8988 
8989    Only MPIAIJ matrix is supported.
8990 
8991    Level: advanced
8992 
8993    Concepts: subcommunicator
8994    Concepts: duplicate matrix
8995 
8996 .seealso: MatDestroy()
8997 @*/
8998 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8999 {
9000   PetscErrorCode ierr;
9001 
9002   PetscFunctionBegin;
9003   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9004   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9005     PetscValidPointer(*matredundant,6);
9006     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
9007   }
9008   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9009   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9010   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9011   MatCheckPreallocated(mat,1);
9012 
9013   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9014   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
9015   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9016   PetscFunctionReturn(0);
9017 }
9018 
9019 #undef __FUNCT__
9020 #define __FUNCT__ "MatGetMultiProcBlock"
9021 /*@C
9022    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9023    a given 'mat' object. Each submatrix can span multiple procs.
9024 
9025    Collective on Mat
9026 
9027    Input Parameters:
9028 +  mat - the matrix
9029 .  subcomm - the subcommunicator obtained by com_split(comm)
9030 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9031 
9032    Output Parameter:
9033 .  subMat - 'parallel submatrices each spans a given subcomm
9034 
9035   Notes:
9036   The submatrix partition across processors is dicated by 'subComm' a
9037   communicator obtained by com_split(comm). The comm_split
9038   is not restriced to be grouped with consequitive original ranks.
9039 
9040   Due the comm_split() usage, the parallel layout of the submatrices
9041   map directly to the layout of the original matrix [wrt the local
9042   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9043   into the 'DiagonalMat' of the subMat, hence it is used directly from
9044   the subMat. However the offDiagMat looses some columns - and this is
9045   reconstructed with MatSetValues()
9046 
9047   Level: advanced
9048 
9049   Concepts: subcommunicator
9050   Concepts: submatrices
9051 
9052 .seealso: MatGetSubMatrices()
9053 @*/
9054 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9055 {
9056   PetscErrorCode ierr;
9057   PetscMPIInt    commsize,subCommSize;
9058 
9059   PetscFunctionBegin;
9060   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
9061   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9062   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9063 
9064   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9065   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9066   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9067   PetscFunctionReturn(0);
9068 }
9069 
9070 #undef __FUNCT__
9071 #define __FUNCT__ "MatGetLocalSubMatrix"
9072 /*@
9073    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9074 
9075    Not Collective
9076 
9077    Input Arguments:
9078    mat - matrix to extract local submatrix from
9079    isrow - local row indices for submatrix
9080    iscol - local column indices for submatrix
9081 
9082    Output Arguments:
9083    submat - the submatrix
9084 
9085    Level: intermediate
9086 
9087    Notes:
9088    The submat should be returned with MatRestoreLocalSubMatrix().
9089 
9090    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9091    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9092 
9093    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9094    MatSetValuesBlockedLocal() will also be implemented.
9095 
9096 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9097 @*/
9098 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9099 {
9100   PetscErrorCode ierr;
9101 
9102   PetscFunctionBegin;
9103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9104   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9105   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9106   PetscCheckSameComm(isrow,2,iscol,3);
9107   PetscValidPointer(submat,4);
9108 
9109   if (mat->ops->getlocalsubmatrix) {
9110     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9111   } else {
9112     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9113   }
9114   PetscFunctionReturn(0);
9115 }
9116 
9117 #undef __FUNCT__
9118 #define __FUNCT__ "MatRestoreLocalSubMatrix"
9119 /*@
9120    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9121 
9122    Not Collective
9123 
9124    Input Arguments:
9125    mat - matrix to extract local submatrix from
9126    isrow - local row indices for submatrix
9127    iscol - local column indices for submatrix
9128    submat - the submatrix
9129 
9130    Level: intermediate
9131 
9132 .seealso: MatGetLocalSubMatrix()
9133 @*/
9134 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9135 {
9136   PetscErrorCode ierr;
9137 
9138   PetscFunctionBegin;
9139   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9140   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9141   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9142   PetscCheckSameComm(isrow,2,iscol,3);
9143   PetscValidPointer(submat,4);
9144   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
9145 
9146   if (mat->ops->restorelocalsubmatrix) {
9147     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9148   } else {
9149     ierr = MatDestroy(submat);CHKERRQ(ierr);
9150   }
9151   *submat = PETSC_NULL;
9152   PetscFunctionReturn(0);
9153 }
9154 
9155 /* --------------------------------------------------------*/
9156 #undef __FUNCT__
9157 #define __FUNCT__ "MatFindZeroDiagonals"
9158 /*@
9159    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9160 
9161    Collective on Mat
9162 
9163    Input Parameter:
9164 .  mat - the matrix
9165 
9166    Output Parameter:
9167 .  is - if any rows have zero diagonals this contains the list of them
9168 
9169    Level: developer
9170 
9171    Concepts: matrix-vector product
9172 
9173 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9174 @*/
9175 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9176 {
9177   PetscErrorCode ierr;
9178 
9179   PetscFunctionBegin;
9180   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9181   PetscValidType(mat,1);
9182   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9183   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9184 
9185   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9186   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
9187   PetscFunctionReturn(0);
9188 }
9189 
9190 #undef __FUNCT__
9191 #define __FUNCT__ "MatInvertBlockDiagonal"
9192 /*@
9193   MatInvertBlockDiagonal - Inverts the block diagonal entries.
9194 
9195   Collective on Mat
9196 
9197   Input Parameters:
9198 . mat - the matrix
9199 
9200   Output Parameters:
9201 . values - the block inverses in column major order (FORTRAN-like)
9202 
9203   Level: advanced
9204 @*/
9205 PetscErrorCode  MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
9206 {
9207   PetscErrorCode ierr;
9208 
9209   PetscFunctionBegin;
9210   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9211   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9212   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9213   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9214   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9215   PetscFunctionReturn(0);
9216 }
9217 
9218 #undef __FUNCT__
9219 #define __FUNCT__ "MatTransposeColoringDestroy"
9220 /*@C
9221     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9222     via MatTransposeColoringCreate().
9223 
9224     Collective on MatTransposeColoring
9225 
9226     Input Parameter:
9227 .   c - coloring context
9228 
9229     Level: intermediate
9230 
9231 .seealso: MatTransposeColoringCreate()
9232 @*/
9233 PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9234 {
9235   PetscErrorCode       ierr;
9236   MatTransposeColoring matcolor=*c;
9237 
9238   PetscFunctionBegin;
9239   if (!matcolor) PetscFunctionReturn(0);
9240   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
9241 
9242   ierr = PetscFree(matcolor->ncolumns);CHKERRQ(ierr);
9243   ierr = PetscFree(matcolor->nrows);CHKERRQ(ierr);
9244   ierr = PetscFree(matcolor->colorforrow);CHKERRQ(ierr);
9245   ierr = PetscFree2(matcolor->rows,matcolor->columnsforspidx);CHKERRQ(ierr);
9246   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
9247   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
9248   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
9249   PetscFunctionReturn(0);
9250 }
9251 
9252 #undef __FUNCT__
9253 #define __FUNCT__ "MatTransColoringApplySpToDen"
9254 /*@C
9255     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9256     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9257     MatTransposeColoring to sparse B.
9258 
9259     Collective on MatTransposeColoring
9260 
9261     Input Parameters:
9262 +   B - sparse matrix B
9263 .   Btdense - symbolic dense matrix B^T
9264 -   coloring - coloring context created with MatTransposeColoringCreate()
9265 
9266     Output Parameter:
9267 .   Btdense - dense matrix B^T
9268 
9269     Options Database Keys:
9270 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9271 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9272 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
9273 
9274     Level: intermediate
9275 
9276 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9277 
9278 .keywords: coloring
9279 @*/
9280 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9281 {
9282   PetscErrorCode ierr;
9283 
9284   PetscFunctionBegin;
9285   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
9286   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
9287   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
9288 
9289   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9290   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
9291   PetscFunctionReturn(0);
9292 }
9293 
9294 #undef __FUNCT__
9295 #define __FUNCT__ "MatTransColoringApplyDenToSp"
9296 /*@C
9297     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9298     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9299     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9300     Csp from Cden.
9301 
9302     Collective on MatTransposeColoring
9303 
9304     Input Parameters:
9305 +   coloring - coloring context created with MatTransposeColoringCreate()
9306 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
9307 
9308     Output Parameter:
9309 .   Csp - sparse matrix
9310 
9311     Options Database Keys:
9312 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9313 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9314 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9315 
9316     Level: intermediate
9317 
9318 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9319 
9320 .keywords: coloring
9321 @*/
9322 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9323 {
9324   PetscErrorCode ierr;
9325 
9326   PetscFunctionBegin;
9327   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
9328   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
9329   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
9330 
9331   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9332   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
9333   PetscFunctionReturn(0);
9334 }
9335 
9336 #undef __FUNCT__
9337 #define __FUNCT__ "MatTransposeColoringCreate"
9338 /*@C
9339    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9340 
9341    Collective on Mat
9342 
9343    Input Parameters:
9344 +  mat - the matrix product C
9345 -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9346 
9347     Output Parameter:
9348 .   color - the new coloring context
9349 
9350     Level: intermediate
9351 
9352 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9353            MatTransColoringApplyDen()ToSp, MatTransposeColoringView(),
9354 @*/
9355 PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9356 {
9357   MatTransposeColoring  c;
9358   MPI_Comm              comm;
9359   PetscErrorCode        ierr;
9360 
9361   PetscFunctionBegin;
9362   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9363   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9364   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);
9365 
9366   c->ctype = iscoloring->ctype;
9367   if (mat->ops->transposecoloringcreate) {
9368     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
9369   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");
9370 
9371   *color = c;
9372   ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9373   PetscFunctionReturn(0);
9374 }
9375