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