xref: /petsc/src/mat/interface/matrix.c (revision a8a8f36618f536eff5e4c1df78b3fdf9dd5d254e)
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_CUSPARSECopyToGPU, 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) PetscValidScalarPointer(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     if (mat->nullsp) {
4919       ierr = PetscOptionsGetBool(PETSC_NULL,"-mat_null_space_test",&flg,PETSC_NULL);CHKERRQ(ierr);
4920       if (flg) {
4921         ierr = MatNullSpaceTest(mat->nullsp,mat,PETSC_NULL);CHKERRQ(ierr);
4922       }
4923     }
4924   }
4925   inassm--;
4926   PetscFunctionReturn(0);
4927 }
4928 
4929 #undef __FUNCT__
4930 #define __FUNCT__ "MatSetOption"
4931 /*@
4932    MatSetOption - Sets a parameter option for a matrix. Some options
4933    may be specific to certain storage formats.  Some options
4934    determine how values will be inserted (or added). Sorted,
4935    row-oriented input will generally assemble the fastest. The default
4936    is row-oriented.
4937 
4938    Logically Collective on Mat
4939 
4940    Input Parameters:
4941 +  mat - the matrix
4942 .  option - the option, one of those listed below (and possibly others),
4943 -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
4944 
4945   Options Describing Matrix Structure:
4946 +    MAT_SPD - symmetric positive definite
4947 -    MAT_SYMMETRIC - symmetric in terms of both structure and value
4948 .    MAT_HERMITIAN - transpose is the complex conjugation
4949 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4950 -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4951                             you set to be kept with all future use of the matrix
4952                             including after MatAssemblyBegin/End() which could
4953                             potentially change the symmetry structure, i.e. you
4954                             KNOW the matrix will ALWAYS have the property you set.
4955 
4956 
4957    Options For Use with MatSetValues():
4958    Insert a logically dense subblock, which can be
4959 .    MAT_ROW_ORIENTED - row-oriented (default)
4960 
4961    Note these options reflect the data you pass in with MatSetValues(); it has
4962    nothing to do with how the data is stored internally in the matrix
4963    data structure.
4964 
4965    When (re)assembling a matrix, we can restrict the input for
4966    efficiency/debugging purposes.  These options include
4967 +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4968         allowed if they generate a new nonzero
4969 .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4970 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4971 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4972 .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4973 +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4974         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4975         performance for very large process counts.
4976 
4977    Notes:
4978    Some options are relevant only for particular matrix types and
4979    are thus ignored by others.  Other options are not supported by
4980    certain matrix types and will generate an error message if set.
4981 
4982    If using a Fortran 77 module to compute a matrix, one may need to
4983    use the column-oriented option (or convert to the row-oriented
4984    format).
4985 
4986    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
4987    that would generate a new entry in the nonzero structure is instead
4988    ignored.  Thus, if memory has not alredy been allocated for this particular
4989    data, then the insertion is ignored. For dense matrices, in which
4990    the entire array is allocated, no entries are ever ignored.
4991    Set after the first MatAssemblyEnd()
4992 
4993    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
4994    that would generate a new entry in the nonzero structure instead produces
4995    an error. (Currently supported for AIJ and BAIJ formats only.)
4996    This is a useful flag when using SAME_NONZERO_PATTERN in calling
4997    KSPSetOperators() to ensure that the nonzero pattern truely does
4998    remain unchanged. Set after the first MatAssemblyEnd()
4999 
5000    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5001    that would generate a new entry that has not been preallocated will
5002    instead produce an error. (Currently supported for AIJ and BAIJ formats
5003    only.) This is a useful flag when debugging matrix memory preallocation.
5004 
5005    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5006    other processors should be dropped, rather than stashed.
5007    This is useful if you know that the "owning" processor is also
5008    always generating the correct matrix entries, so that PETSc need
5009    not transfer duplicate entries generated on another processor.
5010 
5011    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5012    searches during matrix assembly. When this flag is set, the hash table
5013    is created during the first Matrix Assembly. This hash table is
5014    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5015    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5016    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5017    supported by MATMPIBAIJ format only.
5018 
5019    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5020    are kept in the nonzero structure
5021 
5022    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5023    a zero location in the matrix
5024 
5025    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5026    ROWBS matrix types
5027 
5028    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5029         zero row routines and thus improves performance for very large process counts.
5030 
5031    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5032         part of the matrix (since they should match the upper triangular part).
5033 
5034    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5035 
5036    Level: intermediate
5037 
5038    Concepts: matrices^setting options
5039 
5040 @*/
5041 PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5042 {
5043   PetscErrorCode ierr;
5044 
5045   PetscFunctionBegin;
5046   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5047   PetscValidType(mat,1);
5048   PetscValidLogicalCollectiveEnum(mat,op,2);
5049   PetscValidLogicalCollectiveBool(mat,flg,3);
5050 
5051   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);
5052   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()");
5053 
5054   switch (op) {
5055   case MAT_NO_OFF_PROC_ENTRIES:
5056     mat->nooffprocentries                = flg;
5057     PetscFunctionReturn(0);
5058     break;
5059   case MAT_NO_OFF_PROC_ZERO_ROWS:
5060     mat->nooffproczerorows               = flg;
5061     PetscFunctionReturn(0);
5062     break;
5063   case MAT_SPD:
5064     mat->spd_set                         = PETSC_TRUE;
5065     mat->spd                             = flg;
5066     if (flg) {
5067       mat->symmetric                     = PETSC_TRUE;
5068       mat->structurally_symmetric        = PETSC_TRUE;
5069       mat->symmetric_set                 = PETSC_TRUE;
5070       mat->structurally_symmetric_set    = PETSC_TRUE;
5071     }
5072     break;
5073   case MAT_SYMMETRIC:
5074     mat->symmetric                       = flg;
5075     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5076     mat->symmetric_set                   = PETSC_TRUE;
5077     mat->structurally_symmetric_set      = flg;
5078     break;
5079   case MAT_HERMITIAN:
5080     mat->hermitian                       = flg;
5081     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5082     mat->hermitian_set                   = PETSC_TRUE;
5083     mat->structurally_symmetric_set      = flg;
5084     break;
5085   case MAT_STRUCTURALLY_SYMMETRIC:
5086     mat->structurally_symmetric          = flg;
5087     mat->structurally_symmetric_set      = PETSC_TRUE;
5088     break;
5089   case MAT_SYMMETRY_ETERNAL:
5090     mat->symmetric_eternal               = flg;
5091     break;
5092   default:
5093     break;
5094   }
5095   if (mat->ops->setoption) {
5096     ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr);
5097   }
5098   PetscFunctionReturn(0);
5099 }
5100 
5101 #undef __FUNCT__
5102 #define __FUNCT__ "MatZeroEntries"
5103 /*@
5104    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5105    this routine retains the old nonzero structure.
5106 
5107    Logically Collective on Mat
5108 
5109    Input Parameters:
5110 .  mat - the matrix
5111 
5112    Level: intermediate
5113 
5114    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.
5115    See the Performance chapter of the users manual for information on preallocating matrices.
5116 
5117    Concepts: matrices^zeroing
5118 
5119 .seealso: MatZeroRows()
5120 @*/
5121 PetscErrorCode  MatZeroEntries(Mat mat)
5122 {
5123   PetscErrorCode ierr;
5124 
5125   PetscFunctionBegin;
5126   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5127   PetscValidType(mat,1);
5128   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5129   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");
5130   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5131   MatCheckPreallocated(mat,1);
5132 
5133   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5134   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
5135   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
5136   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5137 #if defined(PETSC_HAVE_CUSP)
5138   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5139     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5140   }
5141 #endif
5142   PetscFunctionReturn(0);
5143 }
5144 
5145 #undef __FUNCT__
5146 #define __FUNCT__ "MatZeroRowsColumns"
5147 /*@C
5148    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5149    of a set of rows and columns of a matrix.
5150 
5151    Collective on Mat
5152 
5153    Input Parameters:
5154 +  mat - the matrix
5155 .  numRows - the number of rows to remove
5156 .  rows - the global row indices
5157 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5158 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5159 -  b - optional vector of right hand side, that will be adjusted by provided solution
5160 
5161    Notes:
5162    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5163 
5164    The user can set a value in the diagonal entry (or for the AIJ and
5165    row formats can optionally remove the main diagonal entry from the
5166    nonzero structure as well, by passing 0.0 as the final argument).
5167 
5168    For the parallel case, all processes that share the matrix (i.e.,
5169    those in the communicator used for matrix creation) MUST call this
5170    routine, regardless of whether any rows being zeroed are owned by
5171    them.
5172 
5173    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5174    list only rows local to itself).
5175 
5176    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5177 
5178    Level: intermediate
5179 
5180    Concepts: matrices^zeroing rows
5181 
5182 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5183 @*/
5184 PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5185 {
5186   PetscErrorCode ierr;
5187 
5188   PetscFunctionBegin;
5189   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5190   PetscValidType(mat,1);
5191   if (numRows) PetscValidIntPointer(rows,3);
5192   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5193   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5194   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5195   MatCheckPreallocated(mat,1);
5196 
5197   ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5198   ierr = MatView_Private(mat);CHKERRQ(ierr);
5199   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5200 #if defined(PETSC_HAVE_CUSP)
5201   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5202     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5203   }
5204 #endif
5205   PetscFunctionReturn(0);
5206 }
5207 
5208 #undef __FUNCT__
5209 #define __FUNCT__ "MatZeroRowsColumnsIS"
5210 /*@C
5211    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5212    of a set of rows and columns of a matrix.
5213 
5214    Collective on Mat
5215 
5216    Input Parameters:
5217 +  mat - the matrix
5218 .  is - the rows to zero
5219 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5220 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5221 -  b - optional vector of right hand side, that will be adjusted by provided solution
5222 
5223    Notes:
5224    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5225 
5226    The user can set a value in the diagonal entry (or for the AIJ and
5227    row formats can optionally remove the main diagonal entry from the
5228    nonzero structure as well, by passing 0.0 as the final argument).
5229 
5230    For the parallel case, all processes that share the matrix (i.e.,
5231    those in the communicator used for matrix creation) MUST call this
5232    routine, regardless of whether any rows being zeroed are owned by
5233    them.
5234 
5235    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5236    list only rows local to itself).
5237 
5238    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5239 
5240    Level: intermediate
5241 
5242    Concepts: matrices^zeroing rows
5243 
5244 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5245 @*/
5246 PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5247 {
5248   PetscErrorCode ierr;
5249   PetscInt       numRows;
5250   const PetscInt *rows;
5251 
5252   PetscFunctionBegin;
5253   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5254   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5255   PetscValidType(mat,1);
5256   PetscValidType(is,2);
5257   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5258   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5259   ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5260   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5261   PetscFunctionReturn(0);
5262 }
5263 
5264 #undef __FUNCT__
5265 #define __FUNCT__ "MatZeroRows"
5266 /*@C
5267    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5268    of a set of rows of a matrix.
5269 
5270    Collective on Mat
5271 
5272    Input Parameters:
5273 +  mat - the matrix
5274 .  numRows - the number of rows to remove
5275 .  rows - the global row indices
5276 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5277 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5278 -  b - optional vector of right hand side, that will be adjusted by provided solution
5279 
5280    Notes:
5281    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5282    but does not release memory.  For the dense and block diagonal
5283    formats this does not alter the nonzero structure.
5284 
5285    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5286    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5287    merely zeroed.
5288 
5289    The user can set a value in the diagonal entry (or for the AIJ and
5290    row formats can optionally remove the main diagonal entry from the
5291    nonzero structure as well, by passing 0.0 as the final argument).
5292 
5293    For the parallel case, all processes that share the matrix (i.e.,
5294    those in the communicator used for matrix creation) MUST call this
5295    routine, regardless of whether any rows being zeroed are owned by
5296    them.
5297 
5298    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5299    list only rows local to itself).
5300 
5301    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5302    owns that are to be zeroed. This saves a global synchronization in the implementation.
5303 
5304    Level: intermediate
5305 
5306    Concepts: matrices^zeroing rows
5307 
5308 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5309 @*/
5310 PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5311 {
5312   PetscErrorCode ierr;
5313 
5314   PetscFunctionBegin;
5315   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5316   PetscValidType(mat,1);
5317   if (numRows) PetscValidIntPointer(rows,3);
5318   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5319   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5320   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5321   MatCheckPreallocated(mat,1);
5322 
5323   ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5324   ierr = MatView_Private(mat);CHKERRQ(ierr);
5325   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5326 #if defined(PETSC_HAVE_CUSP)
5327   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5328     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5329   }
5330 #endif
5331   PetscFunctionReturn(0);
5332 }
5333 
5334 #undef __FUNCT__
5335 #define __FUNCT__ "MatZeroRowsIS"
5336 /*@C
5337    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5338    of a set of rows of a matrix.
5339 
5340    Collective on Mat
5341 
5342    Input Parameters:
5343 +  mat - the matrix
5344 .  is - index set of rows to remove
5345 .  diag - value put in all diagonals of eliminated rows
5346 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5347 -  b - optional vector of right hand side, that will be adjusted by provided solution
5348 
5349    Notes:
5350    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5351    but does not release memory.  For the dense and block diagonal
5352    formats this does not alter the nonzero structure.
5353 
5354    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5355    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5356    merely zeroed.
5357 
5358    The user can set a value in the diagonal entry (or for the AIJ and
5359    row formats can optionally remove the main diagonal entry from the
5360    nonzero structure as well, by passing 0.0 as the final argument).
5361 
5362    For the parallel case, all processes that share the matrix (i.e.,
5363    those in the communicator used for matrix creation) MUST call this
5364    routine, regardless of whether any rows being zeroed are owned by
5365    them.
5366 
5367    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5368    list only rows local to itself).
5369 
5370    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5371    owns that are to be zeroed. This saves a global synchronization in the implementation.
5372 
5373    Level: intermediate
5374 
5375    Concepts: matrices^zeroing rows
5376 
5377 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5378 @*/
5379 PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5380 {
5381   PetscInt       numRows;
5382   const PetscInt *rows;
5383   PetscErrorCode ierr;
5384 
5385   PetscFunctionBegin;
5386   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5387   PetscValidType(mat,1);
5388   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5389   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5390   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5391   ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5392   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5393   PetscFunctionReturn(0);
5394 }
5395 
5396 #undef __FUNCT__
5397 #define __FUNCT__ "MatZeroRowsStencil"
5398 /*@C
5399    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5400    of a set of rows of a matrix. These rows must be local to the process.
5401 
5402    Collective on Mat
5403 
5404    Input Parameters:
5405 +  mat - the matrix
5406 .  numRows - the number of rows to remove
5407 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5408 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5409 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5410 -  b - optional vector of right hand side, that will be adjusted by provided solution
5411 
5412    Notes:
5413    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5414    but does not release memory.  For the dense and block diagonal
5415    formats this does not alter the nonzero structure.
5416 
5417    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5418    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5419    merely zeroed.
5420 
5421    The user can set a value in the diagonal entry (or for the AIJ and
5422    row formats can optionally remove the main diagonal entry from the
5423    nonzero structure as well, by passing 0.0 as the final argument).
5424 
5425    For the parallel case, all processes that share the matrix (i.e.,
5426    those in the communicator used for matrix creation) MUST call this
5427    routine, regardless of whether any rows being zeroed are owned by
5428    them.
5429 
5430    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5431    list only rows local to itself).
5432 
5433    The grid coordinates are across the entire grid, not just the local portion
5434 
5435    In Fortran idxm and idxn should be declared as
5436 $     MatStencil idxm(4,m)
5437    and the values inserted using
5438 $    idxm(MatStencil_i,1) = i
5439 $    idxm(MatStencil_j,1) = j
5440 $    idxm(MatStencil_k,1) = k
5441 $    idxm(MatStencil_c,1) = c
5442    etc
5443 
5444    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5445    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5446    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5447    DMDA_BOUNDARY_PERIODIC boundary type.
5448 
5449    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
5450    a single value per point) you can skip filling those indices.
5451 
5452    Level: intermediate
5453 
5454    Concepts: matrices^zeroing rows
5455 
5456 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5457 @*/
5458 PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5459 {
5460   PetscInt       dim    = mat->stencil.dim;
5461   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5462   PetscInt      *dims   = mat->stencil.dims+1;
5463   PetscInt      *starts = mat->stencil.starts;
5464   PetscInt      *dxm    = (PetscInt *) rows;
5465   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5466   PetscErrorCode ierr;
5467 
5468   PetscFunctionBegin;
5469   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5470   PetscValidType(mat,1);
5471   if (numRows) PetscValidIntPointer(rows,3);
5472 
5473   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5474   for(i = 0; i < numRows; ++i) {
5475     /* Skip unused dimensions (they are ordered k, j, i, c) */
5476     for(j = 0; j < 3-sdim; ++j) dxm++;
5477     /* Local index in X dir */
5478     tmp = *dxm++ - starts[0];
5479     /* Loop over remaining dimensions */
5480     for(j = 0; j < dim-1; ++j) {
5481       /* If nonlocal, set index to be negative */
5482       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5483       /* Update local index */
5484       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5485     }
5486     /* Skip component slot if necessary */
5487     if (mat->stencil.noc) dxm++;
5488     /* Local row number */
5489     if (tmp >= 0) {
5490       jdxm[numNewRows++] = tmp;
5491     }
5492   }
5493   ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5494   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5495   PetscFunctionReturn(0);
5496 }
5497 
5498 #undef __FUNCT__
5499 #define __FUNCT__ "MatZeroRowsColumnsStencil"
5500 /*@C
5501    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5502    of a set of rows and columns of a matrix.
5503 
5504    Collective on Mat
5505 
5506    Input Parameters:
5507 +  mat - the matrix
5508 .  numRows - the number of rows/columns to remove
5509 .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5510 .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5511 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5512 -  b - optional vector of right hand side, that will be adjusted by provided solution
5513 
5514    Notes:
5515    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5516    but does not release memory.  For the dense and block diagonal
5517    formats this does not alter the nonzero structure.
5518 
5519    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5520    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5521    merely zeroed.
5522 
5523    The user can set a value in the diagonal entry (or for the AIJ and
5524    row formats can optionally remove the main diagonal entry from the
5525    nonzero structure as well, by passing 0.0 as the final argument).
5526 
5527    For the parallel case, all processes that share the matrix (i.e.,
5528    those in the communicator used for matrix creation) MUST call this
5529    routine, regardless of whether any rows being zeroed are owned by
5530    them.
5531 
5532    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5533    list only rows local to itself, but the row/column numbers are given in local numbering).
5534 
5535    The grid coordinates are across the entire grid, not just the local portion
5536 
5537    In Fortran idxm and idxn should be declared as
5538 $     MatStencil idxm(4,m)
5539    and the values inserted using
5540 $    idxm(MatStencil_i,1) = i
5541 $    idxm(MatStencil_j,1) = j
5542 $    idxm(MatStencil_k,1) = k
5543 $    idxm(MatStencil_c,1) = c
5544    etc
5545 
5546    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5547    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5548    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5549    DMDA_BOUNDARY_PERIODIC boundary type.
5550 
5551    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
5552    a single value per point) you can skip filling those indices.
5553 
5554    Level: intermediate
5555 
5556    Concepts: matrices^zeroing rows
5557 
5558 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5559 @*/
5560 PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5561 {
5562   PetscInt       dim    = mat->stencil.dim;
5563   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5564   PetscInt      *dims   = mat->stencil.dims+1;
5565   PetscInt      *starts = mat->stencil.starts;
5566   PetscInt      *dxm    = (PetscInt *) rows;
5567   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;
5568   PetscErrorCode ierr;
5569 
5570   PetscFunctionBegin;
5571   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5572   PetscValidType(mat,1);
5573   if (numRows) PetscValidIntPointer(rows,3);
5574 
5575   ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr);
5576   for(i = 0; i < numRows; ++i) {
5577     /* Skip unused dimensions (they are ordered k, j, i, c) */
5578     for(j = 0; j < 3-sdim; ++j) dxm++;
5579     /* Local index in X dir */
5580     tmp = *dxm++ - starts[0];
5581     /* Loop over remaining dimensions */
5582     for(j = 0; j < dim-1; ++j) {
5583       /* If nonlocal, set index to be negative */
5584       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5585       /* Update local index */
5586       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5587     }
5588     /* Skip component slot if necessary */
5589     if (mat->stencil.noc) dxm++;
5590     /* Local row number */
5591     if (tmp >= 0) {
5592       jdxm[numNewRows++] = tmp;
5593     }
5594   }
5595   ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr);
5596   ierr = PetscFree(jdxm);CHKERRQ(ierr);
5597   PetscFunctionReturn(0);
5598 }
5599 
5600 #undef __FUNCT__
5601 #define __FUNCT__ "MatZeroRowsLocal"
5602 /*@C
5603    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5604    of a set of rows of a matrix; using local numbering of rows.
5605 
5606    Collective on Mat
5607 
5608    Input Parameters:
5609 +  mat - the matrix
5610 .  numRows - the number of rows to remove
5611 .  rows - the global row indices
5612 .  diag - value put in all diagonals of eliminated rows
5613 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5614 -  b - optional vector of right hand side, that will be adjusted by provided solution
5615 
5616    Notes:
5617    Before calling MatZeroRowsLocal(), the user must first set the
5618    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5619 
5620    For the AIJ matrix formats this removes the old nonzero structure,
5621    but does not release memory.  For the dense and block diagonal
5622    formats this does not alter the nonzero structure.
5623 
5624    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5625    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5626    merely zeroed.
5627 
5628    The user can set a value in the diagonal entry (or for the AIJ and
5629    row formats can optionally remove the main diagonal entry from the
5630    nonzero structure as well, by passing 0.0 as the final argument).
5631 
5632    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5633    owns that are to be zeroed. This saves a global synchronization in the implementation.
5634 
5635    Level: intermediate
5636 
5637    Concepts: matrices^zeroing
5638 
5639 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5640 @*/
5641 PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5642 {
5643   PetscErrorCode ierr;
5644   PetscMPIInt    size;
5645 
5646   PetscFunctionBegin;
5647   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5648   PetscValidType(mat,1);
5649   if (numRows) PetscValidIntPointer(rows,3);
5650   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5651   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5652   MatCheckPreallocated(mat,1);
5653 
5654   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5655   if (mat->ops->zerorowslocal) {
5656     ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5657   } else if (size == 1) {
5658     ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5659   } else {
5660     IS             is, newis;
5661     const PetscInt *newRows;
5662 
5663     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5664     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5665     ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr);
5666     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5667     ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5668     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5669     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5670     ierr = ISDestroy(&is);CHKERRQ(ierr);
5671   }
5672   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5673 #if defined(PETSC_HAVE_CUSP)
5674   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5675     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5676   }
5677 #endif
5678   PetscFunctionReturn(0);
5679 }
5680 
5681 #undef __FUNCT__
5682 #define __FUNCT__ "MatZeroRowsLocalIS"
5683 /*@C
5684    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5685    of a set of rows of a matrix; using local numbering of rows.
5686 
5687    Collective on Mat
5688 
5689    Input Parameters:
5690 +  mat - the matrix
5691 .  is - index set of rows to remove
5692 .  diag - value put in all diagonals of eliminated rows
5693 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5694 -  b - optional vector of right hand side, that will be adjusted by provided solution
5695 
5696    Notes:
5697    Before calling MatZeroRowsLocalIS(), the user must first set the
5698    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5699 
5700    For the AIJ matrix formats this removes the old nonzero structure,
5701    but does not release memory.  For the dense and block diagonal
5702    formats this does not alter the nonzero structure.
5703 
5704    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5705    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5706    merely zeroed.
5707 
5708    The user can set a value in the diagonal entry (or for the AIJ and
5709    row formats can optionally remove the main diagonal entry from the
5710    nonzero structure as well, by passing 0.0 as the final argument).
5711 
5712    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5713    owns that are to be zeroed. This saves a global synchronization in the implementation.
5714 
5715    Level: intermediate
5716 
5717    Concepts: matrices^zeroing
5718 
5719 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5720 @*/
5721 PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5722 {
5723   PetscErrorCode ierr;
5724   PetscInt       numRows;
5725   const PetscInt *rows;
5726 
5727   PetscFunctionBegin;
5728   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5729   PetscValidType(mat,1);
5730   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5731   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5732   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5733   MatCheckPreallocated(mat,1);
5734 
5735   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5736   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5737   ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5738   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5739   PetscFunctionReturn(0);
5740 }
5741 
5742 #undef __FUNCT__
5743 #define __FUNCT__ "MatZeroRowsColumnsLocal"
5744 /*@C
5745    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5746    of a set of rows and columns of a matrix; using local numbering of rows.
5747 
5748    Collective on Mat
5749 
5750    Input Parameters:
5751 +  mat - the matrix
5752 .  numRows - the number of rows to remove
5753 .  rows - the global row indices
5754 .  diag - value put in all diagonals of eliminated rows
5755 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5756 -  b - optional vector of right hand side, that will be adjusted by provided solution
5757 
5758    Notes:
5759    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5760    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5761 
5762    The user can set a value in the diagonal entry (or for the AIJ and
5763    row formats can optionally remove the main diagonal entry from the
5764    nonzero structure as well, by passing 0.0 as the final argument).
5765 
5766    Level: intermediate
5767 
5768    Concepts: matrices^zeroing
5769 
5770 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5771 @*/
5772 PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5773 {
5774   PetscErrorCode ierr;
5775   PetscMPIInt    size;
5776 
5777   PetscFunctionBegin;
5778   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5779   PetscValidType(mat,1);
5780   if (numRows) PetscValidIntPointer(rows,3);
5781   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5782   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5783   MatCheckPreallocated(mat,1);
5784 
5785   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
5786   if (size == 1) {
5787     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5788   } else {
5789     IS             is, newis;
5790     const PetscInt *newRows;
5791 
5792     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5793     ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr);
5794     ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr);
5795     ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr);
5796     ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr);
5797     ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr);
5798     ierr = ISDestroy(&newis);CHKERRQ(ierr);
5799     ierr = ISDestroy(&is);CHKERRQ(ierr);
5800   }
5801   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5802 #if defined(PETSC_HAVE_CUSP)
5803   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5804     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5805   }
5806 #endif
5807   PetscFunctionReturn(0);
5808 }
5809 
5810 #undef __FUNCT__
5811 #define __FUNCT__ "MatZeroRowsColumnsLocalIS"
5812 /*@C
5813    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5814    of a set of rows and columns of a matrix; using local numbering of rows.
5815 
5816    Collective on Mat
5817 
5818    Input Parameters:
5819 +  mat - the matrix
5820 .  is - index set of rows to remove
5821 .  diag - value put in all diagonals of eliminated rows
5822 .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5823 -  b - optional vector of right hand side, that will be adjusted by provided solution
5824 
5825    Notes:
5826    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5827    local-to-global mapping by calling MatSetLocalToGlobalMapping().
5828 
5829    The user can set a value in the diagonal entry (or for the AIJ and
5830    row formats can optionally remove the main diagonal entry from the
5831    nonzero structure as well, by passing 0.0 as the final argument).
5832 
5833    Level: intermediate
5834 
5835    Concepts: matrices^zeroing
5836 
5837 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5838 @*/
5839 PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5840 {
5841   PetscErrorCode ierr;
5842   PetscInt       numRows;
5843   const PetscInt *rows;
5844 
5845   PetscFunctionBegin;
5846   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5847   PetscValidType(mat,1);
5848   PetscValidHeaderSpecific(is,IS_CLASSID,2);
5849   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5850   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5851   MatCheckPreallocated(mat,1);
5852 
5853   ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr);
5854   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
5855   ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr);
5856   ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr);
5857   PetscFunctionReturn(0);
5858 }
5859 
5860 #undef __FUNCT__
5861 #define __FUNCT__ "MatGetSize"
5862 /*@
5863    MatGetSize - Returns the numbers of rows and columns in a matrix.
5864 
5865    Not Collective
5866 
5867    Input Parameter:
5868 .  mat - the matrix
5869 
5870    Output Parameters:
5871 +  m - the number of global rows
5872 -  n - the number of global columns
5873 
5874    Note: both output parameters can be PETSC_NULL on input.
5875 
5876    Level: beginner
5877 
5878    Concepts: matrices^size
5879 
5880 .seealso: MatGetLocalSize()
5881 @*/
5882 PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5883 {
5884   PetscFunctionBegin;
5885   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5886   if (m) *m = mat->rmap->N;
5887   if (n) *n = mat->cmap->N;
5888   PetscFunctionReturn(0);
5889 }
5890 
5891 #undef __FUNCT__
5892 #define __FUNCT__ "MatGetLocalSize"
5893 /*@
5894    MatGetLocalSize - Returns the number of rows and columns in a matrix
5895    stored locally.  This information may be implementation dependent, so
5896    use with care.
5897 
5898    Not Collective
5899 
5900    Input Parameters:
5901 .  mat - the matrix
5902 
5903    Output Parameters:
5904 +  m - the number of local rows
5905 -  n - the number of local columns
5906 
5907    Note: both output parameters can be PETSC_NULL on input.
5908 
5909    Level: beginner
5910 
5911    Concepts: matrices^local size
5912 
5913 .seealso: MatGetSize()
5914 @*/
5915 PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5916 {
5917   PetscFunctionBegin;
5918   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5919   if (m) PetscValidIntPointer(m,2);
5920   if (n) PetscValidIntPointer(n,3);
5921   if (m) *m = mat->rmap->n;
5922   if (n) *n = mat->cmap->n;
5923   PetscFunctionReturn(0);
5924 }
5925 
5926 #undef __FUNCT__
5927 #define __FUNCT__ "MatGetOwnershipRangeColumn"
5928 /*@
5929    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5930    this processor. (The columns of the "diagonal block")
5931 
5932    Not Collective, unless matrix has not been allocated, then collective on Mat
5933 
5934    Input Parameters:
5935 .  mat - the matrix
5936 
5937    Output Parameters:
5938 +  m - the global index of the first local column
5939 -  n - one more than the global index of the last local column
5940 
5941    Notes: both output parameters can be PETSC_NULL on input.
5942 
5943    Level: developer
5944 
5945    Concepts: matrices^column ownership
5946 
5947 .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
5948 
5949 @*/
5950 PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5951 {
5952 
5953   PetscFunctionBegin;
5954   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5955   PetscValidType(mat,1);
5956   if (m) PetscValidIntPointer(m,2);
5957   if (n) PetscValidIntPointer(n,3);
5958   MatCheckPreallocated(mat,1);
5959   if (m) *m = mat->cmap->rstart;
5960   if (n) *n = mat->cmap->rend;
5961   PetscFunctionReturn(0);
5962 }
5963 
5964 #undef __FUNCT__
5965 #define __FUNCT__ "MatGetOwnershipRange"
5966 /*@
5967    MatGetOwnershipRange - Returns the range of matrix rows owned by
5968    this processor, assuming that the matrix is laid out with the first
5969    n1 rows on the first processor, the next n2 rows on the second, etc.
5970    For certain parallel layouts this range may not be well defined.
5971 
5972    Not Collective, unless matrix has not been allocated, then collective on Mat
5973 
5974    Input Parameters:
5975 .  mat - the matrix
5976 
5977    Output Parameters:
5978 +  m - the global index of the first local row
5979 -  n - one more than the global index of the last local row
5980 
5981    Note: both output parameters can be PETSC_NULL on input.
5982 
5983    Level: beginner
5984 
5985    Concepts: matrices^row ownership
5986 
5987 .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
5988 
5989 @*/
5990 PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5991 {
5992 
5993   PetscFunctionBegin;
5994   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5995   PetscValidType(mat,1);
5996   if (m) PetscValidIntPointer(m,2);
5997   if (n) PetscValidIntPointer(n,3);
5998   MatCheckPreallocated(mat,1);
5999   if (m) *m = mat->rmap->rstart;
6000   if (n) *n = mat->rmap->rend;
6001   PetscFunctionReturn(0);
6002 }
6003 
6004 #undef __FUNCT__
6005 #define __FUNCT__ "MatGetOwnershipRanges"
6006 /*@C
6007    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6008    each process
6009 
6010    Not Collective, unless matrix has not been allocated, then collective on Mat
6011 
6012    Input Parameters:
6013 .  mat - the matrix
6014 
6015    Output Parameters:
6016 .  ranges - start of each processors portion plus one more then the total length at the end
6017 
6018    Level: beginner
6019 
6020    Concepts: matrices^row ownership
6021 
6022 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6023 
6024 @*/
6025 PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6026 {
6027   PetscErrorCode ierr;
6028 
6029   PetscFunctionBegin;
6030   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6031   PetscValidType(mat,1);
6032   MatCheckPreallocated(mat,1);
6033   ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr);
6034   PetscFunctionReturn(0);
6035 }
6036 
6037 #undef __FUNCT__
6038 #define __FUNCT__ "MatGetOwnershipRangesColumn"
6039 /*@C
6040    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6041    this processor. (The columns of the "diagonal blocks" for each process)
6042 
6043    Not Collective, unless matrix has not been allocated, then collective on Mat
6044 
6045    Input Parameters:
6046 .  mat - the matrix
6047 
6048    Output Parameters:
6049 .  ranges - start of each processors portion plus one more then the total length at the end
6050 
6051    Level: beginner
6052 
6053    Concepts: matrices^column ownership
6054 
6055 .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6056 
6057 @*/
6058 PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6059 {
6060   PetscErrorCode ierr;
6061 
6062   PetscFunctionBegin;
6063   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6064   PetscValidType(mat,1);
6065   MatCheckPreallocated(mat,1);
6066   ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr);
6067   PetscFunctionReturn(0);
6068 }
6069 
6070 #undef __FUNCT__
6071 #define __FUNCT__ "MatGetOwnershipIS"
6072 /*@C
6073    MatGetOwnershipIS - Get row and column ownership as index sets
6074 
6075    Not Collective
6076 
6077    Input Arguments:
6078 .  A - matrix of type Elemental
6079 
6080    Output Arguments:
6081 +  rows - rows in which this process owns elements
6082 .  cols - columns in which this process owns elements
6083 
6084    Level: intermediate
6085 
6086 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6087 @*/
6088 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6089 {
6090   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6091 
6092   PetscFunctionBegin;
6093   MatCheckPreallocated(A,1);
6094   ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",(PetscVoidStarFunction)&f);CHKERRQ(ierr);
6095   if (f) {
6096     ierr = (*f)(A,rows,cols);CHKERRQ(ierr);
6097   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6098     if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);}
6099     if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);}
6100   }
6101   PetscFunctionReturn(0);
6102 }
6103 
6104 #undef __FUNCT__
6105 #define __FUNCT__ "MatILUFactorSymbolic"
6106 /*@C
6107    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6108    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6109    to complete the factorization.
6110 
6111    Collective on Mat
6112 
6113    Input Parameters:
6114 +  mat - the matrix
6115 .  row - row permutation
6116 .  column - column permutation
6117 -  info - structure containing
6118 $      levels - number of levels of fill.
6119 $      expected fill - as ratio of original fill.
6120 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6121                 missing diagonal entries)
6122 
6123    Output Parameters:
6124 .  fact - new matrix that has been symbolically factored
6125 
6126    Notes:
6127    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6128    choosing the fill factor for better efficiency.
6129 
6130    Most users should employ the simplified KSP interface for linear solvers
6131    instead of working directly with matrix algebra routines such as this.
6132    See, e.g., KSPCreate().
6133 
6134    Level: developer
6135 
6136   Concepts: matrices^symbolic LU factorization
6137   Concepts: matrices^factorization
6138   Concepts: LU^symbolic factorization
6139 
6140 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6141           MatGetOrdering(), MatFactorInfo
6142 
6143     Developer Note: fortran interface is not autogenerated as the f90
6144     interface defintion cannot be generated correctly [due to MatFactorInfo]
6145 
6146 @*/
6147 PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6148 {
6149   PetscErrorCode ierr;
6150 
6151   PetscFunctionBegin;
6152   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6153   PetscValidType(mat,1);
6154   PetscValidHeaderSpecific(row,IS_CLASSID,2);
6155   PetscValidHeaderSpecific(col,IS_CLASSID,3);
6156   PetscValidPointer(info,4);
6157   PetscValidPointer(fact,5);
6158   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6159   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6160   if (!(fact)->ops->ilufactorsymbolic) {
6161     const MatSolverPackage spackage;
6162     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6163     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6164   }
6165   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6166   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6167   MatCheckPreallocated(mat,2);
6168 
6169   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6170   ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr);
6171   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
6172   PetscFunctionReturn(0);
6173 }
6174 
6175 #undef __FUNCT__
6176 #define __FUNCT__ "MatICCFactorSymbolic"
6177 /*@C
6178    MatICCFactorSymbolic - Performs symbolic incomplete
6179    Cholesky factorization for a symmetric matrix.  Use
6180    MatCholeskyFactorNumeric() to complete the factorization.
6181 
6182    Collective on Mat
6183 
6184    Input Parameters:
6185 +  mat - the matrix
6186 .  perm - row and column permutation
6187 -  info - structure containing
6188 $      levels - number of levels of fill.
6189 $      expected fill - as ratio of original fill.
6190 
6191    Output Parameter:
6192 .  fact - the factored matrix
6193 
6194    Notes:
6195    Most users should employ the KSP interface for linear solvers
6196    instead of working directly with matrix algebra routines such as this.
6197    See, e.g., KSPCreate().
6198 
6199    Level: developer
6200 
6201   Concepts: matrices^symbolic incomplete Cholesky factorization
6202   Concepts: matrices^factorization
6203   Concepts: Cholsky^symbolic factorization
6204 
6205 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6206 
6207     Developer Note: fortran interface is not autogenerated as the f90
6208     interface defintion cannot be generated correctly [due to MatFactorInfo]
6209 
6210 @*/
6211 PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6212 {
6213   PetscErrorCode ierr;
6214 
6215   PetscFunctionBegin;
6216   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6217   PetscValidType(mat,1);
6218   PetscValidHeaderSpecific(perm,IS_CLASSID,2);
6219   PetscValidPointer(info,3);
6220   PetscValidPointer(fact,4);
6221   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6222   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6223   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6224   if (!(fact)->ops->iccfactorsymbolic) {
6225     const MatSolverPackage spackage;
6226     ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr);
6227     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6228   }
6229   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6230   MatCheckPreallocated(mat,2);
6231 
6232   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6233   ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr);
6234   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
6235   PetscFunctionReturn(0);
6236 }
6237 
6238 #undef __FUNCT__
6239 #define __FUNCT__ "MatGetArray"
6240 /*@C
6241    MatGetArray - Returns a pointer to the element values in the matrix.
6242    The result of this routine is dependent on the underlying matrix data
6243    structure, and may not even work for certain matrix types.  You MUST
6244    call MatRestoreArray() when you no longer need to access the array.
6245 
6246    Not Collective
6247 
6248    Input Parameter:
6249 .  mat - the matrix
6250 
6251    Output Parameter:
6252 .  v - the location of the values
6253 
6254 
6255    Fortran Note:
6256    This routine is used differently from Fortran, e.g.,
6257 .vb
6258         Mat         mat
6259         PetscScalar mat_array(1)
6260         PetscOffset i_mat
6261         PetscErrorCode ierr
6262         call MatGetArray(mat,mat_array,i_mat,ierr)
6263 
6264   C  Access first local entry in matrix; note that array is
6265   C  treated as one dimensional
6266         value = mat_array(i_mat + 1)
6267 
6268         [... other code ...]
6269         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6270 .ve
6271 
6272    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and
6273    src/mat/examples/tests for details.
6274 
6275    Level: advanced
6276 
6277    Concepts: matrices^access array
6278 
6279 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6280 @*/
6281 PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6282 {
6283   PetscErrorCode ierr;
6284 
6285   PetscFunctionBegin;
6286   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6287   PetscValidType(mat,1);
6288   PetscValidPointer(v,2);
6289   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6290   MatCheckPreallocated(mat,1);
6291   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
6292   CHKMEMQ;
6293   PetscFunctionReturn(0);
6294 }
6295 
6296 #undef __FUNCT__
6297 #define __FUNCT__ "MatRestoreArray"
6298 /*@C
6299    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
6300 
6301    Not Collective
6302 
6303    Input Parameter:
6304 +  mat - the matrix
6305 -  v - the location of the values
6306 
6307    Fortran Note:
6308    This routine is used differently from Fortran, e.g.,
6309 .vb
6310         Mat         mat
6311         PetscScalar mat_array(1)
6312         PetscOffset i_mat
6313         PetscErrorCode ierr
6314         call MatGetArray(mat,mat_array,i_mat,ierr)
6315 
6316   C  Access first local entry in matrix; note that array is
6317   C  treated as one dimensional
6318         value = mat_array(i_mat + 1)
6319 
6320         [... other code ...]
6321         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6322 .ve
6323 
6324    See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a>
6325    src/mat/examples/tests for details
6326 
6327    Level: advanced
6328 
6329 .seealso: MatGetArray(), MatRestoreArrayF90()
6330 @*/
6331 PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6332 {
6333   PetscErrorCode ierr;
6334 
6335   PetscFunctionBegin;
6336   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6337   PetscValidType(mat,1);
6338   PetscValidPointer(v,2);
6339   CHKMEMQ;
6340   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6341   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
6342   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
6343 #if defined(PETSC_HAVE_CUSP)
6344   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6345     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6346   }
6347 #endif
6348   PetscFunctionReturn(0);
6349 }
6350 
6351 #undef __FUNCT__
6352 #define __FUNCT__ "MatGetSubMatrices"
6353 /*@C
6354    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6355    points to an array of valid matrices, they may be reused to store the new
6356    submatrices.
6357 
6358    Collective on Mat
6359 
6360    Input Parameters:
6361 +  mat - the matrix
6362 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6363 .  irow, icol - index sets of rows and columns to extract (must be sorted)
6364 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6365 
6366    Output Parameter:
6367 .  submat - the array of submatrices
6368 
6369    Notes:
6370    MatGetSubMatrices() can extract ONLY sequential submatrices
6371    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6372    to extract a parallel submatrix.
6373 
6374    Currently both row and column indices must be sorted to guarantee
6375    correctness with all matrix types.
6376 
6377    When extracting submatrices from a parallel matrix, each processor can
6378    form a different submatrix by setting the rows and columns of its
6379    individual index sets according to the local submatrix desired.
6380 
6381    When finished using the submatrices, the user should destroy
6382    them with MatDestroyMatrices().
6383 
6384    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6385    original matrix has not changed from that last call to MatGetSubMatrices().
6386 
6387    This routine creates the matrices in submat; you should NOT create them before
6388    calling it. It also allocates the array of matrix pointers submat.
6389 
6390    For BAIJ matrices the index sets must respect the block structure, that is if they
6391    request one row/column in a block, they must request all rows/columns that are in
6392    that block. For example, if the block size is 2 you cannot request just row 0 and
6393    column 0.
6394 
6395    Fortran Note:
6396    The Fortran interface is slightly different from that given below; it
6397    requires one to pass in  as submat a Mat (integer) array of size at least m.
6398 
6399    Level: advanced
6400 
6401    Concepts: matrices^accessing submatrices
6402    Concepts: submatrices
6403 
6404 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6405 @*/
6406 PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6407 {
6408   PetscErrorCode ierr;
6409   PetscInt        i;
6410   PetscBool       eq;
6411 
6412   PetscFunctionBegin;
6413   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6414   PetscValidType(mat,1);
6415   if (n) {
6416     PetscValidPointer(irow,3);
6417     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6418     PetscValidPointer(icol,4);
6419     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6420   }
6421   PetscValidPointer(submat,6);
6422   if (n && scall == MAT_REUSE_MATRIX) {
6423     PetscValidPointer(*submat,6);
6424     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6425   }
6426   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6427   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6428   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6429   MatCheckPreallocated(mat,1);
6430 
6431   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6432   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6433   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6434   for (i=0; i<n; i++) {
6435     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6436       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6437       if (eq) {
6438 	if (mat->symmetric){
6439 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6440 	} else if (mat->hermitian) {
6441 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6442 	} else if (mat->structurally_symmetric) {
6443 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6444 	}
6445       }
6446     }
6447   }
6448   PetscFunctionReturn(0);
6449 }
6450 
6451 #undef __FUNCT__
6452 #define __FUNCT__ "MatGetSubMatricesParallel"
6453 PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6454 {
6455   PetscErrorCode ierr;
6456   PetscInt        i;
6457   PetscBool       eq;
6458 
6459   PetscFunctionBegin;
6460   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6461   PetscValidType(mat,1);
6462   if (n) {
6463     PetscValidPointer(irow,3);
6464     PetscValidHeaderSpecific(*irow,IS_CLASSID,3);
6465     PetscValidPointer(icol,4);
6466     PetscValidHeaderSpecific(*icol,IS_CLASSID,4);
6467   }
6468   PetscValidPointer(submat,6);
6469   if (n && scall == MAT_REUSE_MATRIX) {
6470     PetscValidPointer(*submat,6);
6471     PetscValidHeaderSpecific(**submat,MAT_CLASSID,6);
6472   }
6473   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6474   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6475   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6476   MatCheckPreallocated(mat,1);
6477 
6478   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6479   ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
6480   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
6481   for (i=0; i<n; i++) {
6482     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6483       ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr);
6484       if (eq) {
6485 	if (mat->symmetric){
6486 	  ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6487 	} else if (mat->hermitian) {
6488 	  ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
6489 	} else if (mat->structurally_symmetric) {
6490 	  ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
6491 	}
6492       }
6493     }
6494   }
6495   PetscFunctionReturn(0);
6496 }
6497 
6498 #undef __FUNCT__
6499 #define __FUNCT__ "MatDestroyMatrices"
6500 /*@C
6501    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6502 
6503    Collective on Mat
6504 
6505    Input Parameters:
6506 +  n - the number of local matrices
6507 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6508                        sequence of MatGetSubMatrices())
6509 
6510    Level: advanced
6511 
6512     Notes: Frees not only the matrices, but also the array that contains the matrices
6513            In Fortran will not free the array.
6514 
6515 .seealso: MatGetSubMatrices()
6516 @*/
6517 PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6518 {
6519   PetscErrorCode ierr;
6520   PetscInt       i;
6521 
6522   PetscFunctionBegin;
6523   if (!*mat) PetscFunctionReturn(0);
6524   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6525   PetscValidPointer(mat,2);
6526   for (i=0; i<n; i++) {
6527     ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr);
6528   }
6529   /* memory is allocated even if n = 0 */
6530   ierr = PetscFree(*mat);CHKERRQ(ierr);
6531   *mat = PETSC_NULL;
6532   PetscFunctionReturn(0);
6533 }
6534 
6535 #undef __FUNCT__
6536 #define __FUNCT__ "MatGetSeqNonzeroStructure"
6537 /*@C
6538    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6539 
6540    Collective on Mat
6541 
6542    Input Parameters:
6543 .  mat - the matrix
6544 
6545    Output Parameter:
6546 .  matstruct - the sequential matrix with the nonzero structure of mat
6547 
6548   Level: intermediate
6549 
6550 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6551 @*/
6552 PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6553 {
6554   PetscErrorCode ierr;
6555 
6556   PetscFunctionBegin;
6557   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6558   PetscValidPointer(matstruct,2);
6559 
6560   PetscValidType(mat,1);
6561   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6562   MatCheckPreallocated(mat,1);
6563 
6564   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6565   ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6566   ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr);
6567   ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr);
6568   PetscFunctionReturn(0);
6569 }
6570 
6571 #undef __FUNCT__
6572 #define __FUNCT__ "MatDestroySeqNonzeroStructure"
6573 /*@C
6574    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6575 
6576    Collective on Mat
6577 
6578    Input Parameters:
6579 .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6580                        sequence of MatGetSequentialNonzeroStructure())
6581 
6582    Level: advanced
6583 
6584     Notes: Frees not only the matrices, but also the array that contains the matrices
6585 
6586 .seealso: MatGetSeqNonzeroStructure()
6587 @*/
6588 PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6589 {
6590   PetscErrorCode ierr;
6591 
6592   PetscFunctionBegin;
6593   PetscValidPointer(mat,1);
6594   ierr = MatDestroy(mat);CHKERRQ(ierr);
6595   PetscFunctionReturn(0);
6596 }
6597 
6598 #undef __FUNCT__
6599 #define __FUNCT__ "MatIncreaseOverlap"
6600 /*@
6601    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6602    replaces the index sets by larger ones that represent submatrices with
6603    additional overlap.
6604 
6605    Collective on Mat
6606 
6607    Input Parameters:
6608 +  mat - the matrix
6609 .  n   - the number of index sets
6610 .  is  - the array of index sets (these index sets will changed during the call)
6611 -  ov  - the additional overlap requested
6612 
6613    Level: developer
6614 
6615    Concepts: overlap
6616    Concepts: ASM^computing overlap
6617 
6618 .seealso: MatGetSubMatrices()
6619 @*/
6620 PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6621 {
6622   PetscErrorCode ierr;
6623 
6624   PetscFunctionBegin;
6625   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6626   PetscValidType(mat,1);
6627   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6628   if (n) {
6629     PetscValidPointer(is,3);
6630     PetscValidHeaderSpecific(*is,IS_CLASSID,3);
6631   }
6632   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6633   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6634   MatCheckPreallocated(mat,1);
6635 
6636   if (!ov) PetscFunctionReturn(0);
6637   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6638   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6639   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
6640   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
6641   PetscFunctionReturn(0);
6642 }
6643 
6644 #undef __FUNCT__
6645 #define __FUNCT__ "MatGetBlockSize"
6646 /*@
6647    MatGetBlockSize - Returns the matrix block size; useful especially for the
6648    block row and block diagonal formats.
6649 
6650    Not Collective
6651 
6652    Input Parameter:
6653 .  mat - the matrix
6654 
6655    Output Parameter:
6656 .  bs - block size
6657 
6658    Notes:
6659    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6660 
6661    Level: intermediate
6662 
6663    Concepts: matrices^block size
6664 
6665 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6666 @*/
6667 PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6668 {
6669 
6670   PetscFunctionBegin;
6671   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6672   PetscValidType(mat,1);
6673   PetscValidIntPointer(bs,2);
6674   MatCheckPreallocated(mat,1);
6675   *bs = mat->rmap->bs;
6676   PetscFunctionReturn(0);
6677 }
6678 
6679 #undef __FUNCT__
6680 #define __FUNCT__ "MatGetBlockSizes"
6681 /*@
6682    MatGetBlockSizes - Returns the matrix block row and column sizes;
6683    useful especially for the block row and block diagonal formats.
6684 
6685    Not Collective
6686 
6687    Input Parameter:
6688 .  mat - the matrix
6689 
6690    Output Parameter:
6691 .  rbs - row block size
6692 .  cbs - coumn block size
6693 
6694    Notes:
6695    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6696 
6697    Level: intermediate
6698 
6699    Concepts: matrices^block size
6700 
6701 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6702 @*/
6703 PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6704 {
6705 
6706   PetscFunctionBegin;
6707   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6708   PetscValidType(mat,1);
6709   if(rbs) PetscValidIntPointer(rbs,2);
6710   if(cbs) PetscValidIntPointer(cbs,3);
6711   MatCheckPreallocated(mat,1);
6712   if(rbs) *rbs = mat->rmap->bs;
6713   if(cbs) *cbs = mat->cmap->bs;
6714   PetscFunctionReturn(0);
6715 }
6716 
6717 #undef __FUNCT__
6718 #define __FUNCT__ "MatSetBlockSize"
6719 /*@
6720    MatSetBlockSize - Sets the matrix block size.
6721 
6722    Logically Collective on Mat
6723 
6724    Input Parameters:
6725 +  mat - the matrix
6726 -  bs - block size
6727 
6728    Notes:
6729      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6730 
6731    Level: intermediate
6732 
6733    Concepts: matrices^block size
6734 
6735 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6736 @*/
6737 PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6738 {
6739   PetscErrorCode ierr;
6740 
6741   PetscFunctionBegin;
6742   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6743   PetscValidLogicalCollectiveInt(mat,bs,2);
6744   ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr);
6745   ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr);
6746   PetscFunctionReturn(0);
6747 }
6748 
6749 #undef __FUNCT__
6750 #define __FUNCT__ "MatSetBlockSizes"
6751 /*@
6752    MatSetBlockSizes - Sets the matrix block row and column sizes.
6753 
6754    Logically Collective on Mat
6755 
6756    Input Parameters:
6757 +  mat - the matrix
6758 -  rbs - row block size
6759 -  cbs - column block size
6760 
6761    Notes:
6762      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6763 
6764    Level: intermediate
6765 
6766    Concepts: matrices^block size
6767 
6768 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6769 @*/
6770 PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6771 {
6772   PetscErrorCode ierr;
6773 
6774   PetscFunctionBegin;
6775   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6776   PetscValidLogicalCollectiveInt(mat,rbs,2);
6777   ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr);
6778   ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr);
6779   PetscFunctionReturn(0);
6780 }
6781 
6782 #undef __FUNCT__
6783 #define __FUNCT__ "MatGetRowIJ"
6784 /*@C
6785     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6786 
6787    Collective on Mat
6788 
6789     Input Parameters:
6790 +   mat - the matrix
6791 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6792 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6793 -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6794                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6795                  always used.
6796 
6797     Output Parameters:
6798 +   n - number of rows in the (possibly compressed) matrix
6799 .   ia - the row pointers [of length n+1]
6800 .   ja - the column indices
6801 -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6802            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6803 
6804     Level: developer
6805 
6806     Notes: You CANNOT change any of the ia[] or ja[] values.
6807 
6808            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6809 
6810     Fortran Node
6811 
6812            In Fortran use
6813 $           PetscInt ia(1), ja(1)
6814 $           PetscOffset iia, jja
6815 $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6816 $
6817 $          or
6818 $
6819 $           PetscScalar, pointer :: xx_v(:)
6820 $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6821 
6822 
6823        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6824 
6825 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6826 @*/
6827 PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6828 {
6829   PetscErrorCode ierr;
6830 
6831   PetscFunctionBegin;
6832   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6833   PetscValidType(mat,1);
6834   PetscValidIntPointer(n,4);
6835   if (ia) PetscValidIntPointer(ia,5);
6836   if (ja) PetscValidIntPointer(ja,6);
6837   PetscValidIntPointer(done,7);
6838   MatCheckPreallocated(mat,1);
6839   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6840   else {
6841     *done = PETSC_TRUE;
6842     ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6843     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6844     ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr);
6845   }
6846   PetscFunctionReturn(0);
6847 }
6848 
6849 #undef __FUNCT__
6850 #define __FUNCT__ "MatGetColumnIJ"
6851 /*@C
6852     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6853 
6854     Collective on Mat
6855 
6856     Input Parameters:
6857 +   mat - the matrix
6858 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6859 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6860                 symmetrized
6861 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6862                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6863                  always used.
6864 
6865     Output Parameters:
6866 +   n - number of columns in the (possibly compressed) matrix
6867 .   ia - the column pointers
6868 .   ja - the row indices
6869 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6870 
6871     Level: developer
6872 
6873 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6874 @*/
6875 PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6876 {
6877   PetscErrorCode ierr;
6878 
6879   PetscFunctionBegin;
6880   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6881   PetscValidType(mat,1);
6882   PetscValidIntPointer(n,4);
6883   if (ia) PetscValidIntPointer(ia,5);
6884   if (ja) PetscValidIntPointer(ja,6);
6885   PetscValidIntPointer(done,7);
6886   MatCheckPreallocated(mat,1);
6887   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6888   else {
6889     *done = PETSC_TRUE;
6890     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6891   }
6892   PetscFunctionReturn(0);
6893 }
6894 
6895 #undef __FUNCT__
6896 #define __FUNCT__ "MatRestoreRowIJ"
6897 /*@C
6898     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6899     MatGetRowIJ().
6900 
6901     Collective on Mat
6902 
6903     Input Parameters:
6904 +   mat - the matrix
6905 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6906 .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6907                 symmetrized
6908 -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6909                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6910                  always used.
6911 
6912     Output Parameters:
6913 +   n - size of (possibly compressed) matrix
6914 .   ia - the row pointers
6915 .   ja - the column indices
6916 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6917 
6918     Level: developer
6919 
6920 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6921 @*/
6922 PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6923 {
6924   PetscErrorCode ierr;
6925 
6926   PetscFunctionBegin;
6927   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6928   PetscValidType(mat,1);
6929   if (ia) PetscValidIntPointer(ia,5);
6930   if (ja) PetscValidIntPointer(ja,6);
6931   PetscValidIntPointer(done,7);
6932   MatCheckPreallocated(mat,1);
6933 
6934   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6935   else {
6936     *done = PETSC_TRUE;
6937     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6938   }
6939   PetscFunctionReturn(0);
6940 }
6941 
6942 #undef __FUNCT__
6943 #define __FUNCT__ "MatRestoreColumnIJ"
6944 /*@C
6945     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6946     MatGetColumnIJ().
6947 
6948     Collective on Mat
6949 
6950     Input Parameters:
6951 +   mat - the matrix
6952 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6953 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6954                 symmetrized
6955 -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6956                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6957                  always used.
6958 
6959     Output Parameters:
6960 +   n - size of (possibly compressed) matrix
6961 .   ia - the column pointers
6962 .   ja - the row indices
6963 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6964 
6965     Level: developer
6966 
6967 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6968 @*/
6969 PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6970 {
6971   PetscErrorCode ierr;
6972 
6973   PetscFunctionBegin;
6974   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
6975   PetscValidType(mat,1);
6976   if (ia) PetscValidIntPointer(ia,5);
6977   if (ja) PetscValidIntPointer(ja,6);
6978   PetscValidIntPointer(done,7);
6979   MatCheckPreallocated(mat,1);
6980 
6981   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6982   else {
6983     *done = PETSC_TRUE;
6984     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr);
6985   }
6986   PetscFunctionReturn(0);
6987 }
6988 
6989 #undef __FUNCT__
6990 #define __FUNCT__ "MatColoringPatch"
6991 /*@C
6992     MatColoringPatch -Used inside matrix coloring routines that
6993     use MatGetRowIJ() and/or MatGetColumnIJ().
6994 
6995     Collective on Mat
6996 
6997     Input Parameters:
6998 +   mat - the matrix
6999 .   ncolors - max color value
7000 .   n   - number of entries in colorarray
7001 -   colorarray - array indicating color for each column
7002 
7003     Output Parameters:
7004 .   iscoloring - coloring generated using colorarray information
7005 
7006     Level: developer
7007 
7008 .seealso: MatGetRowIJ(), MatGetColumnIJ()
7009 
7010 @*/
7011 PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7012 {
7013   PetscErrorCode ierr;
7014 
7015   PetscFunctionBegin;
7016   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7017   PetscValidType(mat,1);
7018   PetscValidIntPointer(colorarray,4);
7019   PetscValidPointer(iscoloring,5);
7020   MatCheckPreallocated(mat,1);
7021 
7022   if (!mat->ops->coloringpatch){
7023     ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7024   } else {
7025     ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr);
7026   }
7027   PetscFunctionReturn(0);
7028 }
7029 
7030 
7031 #undef __FUNCT__
7032 #define __FUNCT__ "MatSetUnfactored"
7033 /*@
7034    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7035 
7036    Logically Collective on Mat
7037 
7038    Input Parameter:
7039 .  mat - the factored matrix to be reset
7040 
7041    Notes:
7042    This routine should be used only with factored matrices formed by in-place
7043    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7044    format).  This option can save memory, for example, when solving nonlinear
7045    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7046    ILU(0) preconditioner.
7047 
7048    Note that one can specify in-place ILU(0) factorization by calling
7049 .vb
7050      PCType(pc,PCILU);
7051      PCFactorSeUseInPlace(pc);
7052 .ve
7053    or by using the options -pc_type ilu -pc_factor_in_place
7054 
7055    In-place factorization ILU(0) can also be used as a local
7056    solver for the blocks within the block Jacobi or additive Schwarz
7057    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
7058    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7059    local solver options.
7060 
7061    Most users should employ the simplified KSP interface for linear solvers
7062    instead of working directly with matrix algebra routines such as this.
7063    See, e.g., KSPCreate().
7064 
7065    Level: developer
7066 
7067 .seealso: PCFactorSetUseInPlace()
7068 
7069    Concepts: matrices^unfactored
7070 
7071 @*/
7072 PetscErrorCode  MatSetUnfactored(Mat mat)
7073 {
7074   PetscErrorCode ierr;
7075 
7076   PetscFunctionBegin;
7077   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7078   PetscValidType(mat,1);
7079   MatCheckPreallocated(mat,1);
7080   mat->factortype = MAT_FACTOR_NONE;
7081   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
7082   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
7083   PetscFunctionReturn(0);
7084 }
7085 
7086 /*MC
7087     MatGetArrayF90 - Accesses a matrix array from Fortran90.
7088 
7089     Synopsis:
7090     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7091 
7092     Not collective
7093 
7094     Input Parameter:
7095 .   x - matrix
7096 
7097     Output Parameters:
7098 +   xx_v - the Fortran90 pointer to the array
7099 -   ierr - error code
7100 
7101     Example of Usage:
7102 .vb
7103       PetscScalar, pointer xx_v(:,:)
7104       ....
7105       call MatGetArrayF90(x,xx_v,ierr)
7106       a = xx_v(3)
7107       call MatRestoreArrayF90(x,xx_v,ierr)
7108 .ve
7109 
7110     Notes:
7111     Not yet supported for all F90 compilers
7112 
7113     Level: advanced
7114 
7115 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
7116 
7117     Concepts: matrices^accessing array
7118 
7119 M*/
7120 
7121 /*MC
7122     MatRestoreArrayF90 - Restores a matrix array that has been
7123     accessed with MatGetArrayF90().
7124 
7125     Synopsis:
7126     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7127 
7128     Not collective
7129 
7130     Input Parameters:
7131 +   x - matrix
7132 -   xx_v - the Fortran90 pointer to the array
7133 
7134     Output Parameter:
7135 .   ierr - error code
7136 
7137     Example of Usage:
7138 .vb
7139        PetscScalar, pointer xx_v(:)
7140        ....
7141        call MatGetArrayF90(x,xx_v,ierr)
7142        a = xx_v(3)
7143        call MatRestoreArrayF90(x,xx_v,ierr)
7144 .ve
7145 
7146     Notes:
7147     Not yet supported for all F90 compilers
7148 
7149     Level: advanced
7150 
7151 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
7152 
7153 M*/
7154 
7155 
7156 #undef __FUNCT__
7157 #define __FUNCT__ "MatGetSubMatrix"
7158 /*@
7159     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7160                       as the original matrix.
7161 
7162     Collective on Mat
7163 
7164     Input Parameters:
7165 +   mat - the original matrix
7166 .   isrow - parallel IS containing the rows this processor should obtain
7167 .   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.
7168 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7169 
7170     Output Parameter:
7171 .   newmat - the new submatrix, of the same type as the old
7172 
7173     Level: advanced
7174 
7175     Notes:
7176     The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7177 
7178     The rows in isrow will be sorted into the same order as the original matrix on each process.
7179 
7180       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7181    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7182    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7183    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
7184    you are finished using it.
7185 
7186     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7187     the input matrix.
7188 
7189     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).
7190 
7191    Example usage:
7192    Consider the following 8x8 matrix with 34 non-zero values, that is
7193    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7194    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7195    as follows:
7196 
7197 .vb
7198             1  2  0  |  0  3  0  |  0  4
7199     Proc0   0  5  6  |  7  0  0  |  8  0
7200             9  0 10  | 11  0  0  | 12  0
7201     -------------------------------------
7202            13  0 14  | 15 16 17  |  0  0
7203     Proc1   0 18  0  | 19 20 21  |  0  0
7204             0  0  0  | 22 23  0  | 24  0
7205     -------------------------------------
7206     Proc2  25 26 27  |  0  0 28  | 29  0
7207            30  0  0  | 31 32 33  |  0 34
7208 .ve
7209 
7210     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is
7211 
7212 .vb
7213             2  0  |  0  3  0  |  0
7214     Proc0   5  6  |  7  0  0  |  8
7215     -------------------------------
7216     Proc1  18  0  | 19 20 21  |  0
7217     -------------------------------
7218     Proc2  26 27  |  0  0 28  | 29
7219             0  0  | 31 32 33  |  0
7220 .ve
7221 
7222 
7223     Concepts: matrices^submatrices
7224 
7225 .seealso: MatGetSubMatrices()
7226 @*/
7227 PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7228 {
7229   PetscErrorCode ierr;
7230   PetscMPIInt    size;
7231   Mat            *local;
7232   IS             iscoltmp;
7233 
7234   PetscFunctionBegin;
7235   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7236   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
7237   if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
7238   PetscValidPointer(newmat,5);
7239   if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5);
7240   PetscValidType(mat,1);
7241   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7242   MatCheckPreallocated(mat,1);
7243   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7244 
7245   if (!iscol) {
7246     ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr);
7247   } else {
7248     iscoltmp = iscol;
7249   }
7250 
7251   /* if original matrix is on just one processor then use submatrix generated */
7252   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7253     ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
7254     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7255     PetscFunctionReturn(0);
7256   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7257     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
7258     *newmat = *local;
7259     ierr    = PetscFree(local);CHKERRQ(ierr);
7260     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7261     PetscFunctionReturn(0);
7262   } else if (!mat->ops->getsubmatrix) {
7263     /* Create a new matrix type that implements the operation using the full matrix */
7264     switch (cll) {
7265       case MAT_INITIAL_MATRIX:
7266         ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr);
7267         break;
7268       case MAT_REUSE_MATRIX:
7269         ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr);
7270         break;
7271       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7272     }
7273     if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7274     PetscFunctionReturn(0);
7275   }
7276 
7277   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7278   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr);
7279   if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);}
7280   if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);}
7281   PetscFunctionReturn(0);
7282 }
7283 
7284 #undef __FUNCT__
7285 #define __FUNCT__ "MatStashSetInitialSize"
7286 /*@
7287    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7288    used during the assembly process to store values that belong to
7289    other processors.
7290 
7291    Not Collective
7292 
7293    Input Parameters:
7294 +  mat   - the matrix
7295 .  size  - the initial size of the stash.
7296 -  bsize - the initial size of the block-stash(if used).
7297 
7298    Options Database Keys:
7299 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7300 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
7301 
7302    Level: intermediate
7303 
7304    Notes:
7305      The block-stash is used for values set with MatSetValuesBlocked() while
7306      the stash is used for values set with MatSetValues()
7307 
7308      Run with the option -info and look for output of the form
7309      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7310      to determine the appropriate value, MM, to use for size and
7311      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7312      to determine the value, BMM to use for bsize
7313 
7314    Concepts: stash^setting matrix size
7315    Concepts: matrices^stash
7316 
7317 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7318 
7319 @*/
7320 PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7321 {
7322   PetscErrorCode ierr;
7323 
7324   PetscFunctionBegin;
7325   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7326   PetscValidType(mat,1);
7327   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
7328   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
7329   PetscFunctionReturn(0);
7330 }
7331 
7332 #undef __FUNCT__
7333 #define __FUNCT__ "MatInterpolateAdd"
7334 /*@
7335    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7336      the matrix
7337 
7338    Neighbor-wise Collective on Mat
7339 
7340    Input Parameters:
7341 +  mat   - the matrix
7342 .  x,y - the vectors
7343 -  w - where the result is stored
7344 
7345    Level: intermediate
7346 
7347    Notes:
7348     w may be the same vector as y.
7349 
7350     This allows one to use either the restriction or interpolation (its transpose)
7351     matrix to do the interpolation
7352 
7353     Concepts: interpolation
7354 
7355 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7356 
7357 @*/
7358 PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7359 {
7360   PetscErrorCode ierr;
7361   PetscInt       M,N,Ny;
7362 
7363   PetscFunctionBegin;
7364   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7365   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7366   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7367   PetscValidHeaderSpecific(w,VEC_CLASSID,4);
7368   PetscValidType(A,1);
7369   MatCheckPreallocated(A,1);
7370   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7371   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7372   if (M == Ny) {
7373     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
7374   } else {
7375     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
7376   }
7377   PetscFunctionReturn(0);
7378 }
7379 
7380 #undef __FUNCT__
7381 #define __FUNCT__ "MatInterpolate"
7382 /*@
7383    MatInterpolate - y = A*x or A'*x depending on the shape of
7384      the matrix
7385 
7386    Neighbor-wise Collective on Mat
7387 
7388    Input Parameters:
7389 +  mat   - the matrix
7390 -  x,y - the vectors
7391 
7392    Level: intermediate
7393 
7394    Notes:
7395     This allows one to use either the restriction or interpolation (its transpose)
7396     matrix to do the interpolation
7397 
7398    Concepts: matrices^interpolation
7399 
7400 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7401 
7402 @*/
7403 PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7404 {
7405   PetscErrorCode ierr;
7406   PetscInt       M,N,Ny;
7407 
7408   PetscFunctionBegin;
7409   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7410   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7411   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7412   PetscValidType(A,1);
7413   MatCheckPreallocated(A,1);
7414   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7415   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7416   if (M == Ny) {
7417     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7418   } else {
7419     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7420   }
7421   PetscFunctionReturn(0);
7422 }
7423 
7424 #undef __FUNCT__
7425 #define __FUNCT__ "MatRestrict"
7426 /*@
7427    MatRestrict - y = A*x or A'*x
7428 
7429    Neighbor-wise Collective on Mat
7430 
7431    Input Parameters:
7432 +  mat   - the matrix
7433 -  x,y - the vectors
7434 
7435    Level: intermediate
7436 
7437    Notes:
7438     This allows one to use either the restriction or interpolation (its transpose)
7439     matrix to do the restriction
7440 
7441    Concepts: matrices^restriction
7442 
7443 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7444 
7445 @*/
7446 PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7447 {
7448   PetscErrorCode ierr;
7449   PetscInt       M,N,Ny;
7450 
7451   PetscFunctionBegin;
7452   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7453   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
7454   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
7455   PetscValidType(A,1);
7456   MatCheckPreallocated(A,1);
7457 
7458   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
7459   ierr = VecGetSize(y,&Ny);CHKERRQ(ierr);
7460   if (M == Ny) {
7461     ierr = MatMult(A,x,y);CHKERRQ(ierr);
7462   } else {
7463     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
7464   }
7465   PetscFunctionReturn(0);
7466 }
7467 
7468 #undef __FUNCT__
7469 #define __FUNCT__ "MatGetNullSpace"
7470 /*@
7471    MatGetNullSpace - retrieves the null space to a matrix.
7472 
7473    Logically Collective on Mat and MatNullSpace
7474 
7475    Input Parameters:
7476 +  mat - the matrix
7477 -  nullsp - the null space object
7478 
7479    Level: developer
7480 
7481    Notes:
7482       This null space is used by solvers. Overwrites any previous null space that may have been attached
7483 
7484    Concepts: null space^attaching to matrix
7485 
7486 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7487 @*/
7488 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7489 {
7490   PetscFunctionBegin;
7491   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7492   PetscValidType(mat,1);
7493   PetscValidPointer(nullsp,2);
7494   *nullsp = mat->nullsp;
7495   PetscFunctionReturn(0);
7496 }
7497 
7498 #undef __FUNCT__
7499 #define __FUNCT__ "MatSetNullSpace"
7500 /*@
7501    MatSetNullSpace - attaches a null space to a matrix.
7502         This null space will be removed from the resulting vector whenever
7503         MatMult() is called
7504 
7505    Logically Collective on Mat and MatNullSpace
7506 
7507    Input Parameters:
7508 +  mat - the matrix
7509 -  nullsp - the null space object
7510 
7511    Level: advanced
7512 
7513    Notes:
7514       This null space is used by solvers. Overwrites any previous null space that may have been attached
7515 
7516    Concepts: null space^attaching to matrix
7517 
7518 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7519 @*/
7520 PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7521 {
7522   PetscErrorCode ierr;
7523 
7524   PetscFunctionBegin;
7525   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7526   PetscValidType(mat,1);
7527   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7528   MatCheckPreallocated(mat,1);
7529   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7530   ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr);
7531   mat->nullsp = nullsp;
7532   PetscFunctionReturn(0);
7533 }
7534 
7535 #undef __FUNCT__
7536 #define __FUNCT__ "MatSetNearNullSpace"
7537 /*@
7538    MatSetNearNullSpace - attaches a null space to a matrix.
7539         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7540 
7541    Logically Collective on Mat and MatNullSpace
7542 
7543    Input Parameters:
7544 +  mat - the matrix
7545 -  nullsp - the null space object
7546 
7547    Level: advanced
7548 
7549    Notes:
7550       Overwrites any previous near null space that may have been attached
7551 
7552    Concepts: null space^attaching to matrix
7553 
7554 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7555 @*/
7556 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7557 {
7558   PetscErrorCode ierr;
7559 
7560   PetscFunctionBegin;
7561   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7562   PetscValidType(mat,1);
7563   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2);
7564   MatCheckPreallocated(mat,1);
7565   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
7566   ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr);
7567   mat->nearnullsp = nullsp;
7568   PetscFunctionReturn(0);
7569 }
7570 
7571 #undef __FUNCT__
7572 #define __FUNCT__ "MatGetNearNullSpace"
7573 /*@
7574    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7575 
7576    Not Collective
7577 
7578    Input Parameters:
7579 .  mat - the matrix
7580 
7581    Output Parameters:
7582 .  nullsp - the null space object, PETSC_NULL if not set
7583 
7584    Level: developer
7585 
7586    Concepts: null space^attaching to matrix
7587 
7588 .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7589 @*/
7590 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7591 {
7592 
7593   PetscFunctionBegin;
7594   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7595   PetscValidType(mat,1);
7596   PetscValidPointer(nullsp,2);
7597   MatCheckPreallocated(mat,1);
7598   *nullsp = mat->nearnullsp;
7599   PetscFunctionReturn(0);
7600 }
7601 
7602 #undef __FUNCT__
7603 #define __FUNCT__ "MatICCFactor"
7604 /*@C
7605    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7606 
7607    Collective on Mat
7608 
7609    Input Parameters:
7610 +  mat - the matrix
7611 .  row - row/column permutation
7612 .  fill - expected fill factor >= 1.0
7613 -  level - level of fill, for ICC(k)
7614 
7615    Notes:
7616    Probably really in-place only when level of fill is zero, otherwise allocates
7617    new space to store factored matrix and deletes previous memory.
7618 
7619    Most users should employ the simplified KSP interface for linear solvers
7620    instead of working directly with matrix algebra routines such as this.
7621    See, e.g., KSPCreate().
7622 
7623    Level: developer
7624 
7625    Concepts: matrices^incomplete Cholesky factorization
7626    Concepts: Cholesky factorization
7627 
7628 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7629 
7630     Developer Note: fortran interface is not autogenerated as the f90
7631     interface defintion cannot be generated correctly [due to MatFactorInfo]
7632 
7633 @*/
7634 PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7635 {
7636   PetscErrorCode ierr;
7637 
7638   PetscFunctionBegin;
7639   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7640   PetscValidType(mat,1);
7641   if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2);
7642   PetscValidPointer(info,3);
7643   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7644   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7645   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7646   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7647   MatCheckPreallocated(mat,1);
7648   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
7649   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7650   PetscFunctionReturn(0);
7651 }
7652 
7653 #undef __FUNCT__
7654 #define __FUNCT__ "MatSetValuesAdic"
7655 /*@
7656    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
7657 
7658    Not Collective
7659 
7660    Input Parameters:
7661 +  mat - the matrix
7662 -  v - the values compute with ADIC
7663 
7664    Level: developer
7665 
7666    Notes:
7667      Must call MatSetColoring() before using this routine. Also this matrix must already
7668      have its nonzero pattern determined.
7669 
7670 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7671           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7672 @*/
7673 PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7674 {
7675   PetscErrorCode ierr;
7676 
7677   PetscFunctionBegin;
7678   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7679   PetscValidType(mat,1);
7680   PetscValidPointer(mat,2);
7681 
7682   if (!mat->assembled) {
7683     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7684   }
7685   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7686   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7687   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
7688   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7689   ierr = MatView_Private(mat);CHKERRQ(ierr);
7690   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7691   PetscFunctionReturn(0);
7692 }
7693 
7694 
7695 #undef __FUNCT__
7696 #define __FUNCT__ "MatSetColoring"
7697 /*@
7698    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
7699 
7700    Not Collective
7701 
7702    Input Parameters:
7703 +  mat - the matrix
7704 -  coloring - the coloring
7705 
7706    Level: developer
7707 
7708 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7709           MatSetValues(), MatSetValuesAdic()
7710 @*/
7711 PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7712 {
7713   PetscErrorCode ierr;
7714 
7715   PetscFunctionBegin;
7716   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7717   PetscValidType(mat,1);
7718   PetscValidPointer(coloring,2);
7719 
7720   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7721   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7722   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
7723   PetscFunctionReturn(0);
7724 }
7725 
7726 #undef __FUNCT__
7727 #define __FUNCT__ "MatSetValuesAdifor"
7728 /*@
7729    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7730 
7731    Not Collective
7732 
7733    Input Parameters:
7734 +  mat - the matrix
7735 .  nl - leading dimension of v
7736 -  v - the values compute with ADIFOR
7737 
7738    Level: developer
7739 
7740    Notes:
7741      Must call MatSetColoring() before using this routine. Also this matrix must already
7742      have its nonzero pattern determined.
7743 
7744 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7745           MatSetValues(), MatSetColoring()
7746 @*/
7747 PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7748 {
7749   PetscErrorCode ierr;
7750 
7751   PetscFunctionBegin;
7752   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7753   PetscValidType(mat,1);
7754   PetscValidPointer(v,3);
7755 
7756   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7757   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7758   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7759   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
7760   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
7761   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7762   PetscFunctionReturn(0);
7763 }
7764 
7765 #undef __FUNCT__
7766 #define __FUNCT__ "MatDiagonalScaleLocal"
7767 /*@
7768    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7769          ghosted ones.
7770 
7771    Not Collective
7772 
7773    Input Parameters:
7774 +  mat - the matrix
7775 -  diag = the diagonal values, including ghost ones
7776 
7777    Level: developer
7778 
7779    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7780 
7781 .seealso: MatDiagonalScale()
7782 @*/
7783 PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7784 {
7785   PetscErrorCode ierr;
7786   PetscMPIInt    size;
7787 
7788   PetscFunctionBegin;
7789   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7790   PetscValidHeaderSpecific(diag,VEC_CLASSID,2);
7791   PetscValidType(mat,1);
7792 
7793   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7794   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7795   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
7796   if (size == 1) {
7797     PetscInt n,m;
7798     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
7799     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
7800     if (m == n) {
7801       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
7802     } else {
7803       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7804     }
7805   } else {
7806     ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr);
7807   }
7808   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
7809   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
7810   PetscFunctionReturn(0);
7811 }
7812 
7813 #undef __FUNCT__
7814 #define __FUNCT__ "MatGetInertia"
7815 /*@
7816    MatGetInertia - Gets the inertia from a factored matrix
7817 
7818    Collective on Mat
7819 
7820    Input Parameter:
7821 .  mat - the matrix
7822 
7823    Output Parameters:
7824 +   nneg - number of negative eigenvalues
7825 .   nzero - number of zero eigenvalues
7826 -   npos - number of positive eigenvalues
7827 
7828    Level: advanced
7829 
7830    Notes: Matrix must have been factored by MatCholeskyFactor()
7831 
7832 
7833 @*/
7834 PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7835 {
7836   PetscErrorCode ierr;
7837 
7838   PetscFunctionBegin;
7839   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7840   PetscValidType(mat,1);
7841   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7842   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7843   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7844   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
7845   PetscFunctionReturn(0);
7846 }
7847 
7848 /* ----------------------------------------------------------------*/
7849 #undef __FUNCT__
7850 #define __FUNCT__ "MatSolves"
7851 /*@C
7852    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7853 
7854    Neighbor-wise Collective on Mat and Vecs
7855 
7856    Input Parameters:
7857 +  mat - the factored matrix
7858 -  b - the right-hand-side vectors
7859 
7860    Output Parameter:
7861 .  x - the result vectors
7862 
7863    Notes:
7864    The vectors b and x cannot be the same.  I.e., one cannot
7865    call MatSolves(A,x,x).
7866 
7867    Notes:
7868    Most users should employ the simplified KSP interface for linear solvers
7869    instead of working directly with matrix algebra routines such as this.
7870    See, e.g., KSPCreate().
7871 
7872    Level: developer
7873 
7874    Concepts: matrices^triangular solves
7875 
7876 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7877 @*/
7878 PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7879 {
7880   PetscErrorCode ierr;
7881 
7882   PetscFunctionBegin;
7883   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
7884   PetscValidType(mat,1);
7885   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7886   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7887   if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0);
7888 
7889   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7890   MatCheckPreallocated(mat,1);
7891   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7892   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
7893   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
7894   PetscFunctionReturn(0);
7895 }
7896 
7897 #undef __FUNCT__
7898 #define __FUNCT__ "MatIsSymmetric"
7899 /*@
7900    MatIsSymmetric - Test whether a matrix is symmetric
7901 
7902    Collective on Mat
7903 
7904    Input Parameter:
7905 +  A - the matrix to test
7906 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7907 
7908    Output Parameters:
7909 .  flg - the result
7910 
7911    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7912 
7913    Level: intermediate
7914 
7915    Concepts: matrix^symmetry
7916 
7917 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7918 @*/
7919 PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7920 {
7921   PetscErrorCode ierr;
7922 
7923   PetscFunctionBegin;
7924   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7925   PetscValidPointer(flg,2);
7926 
7927   if (!A->symmetric_set) {
7928     if (!A->ops->issymmetric) {
7929       const MatType mattype;
7930       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7931       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7932     }
7933     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7934     if (!tol) {
7935       A->symmetric_set = PETSC_TRUE;
7936       A->symmetric = *flg;
7937       if (A->symmetric) {
7938 	A->structurally_symmetric_set = PETSC_TRUE;
7939 	A->structurally_symmetric     = PETSC_TRUE;
7940       }
7941     }
7942   } else if (A->symmetric) {
7943     *flg = PETSC_TRUE;
7944   } else if (!tol) {
7945     *flg = PETSC_FALSE;
7946   } else {
7947     if (!A->ops->issymmetric) {
7948       const MatType mattype;
7949       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7950       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7951     }
7952     ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr);
7953   }
7954   PetscFunctionReturn(0);
7955 }
7956 
7957 #undef __FUNCT__
7958 #define __FUNCT__ "MatIsHermitian"
7959 /*@
7960    MatIsHermitian - Test whether a matrix is Hermitian
7961 
7962    Collective on Mat
7963 
7964    Input Parameter:
7965 +  A - the matrix to test
7966 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7967 
7968    Output Parameters:
7969 .  flg - the result
7970 
7971    Level: intermediate
7972 
7973    Concepts: matrix^symmetry
7974 
7975 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7976           MatIsSymmetricKnown(), MatIsSymmetric()
7977 @*/
7978 PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7979 {
7980   PetscErrorCode ierr;
7981 
7982   PetscFunctionBegin;
7983   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
7984   PetscValidPointer(flg,2);
7985 
7986   if (!A->hermitian_set) {
7987     if (!A->ops->ishermitian) {
7988       const MatType mattype;
7989       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
7990       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7991     }
7992     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
7993     if (!tol) {
7994       A->hermitian_set = PETSC_TRUE;
7995       A->hermitian = *flg;
7996       if (A->hermitian) {
7997 	A->structurally_symmetric_set = PETSC_TRUE;
7998 	A->structurally_symmetric     = PETSC_TRUE;
7999       }
8000     }
8001   } else if (A->hermitian) {
8002     *flg = PETSC_TRUE;
8003   } else if (!tol) {
8004     *flg = PETSC_FALSE;
8005   } else {
8006     if (!A->ops->ishermitian) {
8007       const MatType mattype;
8008       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8009       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8010     }
8011     ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr);
8012   }
8013   PetscFunctionReturn(0);
8014 }
8015 
8016 #undef __FUNCT__
8017 #define __FUNCT__ "MatIsSymmetricKnown"
8018 /*@
8019    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8020 
8021    Not Collective
8022 
8023    Input Parameter:
8024 .  A - the matrix to check
8025 
8026    Output Parameters:
8027 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
8028 -  flg - the result
8029 
8030    Level: advanced
8031 
8032    Concepts: matrix^symmetry
8033 
8034    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8035          if you want it explicitly checked
8036 
8037 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8038 @*/
8039 PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8040 {
8041   PetscFunctionBegin;
8042   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8043   PetscValidPointer(set,2);
8044   PetscValidPointer(flg,3);
8045   if (A->symmetric_set) {
8046     *set = PETSC_TRUE;
8047     *flg = A->symmetric;
8048   } else {
8049     *set = PETSC_FALSE;
8050   }
8051   PetscFunctionReturn(0);
8052 }
8053 
8054 #undef __FUNCT__
8055 #define __FUNCT__ "MatIsHermitianKnown"
8056 /*@
8057    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8058 
8059    Not Collective
8060 
8061    Input Parameter:
8062 .  A - the matrix to check
8063 
8064    Output Parameters:
8065 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8066 -  flg - the result
8067 
8068    Level: advanced
8069 
8070    Concepts: matrix^symmetry
8071 
8072    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8073          if you want it explicitly checked
8074 
8075 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8076 @*/
8077 PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8078 {
8079   PetscFunctionBegin;
8080   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8081   PetscValidPointer(set,2);
8082   PetscValidPointer(flg,3);
8083   if (A->hermitian_set) {
8084     *set = PETSC_TRUE;
8085     *flg = A->hermitian;
8086   } else {
8087     *set = PETSC_FALSE;
8088   }
8089   PetscFunctionReturn(0);
8090 }
8091 
8092 #undef __FUNCT__
8093 #define __FUNCT__ "MatIsStructurallySymmetric"
8094 /*@
8095    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8096 
8097    Collective on Mat
8098 
8099    Input Parameter:
8100 .  A - the matrix to test
8101 
8102    Output Parameters:
8103 .  flg - the result
8104 
8105    Level: intermediate
8106 
8107    Concepts: matrix^symmetry
8108 
8109 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8110 @*/
8111 PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8112 {
8113   PetscErrorCode ierr;
8114 
8115   PetscFunctionBegin;
8116   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8117   PetscValidPointer(flg,2);
8118   if (!A->structurally_symmetric_set) {
8119     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8120     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
8121     A->structurally_symmetric_set = PETSC_TRUE;
8122   }
8123   *flg = A->structurally_symmetric;
8124   PetscFunctionReturn(0);
8125 }
8126 
8127 #undef __FUNCT__
8128 #define __FUNCT__ "MatStashGetInfo"
8129 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8130 /*@
8131    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8132        to be communicated to other processors during the MatAssemblyBegin/End() process
8133 
8134     Not collective
8135 
8136    Input Parameter:
8137 .   vec - the vector
8138 
8139    Output Parameters:
8140 +   nstash   - the size of the stash
8141 .   reallocs - the number of additional mallocs incurred.
8142 .   bnstash   - the size of the block stash
8143 -   breallocs - the number of additional mallocs incurred.in the block stash
8144 
8145    Level: advanced
8146 
8147 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8148 
8149 @*/
8150 PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8151 {
8152   PetscErrorCode ierr;
8153   PetscFunctionBegin;
8154   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
8155   ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr);
8156   PetscFunctionReturn(0);
8157 }
8158 
8159 #undef __FUNCT__
8160 #define __FUNCT__ "MatGetVecs"
8161 /*@C
8162    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8163      parallel layout
8164 
8165    Collective on Mat
8166 
8167    Input Parameter:
8168 .  mat - the matrix
8169 
8170    Output Parameter:
8171 +   right - (optional) vector that the matrix can be multiplied against
8172 -   left - (optional) vector that the matrix vector product can be stored in
8173 
8174   Level: advanced
8175 
8176 .seealso: MatCreate()
8177 @*/
8178 PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8179 {
8180   PetscErrorCode ierr;
8181 
8182   PetscFunctionBegin;
8183   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
8184   PetscValidType(mat,1);
8185   MatCheckPreallocated(mat,1);
8186   if (mat->ops->getvecs) {
8187     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
8188   } else {
8189     PetscMPIInt size;
8190     ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr);
8191     if (right) {
8192       ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr);
8193       ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8194       ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr);
8195       ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr);
8196       ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr);
8197     }
8198     if (left) {
8199       ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr);
8200       ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr);
8201       ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr);
8202       ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr);
8203       ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr);
8204     }
8205   }
8206   PetscFunctionReturn(0);
8207 }
8208 
8209 #undef __FUNCT__
8210 #define __FUNCT__ "MatFactorInfoInitialize"
8211 /*@C
8212    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8213      with default values.
8214 
8215    Not Collective
8216 
8217    Input Parameters:
8218 .    info - the MatFactorInfo data structure
8219 
8220 
8221    Notes: The solvers are generally used through the KSP and PC objects, for example
8222           PCLU, PCILU, PCCHOLESKY, PCICC
8223 
8224    Level: developer
8225 
8226 .seealso: MatFactorInfo
8227 
8228     Developer Note: fortran interface is not autogenerated as the f90
8229     interface defintion cannot be generated correctly [due to MatFactorInfo]
8230 
8231 @*/
8232 
8233 PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8234 {
8235   PetscErrorCode ierr;
8236 
8237   PetscFunctionBegin;
8238   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
8239   PetscFunctionReturn(0);
8240 }
8241 
8242 #undef __FUNCT__
8243 #define __FUNCT__ "MatPtAP"
8244 /*@
8245    MatPtAP - Creates the matrix product C = P^T * A * P
8246 
8247    Neighbor-wise Collective on Mat
8248 
8249    Input Parameters:
8250 +  A - the matrix
8251 .  P - the projection matrix
8252 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8253 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8254 
8255    Output Parameters:
8256 .  C - the product matrix
8257 
8258    Notes:
8259    C will be created and must be destroyed by the user with MatDestroy().
8260 
8261    This routine is currently only implemented for pairs of AIJ matrices and classes
8262    which inherit from AIJ.
8263 
8264    Level: intermediate
8265 
8266 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8267 @*/
8268 PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8269 {
8270   PetscErrorCode ierr;
8271 
8272   PetscFunctionBegin;
8273   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8274   PetscValidType(A,1);
8275   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8276   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8277   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8278   PetscValidType(P,2);
8279   MatCheckPreallocated(P,2);
8280   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8281   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8282   PetscValidPointer(C,3);
8283   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);
8284   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8285   MatCheckPreallocated(A,1);
8286 
8287   if (!A->ops->ptap) {
8288     const MatType mattype;
8289     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8290     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8291   }
8292   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8293   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
8294   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
8295   PetscFunctionReturn(0);
8296 }
8297 
8298 #undef __FUNCT__
8299 #define __FUNCT__ "MatPtAPNumeric"
8300 /*@
8301    MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8302 
8303    Neighbor-wise Collective on Mat
8304 
8305    Input Parameters:
8306 +  A - the matrix
8307 -  P - the projection matrix
8308 
8309    Output Parameters:
8310 .  C - the product matrix
8311 
8312    Notes:
8313    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8314    the user using MatDeatroy().
8315 
8316    This routine is currently only implemented for pairs of AIJ matrices and classes
8317    which inherit from AIJ.  C will be of type MATAIJ.
8318 
8319    Level: intermediate
8320 
8321 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8322 @*/
8323 PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8324 {
8325   PetscErrorCode ierr;
8326 
8327   PetscFunctionBegin;
8328   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8329   PetscValidType(A,1);
8330   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8331   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8332   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8333   PetscValidType(P,2);
8334   MatCheckPreallocated(P,2);
8335   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8336   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8337   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8338   PetscValidType(C,3);
8339   MatCheckPreallocated(C,3);
8340   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8341   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);
8342   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);
8343   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);
8344   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);
8345   MatCheckPreallocated(A,1);
8346 
8347   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8348   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
8349   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
8350   PetscFunctionReturn(0);
8351 }
8352 
8353 #undef __FUNCT__
8354 #define __FUNCT__ "MatPtAPSymbolic"
8355 /*@
8356    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8357 
8358    Neighbor-wise Collective on Mat
8359 
8360    Input Parameters:
8361 +  A - the matrix
8362 -  P - the projection matrix
8363 
8364    Output Parameters:
8365 .  C - the (i,j) structure of the product matrix
8366 
8367    Notes:
8368    C will be created and must be destroyed by the user with MatDestroy().
8369 
8370    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8371    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8372    this (i,j) structure by calling MatPtAPNumeric().
8373 
8374    Level: intermediate
8375 
8376 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8377 @*/
8378 PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8379 {
8380   PetscErrorCode ierr;
8381 
8382   PetscFunctionBegin;
8383   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8384   PetscValidType(A,1);
8385   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8386   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8387   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8388   PetscValidHeaderSpecific(P,MAT_CLASSID,2);
8389   PetscValidType(P,2);
8390   MatCheckPreallocated(P,2);
8391   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8392   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8393   PetscValidPointer(C,3);
8394 
8395   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);
8396   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);
8397   MatCheckPreallocated(A,1);
8398   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8399   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
8400   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
8401 
8402   /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */
8403 
8404   PetscFunctionReturn(0);
8405 }
8406 
8407 #undef __FUNCT__
8408 #define __FUNCT__ "MatRARt"
8409 /*@
8410    MatRARt - Creates the matrix product C = R * A * R^T
8411 
8412    Neighbor-wise Collective on Mat
8413 
8414    Input Parameters:
8415 +  A - the matrix
8416 .  R - the projection matrix
8417 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8418 -  fill - expected fill as ratio of nnz(C)/nnz(A)
8419 
8420    Output Parameters:
8421 .  C - the product matrix
8422 
8423    Notes:
8424    C will be created and must be destroyed by the user with MatDestroy().
8425 
8426    This routine is currently only implemented for pairs of AIJ matrices and classes
8427    which inherit from AIJ.
8428 
8429    Level: intermediate
8430 
8431 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8432 @*/
8433 PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8434 {
8435   PetscErrorCode ierr;
8436 
8437   PetscFunctionBegin;
8438   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8439   PetscValidType(A,1);
8440   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8441   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8442   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8443   PetscValidType(R,2);
8444   MatCheckPreallocated(R,2);
8445   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8446   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8447   PetscValidPointer(C,3);
8448   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);
8449   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8450   MatCheckPreallocated(A,1);
8451 
8452   if (!A->ops->rart) {
8453     const MatType mattype;
8454     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
8455     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8456   }
8457   ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8458   ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr);
8459   ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr);
8460   PetscFunctionReturn(0);
8461 }
8462 
8463 #undef __FUNCT__
8464 #define __FUNCT__ "MatRARtNumeric"
8465 /*@
8466    MatRARtNumeric - Computes the matrix product C = R * A * R^T
8467 
8468    Neighbor-wise Collective on Mat
8469 
8470    Input Parameters:
8471 +  A - the matrix
8472 -  R - the projection matrix
8473 
8474    Output Parameters:
8475 .  C - the product matrix
8476 
8477    Notes:
8478    C must have been created by calling MatRARtSymbolic and must be destroyed by
8479    the user using MatDeatroy().
8480 
8481    This routine is currently only implemented for pairs of AIJ matrices and classes
8482    which inherit from AIJ.  C will be of type MATAIJ.
8483 
8484    Level: intermediate
8485 
8486 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8487 @*/
8488 PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8489 {
8490   PetscErrorCode ierr;
8491 
8492   PetscFunctionBegin;
8493   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8494   PetscValidType(A,1);
8495   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8496   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8497   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8498   PetscValidType(R,2);
8499   MatCheckPreallocated(R,2);
8500   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8501   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8502   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8503   PetscValidType(C,3);
8504   MatCheckPreallocated(C,3);
8505   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8506   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);
8507   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);
8508   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);
8509   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);
8510   MatCheckPreallocated(A,1);
8511 
8512   ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8513   ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr);
8514   ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr);
8515   PetscFunctionReturn(0);
8516 }
8517 
8518 #undef __FUNCT__
8519 #define __FUNCT__ "MatRARtSymbolic"
8520 /*@
8521    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8522 
8523    Neighbor-wise Collective on Mat
8524 
8525    Input Parameters:
8526 +  A - the matrix
8527 -  R - the projection matrix
8528 
8529    Output Parameters:
8530 .  C - the (i,j) structure of the product matrix
8531 
8532    Notes:
8533    C will be created and must be destroyed by the user with MatDestroy().
8534 
8535    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8536    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8537    this (i,j) structure by calling MatRARtNumeric().
8538 
8539    Level: intermediate
8540 
8541 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8542 @*/
8543 PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8544 {
8545   PetscErrorCode ierr;
8546 
8547   PetscFunctionBegin;
8548   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8549   PetscValidType(A,1);
8550   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8551   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8552   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8553   PetscValidHeaderSpecific(R,MAT_CLASSID,2);
8554   PetscValidType(R,2);
8555   MatCheckPreallocated(R,2);
8556   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8557   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8558   PetscValidPointer(C,3);
8559 
8560   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);
8561   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);
8562   MatCheckPreallocated(A,1);
8563   ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8564   ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr);
8565   ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr);
8566 
8567   ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr);
8568   PetscFunctionReturn(0);
8569 }
8570 
8571 extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);
8572 
8573 #undef __FUNCT__
8574 #define __FUNCT__ "MatMatMult"
8575 /*@
8576    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8577 
8578    Neighbor-wise Collective on Mat
8579 
8580    Input Parameters:
8581 +  A - the left matrix
8582 .  B - the right matrix
8583 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8584 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8585           if the result is a dense matrix this is irrelevent
8586 
8587    Output Parameters:
8588 .  C - the product matrix
8589 
8590    Notes:
8591    Unless scall is MAT_REUSE_MATRIX C will be created.
8592 
8593    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8594 
8595    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8596    actually needed.
8597 
8598    If you have many matrices with the same non-zero structure to multiply, you
8599    should either
8600 $   1) use MAT_REUSE_MATRIX in all calls but the first or
8601 $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8602 
8603    Level: intermediate
8604 
8605 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8606 @*/
8607 PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8608 {
8609   PetscErrorCode ierr;
8610   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8611   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8612   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;
8613 
8614   PetscFunctionBegin;
8615   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8616   PetscValidType(A,1);
8617   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8618   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8619   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8620   PetscValidType(B,2);
8621   MatCheckPreallocated(B,2);
8622   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8623   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8624   PetscValidPointer(C,3);
8625   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);
8626   if (scall == MAT_REUSE_MATRIX){
8627     PetscValidPointer(*C,5);
8628     PetscValidHeaderSpecific(*C,MAT_CLASSID,5);
8629     ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8630     ierr = (*(*C)->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8631     ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8632   }
8633   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8634   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8635   MatCheckPreallocated(A,1);
8636 
8637   fA = A->ops->matmult;
8638   fB = B->ops->matmult;
8639   if (fB == fA) {
8640     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8641     mult = fB;
8642   } else {
8643     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8644     char  multname[256];
8645     ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr);
8646     ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8647     ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);
8648     ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8649     ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8650     ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr);
8651     if(!mult){
8652       /* dual dispatch using MatQueryOp */
8653       ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8654       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);
8655     }
8656   }
8657   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8658   ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr);
8659   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
8660   PetscFunctionReturn(0);
8661 }
8662 
8663 #undef __FUNCT__
8664 #define __FUNCT__ "MatMatMultSymbolic"
8665 /*@
8666    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8667    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
8668 
8669    Neighbor-wise Collective on Mat
8670 
8671    Input Parameters:
8672 +  A - the left matrix
8673 .  B - the right matrix
8674 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8675       if C is a dense matrix this is irrelevent
8676 
8677    Output Parameters:
8678 .  C - the product matrix
8679 
8680    Notes:
8681    Unless scall is MAT_REUSE_MATRIX C will be created.
8682 
8683    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8684    actually needed.
8685 
8686    This routine is currently implemented for
8687     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8688     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8689     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8690 
8691    Level: intermediate
8692 
8693    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8694      We should incorporate them into PETSc.
8695 
8696 .seealso: MatMatMult(), MatMatMultNumeric()
8697 @*/
8698 PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8699 {
8700   PetscErrorCode ierr;
8701   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8702   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8703   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;
8704 
8705   PetscFunctionBegin;
8706   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8707   PetscValidType(A,1);
8708   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8709   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8710 
8711   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8712   PetscValidType(B,2);
8713   MatCheckPreallocated(B,2);
8714   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8715   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8716   PetscValidPointer(C,3);
8717 
8718   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);
8719   if (fill == PETSC_DEFAULT) fill = 2.0;
8720   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8721   MatCheckPreallocated(A,1);
8722 
8723   Asymbolic = A->ops->matmultsymbolic;
8724   Bsymbolic = B->ops->matmultsymbolic;
8725   if (Asymbolic == Bsymbolic){
8726     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8727     symbolic = Bsymbolic;
8728   } else { /* dispatch based on the type of A and B */
8729     char  symbolicname[256];
8730     ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr);
8731     ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8732     ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr);
8733     ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8734     ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr);
8735     ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr);
8736     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);
8737   }
8738   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8739   ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr);
8740   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8741   PetscFunctionReturn(0);
8742 }
8743 
8744 #undef __FUNCT__
8745 #define __FUNCT__ "MatMatMultNumeric"
8746 /*@
8747    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8748    Call this routine after first calling MatMatMultSymbolic().
8749 
8750    Neighbor-wise Collective on Mat
8751 
8752    Input Parameters:
8753 +  A - the left matrix
8754 -  B - the right matrix
8755 
8756    Output Parameters:
8757 .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8758 
8759    Notes:
8760    C must have been created with MatMatMultSymbolic().
8761 
8762    This routine is currently implemented for
8763     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8764     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8765     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8766 
8767    Level: intermediate
8768 
8769 .seealso: MatMatMult(), MatMatMultSymbolic()
8770 @*/
8771 PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8772 {
8773   PetscErrorCode ierr;
8774   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8775   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8776   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;
8777 
8778   PetscFunctionBegin;
8779   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8780   PetscValidType(A,1);
8781   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8782   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8783 
8784   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8785   PetscValidType(B,2);
8786   MatCheckPreallocated(B,2);
8787   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8788   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8789 
8790   PetscValidHeaderSpecific(C,MAT_CLASSID,3);
8791   PetscValidType(C,3);
8792   MatCheckPreallocated(C,3);
8793   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8794   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8795 
8796   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);
8797   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);
8798   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);
8799   MatCheckPreallocated(A,1);
8800 
8801   Anumeric = A->ops->matmultnumeric;
8802   Bnumeric = B->ops->matmultnumeric;
8803   if (Anumeric == Bnumeric){
8804     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8805     numeric = Bnumeric;
8806   } else {
8807     char  numericname[256];
8808     ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr);
8809     ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr);
8810     ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr);
8811     ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr);
8812     ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr);
8813     ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr);
8814     if (!numeric)
8815       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);
8816   }
8817   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8818   ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
8819   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
8820   PetscFunctionReturn(0);
8821 }
8822 
8823 #undef __FUNCT__
8824 #define __FUNCT__ "MatMatTransposeMult"
8825 /*@
8826    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8827 
8828    Neighbor-wise Collective on Mat
8829 
8830    Input Parameters:
8831 +  A - the left matrix
8832 .  B - the right matrix
8833 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8834 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8835 
8836    Output Parameters:
8837 .  C - the product matrix
8838 
8839    Notes:
8840    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8841 
8842    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8843 
8844   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8845    actually needed.
8846 
8847    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.
8848 
8849    Level: intermediate
8850 
8851 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8852 @*/
8853 PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8854 {
8855   PetscErrorCode ierr;
8856   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8857   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8858 
8859   PetscFunctionBegin;
8860   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8861   PetscValidType(A,1);
8862   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8863   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8864   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8865   PetscValidType(B,2);
8866   MatCheckPreallocated(B,2);
8867   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8868   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8869   PetscValidPointer(C,3);
8870   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);
8871   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8872   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8873   MatCheckPreallocated(A,1);
8874 
8875   fA = A->ops->mattransposemult;
8876   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8877   fB = B->ops->mattransposemult;
8878   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8879   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);
8880 
8881   if (scall == MAT_INITIAL_MATRIX){
8882     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8883     ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);
8884     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
8885   }
8886   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8887   ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);
8888   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
8889   PetscFunctionReturn(0);
8890 }
8891 
8892 #undef __FUNCT__
8893 #define __FUNCT__ "MatTransposeMatMult"
8894 /*@
8895    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8896 
8897    Neighbor-wise Collective on Mat
8898 
8899    Input Parameters:
8900 +  A - the left matrix
8901 .  B - the right matrix
8902 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8903 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8904 
8905    Output Parameters:
8906 .  C - the product matrix
8907 
8908    Notes:
8909    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8910 
8911    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8912 
8913   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8914    actually needed.
8915 
8916    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8917    which inherit from SeqAIJ.  C will be of same type as the input matrices.
8918 
8919    Level: intermediate
8920 
8921 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8922 @*/
8923 PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8924 {
8925   PetscErrorCode ierr;
8926   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8927   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8928   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);
8929 
8930   PetscFunctionBegin;
8931   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
8932   PetscValidType(A,1);
8933   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8934   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8935   PetscValidHeaderSpecific(B,MAT_CLASSID,2);
8936   PetscValidType(B,2);
8937   MatCheckPreallocated(B,2);
8938   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8939   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8940   PetscValidPointer(C,3);
8941   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);
8942   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8943   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8944   MatCheckPreallocated(A,1);
8945 
8946   fA = A->ops->transposematmult;
8947   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8948   fB = B->ops->transposematmult;
8949   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8950   if (fB==fA) {
8951     transposematmult = fA;
8952   }
8953   else {
8954     /* dual dispatch using MatQueryOp */
8955     ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr);
8956     if(!transposematmult)
8957       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);
8958   }
8959   ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8960   ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);
8961   ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);
8962   PetscFunctionReturn(0);
8963 }
8964 
8965 #undef __FUNCT__
8966 #define __FUNCT__ "MatGetRedundantMatrix"
8967 /*@C
8968    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
8969 
8970    Collective on Mat
8971 
8972    Input Parameters:
8973 +  mat - the matrix
8974 .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8975 .  subcomm - MPI communicator split from the communicator where mat resides in
8976 .  mlocal_red - number of local rows of the redundant matrix
8977 -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8978 
8979    Output Parameter:
8980 .  matredundant - redundant matrix
8981 
8982    Notes:
8983    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
8984    original matrix has not changed from that last call to MatGetRedundantMatrix().
8985 
8986    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8987    calling it.
8988 
8989    Only MPIAIJ matrix is supported.
8990 
8991    Level: advanced
8992 
8993    Concepts: subcommunicator
8994    Concepts: duplicate matrix
8995 
8996 .seealso: MatDestroy()
8997 @*/
8998 PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8999 {
9000   PetscErrorCode ierr;
9001 
9002   PetscFunctionBegin;
9003   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9004   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9005     PetscValidPointer(*matredundant,6);
9006     PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6);
9007   }
9008   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9009   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9010   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9011   MatCheckPreallocated(mat,1);
9012 
9013   ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9014   ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr);
9015   ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr);
9016   PetscFunctionReturn(0);
9017 }
9018 
9019 #undef __FUNCT__
9020 #define __FUNCT__ "MatGetMultiProcBlock"
9021 /*@C
9022    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9023    a given 'mat' object. Each submatrix can span multiple procs.
9024 
9025    Collective on Mat
9026 
9027    Input Parameters:
9028 +  mat - the matrix
9029 .  subcomm - the subcommunicator obtained by com_split(comm)
9030 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9031 
9032    Output Parameter:
9033 .  subMat - 'parallel submatrices each spans a given subcomm
9034 
9035   Notes:
9036   The submatrix partition across processors is dicated by 'subComm' a
9037   communicator obtained by com_split(comm). The comm_split
9038   is not restriced to be grouped with consequitive original ranks.
9039 
9040   Due the comm_split() usage, the parallel layout of the submatrices
9041   map directly to the layout of the original matrix [wrt the local
9042   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9043   into the 'DiagonalMat' of the subMat, hence it is used directly from
9044   the subMat. However the offDiagMat looses some columns - and this is
9045   reconstructed with MatSetValues()
9046 
9047   Level: advanced
9048 
9049   Concepts: subcommunicator
9050   Concepts: submatrices
9051 
9052 .seealso: MatGetSubMatrices()
9053 @*/
9054 PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9055 {
9056   PetscErrorCode ierr;
9057   PetscMPIInt    commsize,subCommSize;
9058 
9059   PetscFunctionBegin;
9060   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr);
9061   ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr);
9062   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9063 
9064   ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9065   ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr);
9066   ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr);
9067   PetscFunctionReturn(0);
9068 }
9069 
9070 #undef __FUNCT__
9071 #define __FUNCT__ "MatGetLocalSubMatrix"
9072 /*@
9073    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9074 
9075    Not Collective
9076 
9077    Input Arguments:
9078    mat - matrix to extract local submatrix from
9079    isrow - local row indices for submatrix
9080    iscol - local column indices for submatrix
9081 
9082    Output Arguments:
9083    submat - the submatrix
9084 
9085    Level: intermediate
9086 
9087    Notes:
9088    The submat should be returned with MatRestoreLocalSubMatrix().
9089 
9090    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9091    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9092 
9093    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9094    MatSetValuesBlockedLocal() will also be implemented.
9095 
9096 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9097 @*/
9098 PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9099 {
9100   PetscErrorCode ierr;
9101 
9102   PetscFunctionBegin;
9103   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9104   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9105   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9106   PetscCheckSameComm(isrow,2,iscol,3);
9107   PetscValidPointer(submat,4);
9108 
9109   if (mat->ops->getlocalsubmatrix) {
9110     ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9111   } else {
9112     ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr);
9113   }
9114   PetscFunctionReturn(0);
9115 }
9116 
9117 #undef __FUNCT__
9118 #define __FUNCT__ "MatRestoreLocalSubMatrix"
9119 /*@
9120    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9121 
9122    Not Collective
9123 
9124    Input Arguments:
9125    mat - matrix to extract local submatrix from
9126    isrow - local row indices for submatrix
9127    iscol - local column indices for submatrix
9128    submat - the submatrix
9129 
9130    Level: intermediate
9131 
9132 .seealso: MatGetLocalSubMatrix()
9133 @*/
9134 PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9135 {
9136   PetscErrorCode ierr;
9137 
9138   PetscFunctionBegin;
9139   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9140   PetscValidHeaderSpecific(isrow,IS_CLASSID,2);
9141   PetscValidHeaderSpecific(iscol,IS_CLASSID,3);
9142   PetscCheckSameComm(isrow,2,iscol,3);
9143   PetscValidPointer(submat,4);
9144   if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);}
9145 
9146   if (mat->ops->restorelocalsubmatrix) {
9147     ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr);
9148   } else {
9149     ierr = MatDestroy(submat);CHKERRQ(ierr);
9150   }
9151   *submat = PETSC_NULL;
9152   PetscFunctionReturn(0);
9153 }
9154 
9155 /* --------------------------------------------------------*/
9156 #undef __FUNCT__
9157 #define __FUNCT__ "MatFindZeroDiagonals"
9158 /*@
9159    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9160 
9161    Collective on Mat
9162 
9163    Input Parameter:
9164 .  mat - the matrix
9165 
9166    Output Parameter:
9167 .  is - if any rows have zero diagonals this contains the list of them
9168 
9169    Level: developer
9170 
9171    Concepts: matrix-vector product
9172 
9173 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9174 @*/
9175 PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9176 {
9177   PetscErrorCode ierr;
9178 
9179   PetscFunctionBegin;
9180   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9181   PetscValidType(mat,1);
9182   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9183   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9184 
9185   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9186   ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr);
9187   PetscFunctionReturn(0);
9188 }
9189 
9190 #undef __FUNCT__
9191 #define __FUNCT__ "MatInvertBlockDiagonal"
9192 /*@C
9193   MatInvertBlockDiagonal - Inverts the block diagonal entries.
9194 
9195   Collective on Mat
9196 
9197   Input Parameters:
9198 . mat - the matrix
9199 
9200   Output Parameters:
9201 . values - the block inverses in column major order (FORTRAN-like)
9202 
9203    Note:
9204    This routine is not available from Fortran.
9205 
9206   Level: advanced
9207 @*/
9208 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9209 {
9210   PetscErrorCode ierr;
9211 
9212   PetscFunctionBegin;
9213   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
9214   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9215   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9216   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9217   ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr);
9218   PetscFunctionReturn(0);
9219 }
9220 
9221 #undef __FUNCT__
9222 #define __FUNCT__ "MatTransposeColoringDestroy"
9223 /*@C
9224     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9225     via MatTransposeColoringCreate().
9226 
9227     Collective on MatTransposeColoring
9228 
9229     Input Parameter:
9230 .   c - coloring context
9231 
9232     Level: intermediate
9233 
9234 .seealso: MatTransposeColoringCreate()
9235 @*/
9236 PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9237 {
9238   PetscErrorCode       ierr;
9239   MatTransposeColoring matcolor=*c;
9240 
9241   PetscFunctionBegin;
9242   if (!matcolor) PetscFunctionReturn(0);
9243   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);}
9244 
9245   ierr = PetscFree(matcolor->ncolumns);CHKERRQ(ierr);
9246   ierr = PetscFree(matcolor->nrows);CHKERRQ(ierr);
9247   ierr = PetscFree(matcolor->colorforrow);CHKERRQ(ierr);
9248   ierr = PetscFree2(matcolor->rows,matcolor->columnsforspidx);CHKERRQ(ierr);
9249   ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr);
9250   ierr = PetscFree(matcolor->columns);CHKERRQ(ierr);
9251   ierr = PetscHeaderDestroy(c);CHKERRQ(ierr);
9252   PetscFunctionReturn(0);
9253 }
9254 
9255 #undef __FUNCT__
9256 #define __FUNCT__ "MatTransColoringApplySpToDen"
9257 /*@C
9258     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9259     a MatTransposeColoring context has been created, computes a dense B^T by Apply
9260     MatTransposeColoring to sparse B.
9261 
9262     Collective on MatTransposeColoring
9263 
9264     Input Parameters:
9265 +   B - sparse matrix B
9266 .   Btdense - symbolic dense matrix B^T
9267 -   coloring - coloring context created with MatTransposeColoringCreate()
9268 
9269     Output Parameter:
9270 .   Btdense - dense matrix B^T
9271 
9272     Options Database Keys:
9273 +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9274 .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9275 -    -mat_transpose_coloring_view_info - Activates viewing of coloring info
9276 
9277     Level: intermediate
9278 
9279 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9280 
9281 .keywords: coloring
9282 @*/
9283 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9284 {
9285   PetscErrorCode ierr;
9286 
9287   PetscFunctionBegin;
9288   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
9289   PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2);
9290   PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3);
9291 
9292   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9293   ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr);
9294   PetscFunctionReturn(0);
9295 }
9296 
9297 #undef __FUNCT__
9298 #define __FUNCT__ "MatTransColoringApplyDenToSp"
9299 /*@C
9300     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9301     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9302     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9303     Csp from Cden.
9304 
9305     Collective on MatTransposeColoring
9306 
9307     Input Parameters:
9308 +   coloring - coloring context created with MatTransposeColoringCreate()
9309 -   Cden - matrix product of a sparse matrix and a dense matrix Btdense
9310 
9311     Output Parameter:
9312 .   Csp - sparse matrix
9313 
9314     Options Database Keys:
9315 +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9316 .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9317 -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9318 
9319     Level: intermediate
9320 
9321 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9322 
9323 .keywords: coloring
9324 @*/
9325 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9326 {
9327   PetscErrorCode ierr;
9328 
9329   PetscFunctionBegin;
9330   PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1);
9331   PetscValidHeaderSpecific(Cden,MAT_CLASSID,2);
9332   PetscValidHeaderSpecific(Csp,MAT_CLASSID,3);
9333 
9334   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9335   ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr);
9336   PetscFunctionReturn(0);
9337 }
9338 
9339 #undef __FUNCT__
9340 #define __FUNCT__ "MatTransposeColoringCreate"
9341 /*@C
9342    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9343 
9344    Collective on Mat
9345 
9346    Input Parameters:
9347 +  mat - the matrix product C
9348 -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9349 
9350     Output Parameter:
9351 .   color - the new coloring context
9352 
9353     Level: intermediate
9354 
9355 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9356            MatTransColoringApplyDen()ToSp, MatTransposeColoringView(),
9357 @*/
9358 PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9359 {
9360   MatTransposeColoring  c;
9361   MPI_Comm              comm;
9362   PetscErrorCode        ierr;
9363 
9364   PetscFunctionBegin;
9365   ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9366   ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr);
9367   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);
9368 
9369   c->ctype = iscoloring->ctype;
9370   if (mat->ops->transposecoloringcreate) {
9371     ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr);
9372   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");
9373 
9374   *color = c;
9375   ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr);
9376   PetscFunctionReturn(0);
9377 }
9378