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