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