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