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