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