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