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