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