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