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