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