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