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