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