xref: /petsc/src/mat/interface/matrix.c (revision db090513750e512db36c746fd2b7b9368f9e7cc5)
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 "private/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 /*@
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   ierr = MatSetFromOptions(A);CHKERRQ(ierr);
311   PetscFunctionReturn(0);
312 }
313 
314 #undef __FUNCT__
315 #define __FUNCT__ "MatView"
316 /*@C
317    MatView - Visualizes a matrix object.
318 
319    Collective on Mat
320 
321    Input Parameters:
322 +  mat - the matrix
323 -  viewer - visualization context
324 
325   Notes:
326   The available visualization contexts include
327 +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
328 .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
329         output where only the first processor opens
330         the file.  All other processors send their
331         data to the first processor to print.
332 -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
333 
334    The user can open alternative visualization contexts with
335 +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
336 .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
337          specified file; corresponding input uses MatLoad()
338 .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
339          an X window display
340 -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
341          Currently only the sequential dense and AIJ
342          matrix types support the Socket viewer.
343 
344    The user can call PetscViewerSetFormat() to specify the output
345    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
346    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
347 +    PETSC_VIEWER_ASCII_DEFAULT - default, prints matrix contents
348 .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
349 .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
350 .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
351          format common among all matrix types
352 .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
353          format (which is in many cases the same as the default)
354 .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
355          size and structure (not the matrix entries)
356 .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
357          the matrix structure
358 
359    Options Database Keys:
360 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
361 .  -mat_view_info_detailed - Prints more detailed info
362 .  -mat_view - Prints matrix in ASCII format
363 .  -mat_view_matlab - Prints matrix in Matlab format
364 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
365 .  -display <name> - Sets display name (default is host)
366 .  -draw_pause <sec> - Sets number of seconds to pause after display
367 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
368 .  -viewer_socket_machine <machine>
369 .  -viewer_socket_port <port>
370 .  -mat_view_binary - save matrix to file in binary format
371 -  -viewer_binary_filename <name>
372    Level: beginner
373 
374    Concepts: matrices^viewing
375    Concepts: matrices^plotting
376    Concepts: matrices^printing
377 
378 .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
379           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
380 @*/
381 PetscErrorCode PETSCMAT_DLLEXPORT MatView(Mat mat,PetscViewer viewer)
382 {
383   PetscErrorCode    ierr;
384   PetscInt          rows,cols;
385   PetscTruth        iascii;
386   const char        *cstr;
387   PetscViewerFormat format;
388 
389   PetscFunctionBegin;
390   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
391   PetscValidType(mat,1);
392   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mat->comm);
393   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
394   PetscCheckSameComm(mat,1,viewer,2);
395   if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
396   ierr = MatPreallocated(mat);CHKERRQ(ierr);
397 
398   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
399   if (iascii) {
400     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
401     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
402       if (mat->prefix) {
403         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",mat->prefix);CHKERRQ(ierr);
404       } else {
405         ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");CHKERRQ(ierr);
406       }
407       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
408       ierr = MatGetType(mat,&cstr);CHKERRQ(ierr);
409       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
410       ierr = PetscViewerASCIIPrintf(viewer,"type=%s, rows=%D, cols=%D\n",cstr,rows,cols);CHKERRQ(ierr);
411       if (mat->ops->getinfo) {
412         MatInfo info;
413         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
414         ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",
415                           (PetscInt)info.nz_used,(PetscInt)info.nz_allocated);CHKERRQ(ierr);
416       }
417     }
418   }
419   if (mat->ops->view) {
420     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
421     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
422     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
423   } else if (!iascii) {
424     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
425   }
426   if (iascii) {
427     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
428     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
429       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
430     }
431   }
432   PetscFunctionReturn(0);
433 }
434 
435 #undef __FUNCT__
436 #define __FUNCT__ "MatScaleSystem"
437 /*@C
438    MatScaleSystem - Scale a vector solution and right hand side to
439    match the scaling of a scaled matrix.
440 
441    Collective on Mat
442 
443    Input Parameter:
444 +  mat - the matrix
445 .  x - solution vector (or PETSC_NULL)
446 -  b - right hand side vector (or PETSC_NULL)
447 
448 
449    Notes:
450    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not
451    internally scaled, so this does nothing. For MPIROWBS it
452    permutes and diagonally scales.
453 
454    The KSP methods automatically call this routine when required
455    (via PCPreSolve()) so it is rarely used directly.
456 
457    Level: Developer
458 
459    Concepts: matrices^scaling
460 
461 .seealso: MatUseScaledForm(), MatUnScaleSystem()
462 @*/
463 PetscErrorCode PETSCMAT_DLLEXPORT MatScaleSystem(Mat mat,Vec x,Vec b)
464 {
465   PetscErrorCode ierr;
466 
467   PetscFunctionBegin;
468   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
469   PetscValidType(mat,1);
470   ierr = MatPreallocated(mat);CHKERRQ(ierr);
471   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
472   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
473 
474   if (mat->ops->scalesystem) {
475     ierr = (*mat->ops->scalesystem)(mat,x,b);CHKERRQ(ierr);
476   }
477   PetscFunctionReturn(0);
478 }
479 
480 #undef __FUNCT__
481 #define __FUNCT__ "MatUnScaleSystem"
482 /*@C
483    MatUnScaleSystem - Unscales a vector solution and right hand side to
484    match the original scaling of a scaled matrix.
485 
486    Collective on Mat
487 
488    Input Parameter:
489 +  mat - the matrix
490 .  x - solution vector (or PETSC_NULL)
491 -  b - right hand side vector (or PETSC_NULL)
492 
493 
494    Notes:
495    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not
496    internally scaled, so this does nothing. For MPIROWBS it
497    permutes and diagonally scales.
498 
499    The KSP methods automatically call this routine when required
500    (via PCPreSolve()) so it is rarely used directly.
501 
502    Level: Developer
503 
504 .seealso: MatUseScaledForm(), MatScaleSystem()
505 @*/
506 PetscErrorCode PETSCMAT_DLLEXPORT MatUnScaleSystem(Mat mat,Vec x,Vec b)
507 {
508   PetscErrorCode ierr;
509 
510   PetscFunctionBegin;
511   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
512   PetscValidType(mat,1);
513   ierr = MatPreallocated(mat);CHKERRQ(ierr);
514   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE,2);PetscCheckSameComm(mat,1,x,2);}
515   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE,3);PetscCheckSameComm(mat,1,b,3);}
516   if (mat->ops->unscalesystem) {
517     ierr = (*mat->ops->unscalesystem)(mat,x,b);CHKERRQ(ierr);
518   }
519   PetscFunctionReturn(0);
520 }
521 
522 #undef __FUNCT__
523 #define __FUNCT__ "MatUseScaledForm"
524 /*@C
525    MatUseScaledForm - For matrix storage formats that scale the
526    matrix (for example MPIRowBS matrices are diagonally scaled on
527    assembly) indicates matrix operations (MatMult() etc) are
528    applied using the scaled matrix.
529 
530    Collective on Mat
531 
532    Input Parameter:
533 +  mat - the matrix
534 -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
535             applying the original matrix
536 
537    Notes:
538    For scaled matrix formats, applying the original, unscaled matrix
539    will be slightly more expensive
540 
541    Level: Developer
542 
543 .seealso: MatScaleSystem(), MatUnScaleSystem()
544 @*/
545 PetscErrorCode PETSCMAT_DLLEXPORT MatUseScaledForm(Mat mat,PetscTruth scaled)
546 {
547   PetscErrorCode ierr;
548 
549   PetscFunctionBegin;
550   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
551   PetscValidType(mat,1);
552   ierr = MatPreallocated(mat);CHKERRQ(ierr);
553   if (mat->ops->usescaledform) {
554     ierr = (*mat->ops->usescaledform)(mat,scaled);CHKERRQ(ierr);
555   }
556   PetscFunctionReturn(0);
557 }
558 
559 #undef __FUNCT__
560 #define __FUNCT__ "MatDestroy"
561 /*@
562    MatDestroy - Frees space taken by a matrix.
563 
564    Collective on Mat
565 
566    Input Parameter:
567 .  A - the matrix
568 
569    Level: beginner
570 
571 @*/
572 PetscErrorCode PETSCMAT_DLLEXPORT MatDestroy(Mat A)
573 {
574   PetscErrorCode ierr;
575 
576   PetscFunctionBegin;
577   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
578   if (--A->refct > 0) PetscFunctionReturn(0);
579 
580   PetscValidType(A,1);
581   ierr = MatPreallocated(A);CHKERRQ(ierr);
582   /* if memory was published with AMS then destroy it */
583   ierr = PetscObjectDepublish(A);CHKERRQ(ierr);
584   if (A->mapping) {
585     ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr);
586   }
587   if (A->bmapping) {
588     ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr);
589   }
590   if (A->rmap) {
591     ierr = PetscMapDestroy(A->rmap);CHKERRQ(ierr);
592   }
593   if (A->cmap) {
594     ierr = PetscMapDestroy(A->cmap);CHKERRQ(ierr);
595   }
596   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
597   ierr = PetscHeaderDestroy(A);CHKERRQ(ierr);
598   PetscFunctionReturn(0);
599 }
600 
601 #undef __FUNCT__
602 #define __FUNCT__ "MatValid"
603 /*@
604    MatValid - Checks whether a matrix object is valid.
605 
606    Collective on Mat
607 
608    Input Parameter:
609 .  m - the matrix to check
610 
611    Output Parameter:
612    flg - flag indicating matrix status, either
613    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
614 
615    Level: developer
616 
617    Concepts: matrices^validity
618 @*/
619 PetscErrorCode PETSCMAT_DLLEXPORT MatValid(Mat m,PetscTruth *flg)
620 {
621   PetscFunctionBegin;
622   PetscValidIntPointer(flg,1);
623   if (!m)                           *flg = PETSC_FALSE;
624   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
625   else                              *flg = PETSC_TRUE;
626   PetscFunctionReturn(0);
627 }
628 
629 #undef __FUNCT__
630 #define __FUNCT__ "MatSetValues"
631 /*@
632    MatSetValues - Inserts or adds a block of values into a matrix.
633    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
634    MUST be called after all calls to MatSetValues() have been completed.
635 
636    Not Collective
637 
638    Input Parameters:
639 +  mat - the matrix
640 .  v - a logically two-dimensional array of values
641 .  m, idxm - the number of rows and their global indices
642 .  n, idxn - the number of columns and their global indices
643 -  addv - either ADD_VALUES or INSERT_VALUES, where
644    ADD_VALUES adds values to any existing entries, and
645    INSERT_VALUES replaces existing entries with new values
646 
647    Notes:
648    By default the values, v, are row-oriented and unsorted.
649    See MatSetOption() for other options.
650 
651    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
652    options cannot be mixed without intervening calls to the assembly
653    routines.
654 
655    MatSetValues() uses 0-based row and column numbers in Fortran
656    as well as in C.
657 
658    Negative indices may be passed in idxm and idxn, these rows and columns are
659    simply ignored. This allows easily inserting element stiffness matrices
660    with homogeneous Dirchlet boundary conditions that you don't want represented
661    in the matrix.
662 
663    Efficiency Alert:
664    The routine MatSetValuesBlocked() may offer much better efficiency
665    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
666 
667    Level: beginner
668 
669    Concepts: matrices^putting entries in
670 
671 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
672           InsertMode, INSERT_VALUES, ADD_VALUES
673 @*/
674 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
675 {
676   PetscErrorCode ierr;
677 
678   PetscFunctionBegin;
679   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
680   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
681   PetscValidType(mat,1);
682   PetscValidIntPointer(idxm,3);
683   PetscValidIntPointer(idxn,5);
684   PetscValidScalarPointer(v,6);
685   ierr = MatPreallocated(mat);CHKERRQ(ierr);
686   if (mat->insertmode == NOT_SET_VALUES) {
687     mat->insertmode = addv;
688   }
689 #if defined(PETSC_USE_DEBUG)
690   else if (mat->insertmode != addv) {
691     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
692   }
693   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
694 #endif
695 
696   if (mat->assembled) {
697     mat->was_assembled = PETSC_TRUE;
698     mat->assembled     = PETSC_FALSE;
699   }
700   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
701   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
702   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
703   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
704   PetscFunctionReturn(0);
705 }
706 
707 #undef __FUNCT__
708 #define __FUNCT__ "MatSetValuesStencil"
709 /*@
710    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
711      Using structured grid indexing
712 
713    Not Collective
714 
715    Input Parameters:
716 +  mat - the matrix
717 .  v - a logically two-dimensional array of values
718 .  m - number of rows being entered
719 .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
720 .  n - number of columns being entered
721 .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
722 -  addv - either ADD_VALUES or INSERT_VALUES, where
723    ADD_VALUES adds values to any existing entries, and
724    INSERT_VALUES replaces existing entries with new values
725 
726    Notes:
727    By default the values, v, are row-oriented and unsorted.
728    See MatSetOption() for other options.
729 
730    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
731    options cannot be mixed without intervening calls to the assembly
732    routines.
733 
734    The grid coordinates are across the entire grid, not just the local portion
735 
736    MatSetValuesStencil() uses 0-based row and column numbers in Fortran
737    as well as in C.
738 
739    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
740 
741    In order to use this routine you must either obtain the matrix with DAGetMatrix()
742    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
743 
744    The columns and rows in the stencil passed in MUST be contained within the
745    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
746    if you create a DA with an overlap of one grid level and on a particular process its first
747    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
748    first i index you can use in your column and row indices in MatSetStencil() is 5.
749 
750    In Fortran idxm and idxn should be declared as
751 $     MatStencil idxm(4,m),idxn(4,n)
752    and the values inserted using
753 $    idxm(MatStencil_i,1) = i
754 $    idxm(MatStencil_j,1) = j
755 $    idxm(MatStencil_k,1) = k
756 $    idxm(MatStencil_c,1) = c
757    etc
758 
759    Negative indices may be passed in idxm and idxn, these rows and columns are
760    simply ignored. This allows easily inserting element stiffness matrices
761    with homogeneous Dirchlet boundary conditions that you don't want represented
762    in the matrix.
763 
764    Inspired by the structured grid interface to the HYPRE package
765    (http://www.llnl.gov/CASC/hypre)
766 
767    Efficiency Alert:
768    The routine MatSetValuesBlockedStencil() may offer much better efficiency
769    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
770 
771    Level: beginner
772 
773    Concepts: matrices^putting entries in
774 
775 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
776           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
777 @*/
778 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
779 {
780   PetscErrorCode ierr;
781   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
782   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
783 
784   PetscFunctionBegin;
785   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
786   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
787   PetscValidType(mat,1);
788   PetscValidIntPointer(idxm,3);
789   PetscValidIntPointer(idxn,5);
790   PetscValidScalarPointer(v,6);
791 
792   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
793   if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
794 
795   for (i=0; i<m; i++) {
796     for (j=0; j<3-sdim; j++) dxm++;
797     tmp = *dxm++ - starts[0];
798     for (j=0; j<dim-1; j++) {
799       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
800       else                                       tmp = tmp*dims[j] + dxm[-1] - starts[j+1];
801     }
802     if (mat->stencil.noc) dxm++;
803     jdxm[i] = tmp;
804   }
805   for (i=0; i<n; i++) {
806     for (j=0; j<3-sdim; j++) dxn++;
807     tmp = *dxn++ - starts[0];
808     for (j=0; j<dim-1; j++) {
809       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
810       else                                       tmp = tmp*dims[j] + dxn[-1] - starts[j+1];
811     }
812     if (mat->stencil.noc) dxn++;
813     jdxn[i] = tmp;
814   }
815   ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
816   PetscFunctionReturn(0);
817 }
818 
819 #undef __FUNCT__
820 #define __FUNCT__ "MatSetValuesBlockedStencil"
821 /*@C
822    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
823      Using structured grid indexing
824 
825    Not Collective
826 
827    Input Parameters:
828 +  mat - the matrix
829 .  v - a logically two-dimensional array of values
830 .  m - number of rows being entered
831 .  idxm - grid coordinates for matrix rows being entered
832 .  n - number of columns being entered
833 .  idxn - grid coordinates for matrix columns being entered
834 -  addv - either ADD_VALUES or INSERT_VALUES, where
835    ADD_VALUES adds values to any existing entries, and
836    INSERT_VALUES replaces existing entries with new values
837 
838    Notes:
839    By default the values, v, are row-oriented and unsorted.
840    See MatSetOption() for other options.
841 
842    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
843    options cannot be mixed without intervening calls to the assembly
844    routines.
845 
846    The grid coordinates are across the entire grid, not just the local portion
847 
848    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
849    as well as in C.
850 
851    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine
852 
853    In order to use this routine you must either obtain the matrix with DAGetMatrix()
854    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
855 
856    The columns and rows in the stencil passed in MUST be contained within the
857    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
858    if you create a DA with an overlap of one grid level and on a particular process its first
859    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
860    first i index you can use in your column and row indices in MatSetStencil() is 5.
861 
862    In Fortran idxm and idxn should be declared as
863 $     MatStencil idxm(4,m),idxn(4,n)
864    and the values inserted using
865 $    idxm(MatStencil_i,1) = i
866 $    idxm(MatStencil_j,1) = j
867 $    idxm(MatStencil_k,1) = k
868    etc
869 
870    Negative indices may be passed in idxm and idxn, these rows and columns are
871    simply ignored. This allows easily inserting element stiffness matrices
872    with homogeneous Dirchlet boundary conditions that you don't want represented
873    in the matrix.
874 
875    Inspired by the structured grid interface to the HYPRE package
876    (http://www.llnl.gov/CASC/hypre)
877 
878    Level: beginner
879 
880    Concepts: matrices^putting entries in
881 
882 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
883           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
884 @*/
885 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
886 {
887   PetscErrorCode ierr;
888   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
889   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
890 
891   PetscFunctionBegin;
892   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
893   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
894   PetscValidType(mat,1);
895   PetscValidIntPointer(idxm,3);
896   PetscValidIntPointer(idxn,5);
897   PetscValidScalarPointer(v,6);
898 
899   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
900   if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);
901 
902   for (i=0; i<m; i++) {
903     for (j=0; j<3-sdim; j++) dxm++;
904     tmp = *dxm++ - starts[0];
905     for (j=0; j<sdim-1; j++) {
906       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
907       else                                      tmp = tmp*dims[j] + dxm[-1] - starts[j+1];
908     }
909     dxm++;
910     jdxm[i] = tmp;
911   }
912   for (i=0; i<n; i++) {
913     for (j=0; j<3-sdim; j++) dxn++;
914     tmp = *dxn++ - starts[0];
915     for (j=0; j<sdim-1; j++) {
916       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
917       else                                       tmp = tmp*dims[j] + dxn[-1] - starts[j+1];
918     }
919     dxn++;
920     jdxn[i] = tmp;
921   }
922   ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr);
923   PetscFunctionReturn(0);
924 }
925 
926 #undef __FUNCT__
927 #define __FUNCT__ "MatSetStencil"
928 /*@
929    MatSetStencil - Sets the grid information for setting values into a matrix via
930         MatSetValuesStencil()
931 
932    Not Collective
933 
934    Input Parameters:
935 +  mat - the matrix
936 .  dim - dimension of the grid 1, 2, or 3
937 .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
938 .  starts - starting point of ghost nodes on your processor in x, y, and z direction
939 -  dof - number of degrees of freedom per node
940 
941 
942    Inspired by the structured grid interface to the HYPRE package
943    (www.llnl.gov/CASC/hyper)
944 
945    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
946    user.
947 
948    Level: beginner
949 
950    Concepts: matrices^putting entries in
951 
952 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
953           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
954 @*/
955 PetscErrorCode PETSCMAT_DLLEXPORT MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
956 {
957   PetscInt i;
958 
959   PetscFunctionBegin;
960   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
961   PetscValidIntPointer(dims,3);
962   PetscValidIntPointer(starts,4);
963 
964   mat->stencil.dim = dim + (dof > 1);
965   for (i=0; i<dim; i++) {
966     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
967     mat->stencil.starts[i] = starts[dim-i-1];
968   }
969   mat->stencil.dims[dim]   = dof;
970   mat->stencil.starts[dim] = 0;
971   mat->stencil.noc         = (PetscTruth)(dof == 1);
972   PetscFunctionReturn(0);
973 }
974 
975 #undef __FUNCT__
976 #define __FUNCT__ "MatSetValuesBlocked"
977 /*@
978    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
979 
980    Not Collective
981 
982    Input Parameters:
983 +  mat - the matrix
984 .  v - a logically two-dimensional array of values
985 .  m, idxm - the number of block rows and their global block indices
986 .  n, idxn - the number of block columns and their global block indices
987 -  addv - either ADD_VALUES or INSERT_VALUES, where
988    ADD_VALUES adds values to any existing entries, and
989    INSERT_VALUES replaces existing entries with new values
990 
991    Notes:
992    By default the values, v, are row-oriented and unsorted. So the layout of
993    v is the same as for MatSetValues(). See MatSetOption() for other options.
994 
995    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
996    options cannot be mixed without intervening calls to the assembly
997    routines.
998 
999    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1000    as well as in C.
1001 
1002    Negative indices may be passed in idxm and idxn, these rows and columns are
1003    simply ignored. This allows easily inserting element stiffness matrices
1004    with homogeneous Dirchlet boundary conditions that you don't want represented
1005    in the matrix.
1006 
1007    Each time an entry is set within a sparse matrix via MatSetValues(),
1008    internal searching must be done to determine where to place the the
1009    data in the matrix storage space.  By instead inserting blocks of
1010    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1011    reduced.
1012 
1013    Restrictions:
1014    MatSetValuesBlocked() is currently supported only for the BAIJ and SBAIJ formats
1015 
1016    Level: intermediate
1017 
1018    Concepts: matrices^putting entries in blocked
1019 
1020 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1021 @*/
1022 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1023 {
1024   PetscErrorCode ierr;
1025 
1026   PetscFunctionBegin;
1027   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
1028   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1029   PetscValidType(mat,1);
1030   PetscValidIntPointer(idxm,3);
1031   PetscValidIntPointer(idxn,5);
1032   PetscValidScalarPointer(v,6);
1033   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1034   if (mat->insertmode == NOT_SET_VALUES) {
1035     mat->insertmode = addv;
1036   }
1037 #if defined(PETSC_USE_DEBUG)
1038   else if (mat->insertmode != addv) {
1039     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1040   }
1041   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1042 #endif
1043 
1044   if (mat->assembled) {
1045     mat->was_assembled = PETSC_TRUE;
1046     mat->assembled     = PETSC_FALSE;
1047   }
1048   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1049   if (!mat->ops->setvaluesblocked) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1050   ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
1051   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1052   PetscFunctionReturn(0);
1053 }
1054 
1055 #undef __FUNCT__
1056 #define __FUNCT__ "MatGetValues"
1057 /*@
1058    MatGetValues - Gets a block of values from a matrix.
1059 
1060    Not Collective; currently only returns a local block
1061 
1062    Input Parameters:
1063 +  mat - the matrix
1064 .  v - a logically two-dimensional array for storing the values
1065 .  m, idxm - the number of rows and their global indices
1066 -  n, idxn - the number of columns and their global indices
1067 
1068    Notes:
1069    The user must allocate space (m*n PetscScalars) for the values, v.
1070    The values, v, are then returned in a row-oriented format,
1071    analogous to that used by default in MatSetValues().
1072 
1073    MatGetValues() uses 0-based row and column numbers in
1074    Fortran as well as in C.
1075 
1076    MatGetValues() requires that the matrix has been assembled
1077    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1078    MatSetValues() and MatGetValues() CANNOT be made in succession
1079    without intermediate matrix assembly.
1080 
1081    Level: advanced
1082 
1083    Concepts: matrices^accessing values
1084 
1085 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
1086 @*/
1087 PetscErrorCode PETSCMAT_DLLEXPORT MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1088 {
1089   PetscErrorCode ierr;
1090 
1091   PetscFunctionBegin;
1092   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1093   PetscValidType(mat,1);
1094   PetscValidIntPointer(idxm,3);
1095   PetscValidIntPointer(idxn,5);
1096   PetscValidScalarPointer(v,6);
1097   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1098   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1099   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1100   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1101 
1102   ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1103   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
1104   ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr);
1105   PetscFunctionReturn(0);
1106 }
1107 
1108 #undef __FUNCT__
1109 #define __FUNCT__ "MatSetLocalToGlobalMapping"
1110 /*@
1111    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1112    the routine MatSetValuesLocal() to allow users to insert matrix entries
1113    using a local (per-processor) numbering.
1114 
1115    Not Collective
1116 
1117    Input Parameters:
1118 +  x - the matrix
1119 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
1120              or ISLocalToGlobalMappingCreateIS()
1121 
1122    Level: intermediate
1123 
1124    Concepts: matrices^local to global mapping
1125    Concepts: local to global mapping^for matrices
1126 
1127 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1128 @*/
1129 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1130 {
1131   PetscErrorCode ierr;
1132   PetscFunctionBegin;
1133   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1134   PetscValidType(x,1);
1135   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1136   if (x->mapping) {
1137     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1138   }
1139   ierr = MatPreallocated(x);CHKERRQ(ierr);
1140 
1141   if (x->ops->setlocaltoglobalmapping) {
1142     ierr = (*x->ops->setlocaltoglobalmapping)(x,mapping);CHKERRQ(ierr);
1143   } else {
1144     x->mapping = mapping;
1145     ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1146   }
1147   PetscFunctionReturn(0);
1148 }
1149 
1150 #undef __FUNCT__
1151 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock"
1152 /*@
1153    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1154    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1155    entries using a local (per-processor) numbering.
1156 
1157    Not Collective
1158 
1159    Input Parameters:
1160 +  x - the matrix
1161 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
1162              ISLocalToGlobalMappingCreateIS()
1163 
1164    Level: intermediate
1165 
1166    Concepts: matrices^local to global mapping blocked
1167    Concepts: local to global mapping^for matrices, blocked
1168 
1169 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1170            MatSetValuesBlocked(), MatSetValuesLocal()
1171 @*/
1172 PetscErrorCode PETSCMAT_DLLEXPORT MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1173 {
1174   PetscErrorCode ierr;
1175   PetscFunctionBegin;
1176   PetscValidHeaderSpecific(x,MAT_COOKIE,1);
1177   PetscValidType(x,1);
1178   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,2);
1179   if (x->bmapping) {
1180     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1181   }
1182   x->bmapping = mapping;
1183   ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr);
1184   PetscFunctionReturn(0);
1185 }
1186 
1187 #undef __FUNCT__
1188 #define __FUNCT__ "MatSetValuesLocal"
1189 /*@
1190    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1191    using a local ordering of the nodes.
1192 
1193    Not Collective
1194 
1195    Input Parameters:
1196 +  x - the matrix
1197 .  nrow, irow - number of rows and their local indices
1198 .  ncol, icol - number of columns and their local indices
1199 .  y -  a logically two-dimensional array of values
1200 -  addv - either INSERT_VALUES or ADD_VALUES, where
1201    ADD_VALUES adds values to any existing entries, and
1202    INSERT_VALUES replaces existing entries with new values
1203 
1204    Notes:
1205    Before calling MatSetValuesLocal(), the user must first set the
1206    local-to-global mapping by calling MatSetLocalToGlobalMapping().
1207 
1208    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1209    options cannot be mixed without intervening calls to the assembly
1210    routines.
1211 
1212    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1213    MUST be called after all calls to MatSetValuesLocal() have been completed.
1214 
1215    Level: intermediate
1216 
1217    Concepts: matrices^putting entries in with local numbering
1218 
1219 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1220            MatSetValueLocal()
1221 @*/
1222 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1223 {
1224   PetscErrorCode ierr;
1225   PetscInt       irowm[2048],icolm[2048];
1226 
1227   PetscFunctionBegin;
1228   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1229   PetscValidType(mat,1);
1230   PetscValidIntPointer(irow,3);
1231   PetscValidIntPointer(icol,5);
1232   PetscValidScalarPointer(y,6);
1233   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1234   if (mat->insertmode == NOT_SET_VALUES) {
1235     mat->insertmode = addv;
1236   }
1237 #if defined(PETSC_USE_DEBUG)
1238   else if (mat->insertmode != addv) {
1239     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1240   }
1241   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1242     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1243   }
1244   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1245 #endif
1246 
1247   if (mat->assembled) {
1248     mat->was_assembled = PETSC_TRUE;
1249     mat->assembled     = PETSC_FALSE;
1250   }
1251   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1252   if (!mat->ops->setvalueslocal) {
1253     ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr);
1254     ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
1255     ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1256   } else {
1257     ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr);
1258   }
1259   mat->same_nonzero = PETSC_FALSE;
1260   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1261   PetscFunctionReturn(0);
1262 }
1263 
1264 #undef __FUNCT__
1265 #define __FUNCT__ "MatSetValuesBlockedLocal"
1266 /*@
1267    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1268    using a local ordering of the nodes a block at a time.
1269 
1270    Not Collective
1271 
1272    Input Parameters:
1273 +  x - the matrix
1274 .  nrow, irow - number of rows and their local indices
1275 .  ncol, icol - number of columns and their local indices
1276 .  y -  a logically two-dimensional array of values
1277 -  addv - either INSERT_VALUES or ADD_VALUES, where
1278    ADD_VALUES adds values to any existing entries, and
1279    INSERT_VALUES replaces existing entries with new values
1280 
1281    Notes:
1282    Before calling MatSetValuesBlockedLocal(), the user must first set the
1283    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1284    where the mapping MUST be set for matrix blocks, not for matrix elements.
1285 
1286    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1287    options cannot be mixed without intervening calls to the assembly
1288    routines.
1289 
1290    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1291    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
1292 
1293    Level: intermediate
1294 
1295    Concepts: matrices^putting blocked values in with local numbering
1296 
1297 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1298 @*/
1299 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1300 {
1301   PetscErrorCode ierr;
1302   PetscInt       irowm[2048],icolm[2048];
1303 
1304   PetscFunctionBegin;
1305   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1306   PetscValidType(mat,1);
1307   PetscValidIntPointer(irow,3);
1308   PetscValidIntPointer(icol,5);
1309   PetscValidScalarPointer(y,6);
1310   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1311   if (mat->insertmode == NOT_SET_VALUES) {
1312     mat->insertmode = addv;
1313   }
1314 #if defined(PETSC_USE_DEBUG)
1315   else if (mat->insertmode != addv) {
1316     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1317   }
1318   if (!mat->bmapping) {
1319     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1320   }
1321   if (nrow > 2048 || ncol > 2048) {
1322     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1323   }
1324   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1325 #endif
1326 
1327   if (mat->assembled) {
1328     mat->was_assembled = PETSC_TRUE;
1329     mat->assembled     = PETSC_FALSE;
1330   }
1331   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1332   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr);
1333   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr);
1334   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
1335   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
1336   PetscFunctionReturn(0);
1337 }
1338 
1339 /* --------------------------------------------------------*/
1340 #undef __FUNCT__
1341 #define __FUNCT__ "MatMult"
1342 /*@
1343    MatMult - Computes the matrix-vector product, y = Ax.
1344 
1345    Collective on Mat and Vec
1346 
1347    Input Parameters:
1348 +  mat - the matrix
1349 -  x   - the vector to be multiplied
1350 
1351    Output Parameters:
1352 .  y - the result
1353 
1354    Notes:
1355    The vectors x and y cannot be the same.  I.e., one cannot
1356    call MatMult(A,y,y).
1357 
1358    Level: beginner
1359 
1360    Concepts: matrix-vector product
1361 
1362 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1363 @*/
1364 PetscErrorCode PETSCMAT_DLLEXPORT MatMult(Mat mat,Vec x,Vec y)
1365 {
1366   PetscErrorCode ierr;
1367 
1368   PetscFunctionBegin;
1369   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1370   PetscValidType(mat,1);
1371   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1372   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1373 
1374   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1375   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1376   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1377 #ifndef PETSC_HAVE_CONSTRAINTS
1378   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
1379   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->M,y->N);
1380   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->m,y->n);
1381 #endif
1382   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1383 
1384   if (mat->nullsp) {
1385     ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr);
1386   }
1387 
1388   ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1389   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1390   ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr);
1391 
1392   if (mat->nullsp) {
1393     ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr);
1394   }
1395   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1396   PetscFunctionReturn(0);
1397 }
1398 
1399 #undef __FUNCT__
1400 #define __FUNCT__ "MatMultTranspose"
1401 /*@
1402    MatMultTranspose - Computes matrix transpose times a vector.
1403 
1404    Collective on Mat and Vec
1405 
1406    Input Parameters:
1407 +  mat - the matrix
1408 -  x   - the vector to be multilplied
1409 
1410    Output Parameters:
1411 .  y - the result
1412 
1413    Notes:
1414    The vectors x and y cannot be the same.  I.e., one cannot
1415    call MatMultTranspose(A,y,y).
1416 
1417    Level: beginner
1418 
1419    Concepts: matrix vector product^transpose
1420 
1421 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1422 @*/
1423 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTranspose(Mat mat,Vec x,Vec y)
1424 {
1425   PetscErrorCode ierr;
1426   PetscTruth     flg1, flg2;
1427 
1428   PetscFunctionBegin;
1429   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1430   PetscValidType(mat,1);
1431   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1432   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1433 
1434   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1435   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1436   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1437 #ifndef PETSC_HAVE_CONSTRAINTS
1438   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->M,x->N);
1439   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->N,y->N);
1440 #endif
1441   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1442 
1443   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP, "Operation not supported");
1444   ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1445   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1446 
1447   ierr = PetscTypeCompare((PetscObject)mat,MATSEQSBAIJ,&flg1);
1448   ierr = PetscTypeCompare((PetscObject)mat,MATMPISBAIJ,&flg2);
1449   if (flg1 || flg2) { /* mat is in sbaij format */
1450     ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
1451   } else {
1452     ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr);
1453   }
1454   ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr);
1455   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1456   PetscFunctionReturn(0);
1457 }
1458 
1459 #undef __FUNCT__
1460 #define __FUNCT__ "MatMultAdd"
1461 /*@
1462     MatMultAdd -  Computes v3 = v2 + A * v1.
1463 
1464     Collective on Mat and Vec
1465 
1466     Input Parameters:
1467 +   mat - the matrix
1468 -   v1, v2 - the vectors
1469 
1470     Output Parameters:
1471 .   v3 - the result
1472 
1473     Notes:
1474     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1475     call MatMultAdd(A,v1,v2,v1).
1476 
1477     Level: beginner
1478 
1479     Concepts: matrix vector product^addition
1480 
1481 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1482 @*/
1483 PetscErrorCode PETSCMAT_DLLEXPORT MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1484 {
1485   PetscErrorCode ierr;
1486 
1487   PetscFunctionBegin;
1488   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1489   PetscValidType(mat,1);
1490   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1491   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1492   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1493 
1494   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1495   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1496   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->N,v1->N);
1497   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->M,v2->N);
1498   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->M,v3->N);
1499   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->m,v3->n);
1500   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->m,v2->n);
1501   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1502   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1503 
1504   ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1505   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1506   ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1507   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1508   PetscFunctionReturn(0);
1509 }
1510 
1511 #undef __FUNCT__
1512 #define __FUNCT__ "MatMultTransposeAdd"
1513 /*@
1514    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
1515 
1516    Collective on Mat and Vec
1517 
1518    Input Parameters:
1519 +  mat - the matrix
1520 -  v1, v2 - the vectors
1521 
1522    Output Parameters:
1523 .  v3 - the result
1524 
1525    Notes:
1526    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1527    call MatMultTransposeAdd(A,v1,v2,v1).
1528 
1529    Level: beginner
1530 
1531    Concepts: matrix vector product^transpose and addition
1532 
1533 .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1534 @*/
1535 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1536 {
1537   PetscErrorCode ierr;
1538 
1539   PetscFunctionBegin;
1540   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1541   PetscValidType(mat,1);
1542   PetscValidHeaderSpecific(v1,VEC_COOKIE,2);
1543   PetscValidHeaderSpecific(v2,VEC_COOKIE,3);
1544   PetscValidHeaderSpecific(v3,VEC_COOKIE,4);
1545 
1546   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1547   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1548   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1549   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1550   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->M,v1->N);
1551   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->N,v2->N);
1552   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->N,v3->N);
1553   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1554 
1555   ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1556   ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1557   ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr);
1558   ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr);
1559   PetscFunctionReturn(0);
1560 }
1561 
1562 #undef __FUNCT__
1563 #define __FUNCT__ "MatMultConstrained"
1564 /*@
1565    MatMultConstrained - The inner multiplication routine for a
1566    constrained matrix P^T A P.
1567 
1568    Collective on Mat and Vec
1569 
1570    Input Parameters:
1571 +  mat - the matrix
1572 -  x   - the vector to be multilplied
1573 
1574    Output Parameters:
1575 .  y - the result
1576 
1577    Notes:
1578    The vectors x and y cannot be the same.  I.e., one cannot
1579    call MatMult(A,y,y).
1580 
1581    Level: beginner
1582 
1583 .keywords: matrix, multiply, matrix-vector product, constraint
1584 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1585 @*/
1586 PetscErrorCode PETSCMAT_DLLEXPORT MatMultConstrained(Mat mat,Vec x,Vec y)
1587 {
1588   PetscErrorCode ierr;
1589 
1590   PetscFunctionBegin;
1591   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1592   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1593   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1594   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1595   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1596   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1597   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
1598   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->M,y->N);
1599   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->m,y->n);
1600 
1601   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1602   ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr);
1603   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1604   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1605 
1606   PetscFunctionReturn(0);
1607 }
1608 
1609 #undef __FUNCT__
1610 #define __FUNCT__ "MatMultTransposeConstrained"
1611 /*@
1612    MatMultTransposeConstrained - The inner multiplication routine for a
1613    constrained matrix P^T A^T P.
1614 
1615    Collective on Mat and Vec
1616 
1617    Input Parameters:
1618 +  mat - the matrix
1619 -  x   - the vector to be multilplied
1620 
1621    Output Parameters:
1622 .  y - the result
1623 
1624    Notes:
1625    The vectors x and y cannot be the same.  I.e., one cannot
1626    call MatMult(A,y,y).
1627 
1628    Level: beginner
1629 
1630 .keywords: matrix, multiply, matrix-vector product, constraint
1631 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1632 @*/
1633 PetscErrorCode PETSCMAT_DLLEXPORT MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1634 {
1635   PetscErrorCode ierr;
1636 
1637   PetscFunctionBegin;
1638   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1639   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
1640   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1641   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1642   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1643   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1644   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->N,x->N);
1645   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->M,y->N);
1646 
1647   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1648   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
1649   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1650   ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr);
1651 
1652   PetscFunctionReturn(0);
1653 }
1654 /* ------------------------------------------------------------*/
1655 #undef __FUNCT__
1656 #define __FUNCT__ "MatGetInfo"
1657 /*@
1658    MatGetInfo - Returns information about matrix storage (number of
1659    nonzeros, memory, etc.).
1660 
1661    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1662    as the flag
1663 
1664    Input Parameters:
1665 .  mat - the matrix
1666 
1667    Output Parameters:
1668 +  flag - flag indicating the type of parameters to be returned
1669    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1670    MAT_GLOBAL_SUM - sum over all processors)
1671 -  info - matrix information context
1672 
1673    Notes:
1674    The MatInfo context contains a variety of matrix data, including
1675    number of nonzeros allocated and used, number of mallocs during
1676    matrix assembly, etc.  Additional information for factored matrices
1677    is provided (such as the fill ratio, number of mallocs during
1678    factorization, etc.).  Much of this info is printed to STDOUT
1679    when using the runtime options
1680 $       -log_info -mat_view_info
1681 
1682    Example for C/C++ Users:
1683    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1684    data within the MatInfo context.  For example,
1685 .vb
1686       MatInfo info;
1687       Mat     A;
1688       double  mal, nz_a, nz_u;
1689 
1690       MatGetInfo(A,MAT_LOCAL,&info);
1691       mal  = info.mallocs;
1692       nz_a = info.nz_allocated;
1693 .ve
1694 
1695    Example for Fortran Users:
1696    Fortran users should declare info as a double precision
1697    array of dimension MAT_INFO_SIZE, and then extract the parameters
1698    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1699    a complete list of parameter names.
1700 .vb
1701       double  precision info(MAT_INFO_SIZE)
1702       double  precision mal, nz_a
1703       Mat     A
1704       integer ierr
1705 
1706       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1707       mal = info(MAT_INFO_MALLOCS)
1708       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1709 .ve
1710 
1711     Level: intermediate
1712 
1713     Concepts: matrices^getting information on
1714 
1715 @*/
1716 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1717 {
1718   PetscErrorCode ierr;
1719 
1720   PetscFunctionBegin;
1721   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1722   PetscValidType(mat,1);
1723   PetscValidPointer(info,3);
1724   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1725   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1726   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1727   PetscFunctionReturn(0);
1728 }
1729 
1730 /* ----------------------------------------------------------*/
1731 #undef __FUNCT__
1732 #define __FUNCT__ "MatILUDTFactor"
1733 /*@C
1734    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1735 
1736    Collective on Mat
1737 
1738    Input Parameters:
1739 +  mat - the matrix
1740 .  row - row permutation
1741 .  col - column permutation
1742 -  info - information about the factorization to be done
1743 
1744    Output Parameters:
1745 .  fact - the factored matrix
1746 
1747    Level: developer
1748 
1749    Notes:
1750    Most users should employ the simplified KSP interface for linear solvers
1751    instead of working directly with matrix algebra routines such as this.
1752    See, e.g., KSPCreate().
1753 
1754    This is currently only supported for the SeqAIJ matrix format using code
1755    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1756    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1757    and thus can be distributed with PETSc.
1758 
1759     Concepts: matrices^ILUDT factorization
1760 
1761 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1762 @*/
1763 PetscErrorCode PETSCMAT_DLLEXPORT MatILUDTFactor(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
1764 {
1765   PetscErrorCode ierr;
1766 
1767   PetscFunctionBegin;
1768   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1769   PetscValidType(mat,1);
1770   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1771   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1772   PetscValidPointer(info,4);
1773   PetscValidPointer(fact,5);
1774   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1775   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1776   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1777   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1778   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1779   ierr = (*mat->ops->iludtfactor)(mat,row,col,info,fact);CHKERRQ(ierr);
1780   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1781   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
1782 
1783   PetscFunctionReturn(0);
1784 }
1785 
1786 #undef __FUNCT__
1787 #define __FUNCT__ "MatLUFactor"
1788 /*@
1789    MatLUFactor - Performs in-place LU factorization of matrix.
1790 
1791    Collective on Mat
1792 
1793    Input Parameters:
1794 +  mat - the matrix
1795 .  row - row permutation
1796 .  col - column permutation
1797 -  info - options for factorization, includes
1798 $          fill - expected fill as ratio of original fill.
1799 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1800 $                   Run with the option -log_info to determine an optimal value to use
1801 
1802    Notes:
1803    Most users should employ the simplified KSP interface for linear solvers
1804    instead of working directly with matrix algebra routines such as this.
1805    See, e.g., KSPCreate().
1806 
1807    This changes the state of the matrix to a factored matrix; it cannot be used
1808    for example with MatSetValues() unless one first calls MatSetUnfactored().
1809 
1810    Level: developer
1811 
1812    Concepts: matrices^LU factorization
1813 
1814 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1815           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
1816 
1817 @*/
1818 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1819 {
1820   PetscErrorCode ierr;
1821 
1822   PetscFunctionBegin;
1823   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1824   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1825   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1826   PetscValidPointer(info,4);
1827   PetscValidType(mat,1);
1828   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1829   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1830   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1831   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1832 
1833   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1834   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
1835   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1836   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
1837   PetscFunctionReturn(0);
1838 }
1839 
1840 #undef __FUNCT__
1841 #define __FUNCT__ "MatILUFactor"
1842 /*@
1843    MatILUFactor - Performs in-place ILU factorization of matrix.
1844 
1845    Collective on Mat
1846 
1847    Input Parameters:
1848 +  mat - the matrix
1849 .  row - row permutation
1850 .  col - column permutation
1851 -  info - structure containing
1852 $      levels - number of levels of fill.
1853 $      expected fill - as ratio of original fill.
1854 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1855                 missing diagonal entries)
1856 
1857    Notes:
1858    Probably really in-place only when level of fill is zero, otherwise allocates
1859    new space to store factored matrix and deletes previous memory.
1860 
1861    Most users should employ the simplified KSP interface for linear solvers
1862    instead of working directly with matrix algebra routines such as this.
1863    See, e.g., KSPCreate().
1864 
1865    Level: developer
1866 
1867    Concepts: matrices^ILU factorization
1868 
1869 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1870 @*/
1871 PetscErrorCode PETSCMAT_DLLEXPORT MatILUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1872 {
1873   PetscErrorCode ierr;
1874 
1875   PetscFunctionBegin;
1876   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1877   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1878   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1879   PetscValidPointer(info,4);
1880   PetscValidType(mat,1);
1881   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1882   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1883   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1884   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1885   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1886 
1887   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1888   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
1889   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1890   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
1891   PetscFunctionReturn(0);
1892 }
1893 
1894 #undef __FUNCT__
1895 #define __FUNCT__ "MatLUFactorSymbolic"
1896 /*@
1897    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1898    Call this routine before calling MatLUFactorNumeric().
1899 
1900    Collective on Mat
1901 
1902    Input Parameters:
1903 +  mat - the matrix
1904 .  row, col - row and column permutations
1905 -  info - options for factorization, includes
1906 $          fill - expected fill as ratio of original fill.
1907 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1908 $                   Run with the option -log_info to determine an optimal value to use
1909 
1910    Output Parameter:
1911 .  fact - new matrix that has been symbolically factored
1912 
1913    Notes:
1914    See the users manual for additional information about
1915    choosing the fill factor for better efficiency.
1916 
1917    Most users should employ the simplified KSP interface for linear solvers
1918    instead of working directly with matrix algebra routines such as this.
1919    See, e.g., KSPCreate().
1920 
1921    Level: developer
1922 
1923    Concepts: matrices^LU symbolic factorization
1924 
1925 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1926 @*/
1927 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
1928 {
1929   PetscErrorCode ierr;
1930 
1931   PetscFunctionBegin;
1932   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1933   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
1934   if (col) PetscValidHeaderSpecific(col,IS_COOKIE,3);
1935   PetscValidPointer(info,4);
1936   PetscValidType(mat,1);
1937   PetscValidPointer(fact,5);
1938   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1939   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1940   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);
1941   ierr = MatPreallocated(mat);CHKERRQ(ierr);
1942 
1943   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1944   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
1945   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1946   ierr = PetscObjectStateIncrease((PetscObject)*fact);CHKERRQ(ierr);
1947   PetscFunctionReturn(0);
1948 }
1949 
1950 #undef __FUNCT__
1951 #define __FUNCT__ "MatLUFactorNumeric"
1952 /*@
1953    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1954    Call this routine after first calling MatLUFactorSymbolic().
1955 
1956    Collective on Mat
1957 
1958    Input Parameters:
1959 +  mat - the matrix
1960 .  info - options for factorization
1961 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
1962 
1963    Notes:
1964    See MatLUFactor() for in-place factorization.  See
1965    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1966 
1967    Most users should employ the simplified KSP interface for linear solvers
1968    instead of working directly with matrix algebra routines such as this.
1969    See, e.g., KSPCreate().
1970 
1971    Level: developer
1972 
1973    Concepts: matrices^LU numeric factorization
1974 
1975 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1976 @*/
1977 PetscErrorCode PETSCMAT_DLLEXPORT MatLUFactorNumeric(Mat mat,MatFactorInfo *info,Mat *fact)
1978 {
1979   PetscErrorCode ierr;
1980 
1981   PetscFunctionBegin;
1982   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
1983   PetscValidType(mat,1);
1984   PetscValidPointer(fact,2);
1985   PetscValidHeaderSpecific(*fact,MAT_COOKIE,2);
1986   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1987   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1988     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %D should = %D %D should = %D",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 /*@
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 /*@
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,"MatPermute not available for 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 MatSetValuesBlocked() while
5245      the stash is used for values set with MatSetValues()
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 = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
5265   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
5266   PetscFunctionReturn(0);
5267 }
5268 
5269 #undef __FUNCT__
5270 #define __FUNCT__ "MatInterpolateAdd"
5271 /*@
5272    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
5273      the matrix
5274 
5275    Collective on Mat
5276 
5277    Input Parameters:
5278 +  mat   - the matrix
5279 .  x,y - the vectors
5280 -  w - where the result is stored
5281 
5282    Level: intermediate
5283 
5284    Notes:
5285     w may be the same vector as y.
5286 
5287     This allows one to use either the restriction or interpolation (its transpose)
5288     matrix to do the interpolation
5289 
5290     Concepts: interpolation
5291 
5292 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5293 
5294 @*/
5295 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
5296 {
5297   PetscErrorCode ierr;
5298   PetscInt       M,N;
5299 
5300   PetscFunctionBegin;
5301   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5302   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5303   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5304   PetscValidHeaderSpecific(w,VEC_COOKIE,4);
5305   PetscValidType(A,1);
5306   ierr = MatPreallocated(A);CHKERRQ(ierr);
5307   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5308   if (N > M) {
5309     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
5310   } else {
5311     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
5312   }
5313   PetscFunctionReturn(0);
5314 }
5315 
5316 #undef __FUNCT__
5317 #define __FUNCT__ "MatInterpolate"
5318 /*@
5319    MatInterpolate - y = A*x or A'*x depending on the shape of
5320      the matrix
5321 
5322    Collective on Mat
5323 
5324    Input Parameters:
5325 +  mat   - the matrix
5326 -  x,y - the vectors
5327 
5328    Level: intermediate
5329 
5330    Notes:
5331     This allows one to use either the restriction or interpolation (its transpose)
5332     matrix to do the interpolation
5333 
5334    Concepts: matrices^interpolation
5335 
5336 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
5337 
5338 @*/
5339 PetscErrorCode PETSCMAT_DLLEXPORT MatInterpolate(Mat A,Vec x,Vec y)
5340 {
5341   PetscErrorCode ierr;
5342   PetscInt       M,N;
5343 
5344   PetscFunctionBegin;
5345   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5346   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5347   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5348   PetscValidType(A,1);
5349   ierr = MatPreallocated(A);CHKERRQ(ierr);
5350   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5351   if (N > M) {
5352     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5353   } else {
5354     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5355   }
5356   PetscFunctionReturn(0);
5357 }
5358 
5359 #undef __FUNCT__
5360 #define __FUNCT__ "MatRestrict"
5361 /*@
5362    MatRestrict - y = A*x or A'*x
5363 
5364    Collective on Mat
5365 
5366    Input Parameters:
5367 +  mat   - the matrix
5368 -  x,y - the vectors
5369 
5370    Level: intermediate
5371 
5372    Notes:
5373     This allows one to use either the restriction or interpolation (its transpose)
5374     matrix to do the restriction
5375 
5376    Concepts: matrices^restriction
5377 
5378 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
5379 
5380 @*/
5381 PetscErrorCode PETSCMAT_DLLEXPORT MatRestrict(Mat A,Vec x,Vec y)
5382 {
5383   PetscErrorCode ierr;
5384   PetscInt       M,N;
5385 
5386   PetscFunctionBegin;
5387   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5388   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
5389   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
5390   PetscValidType(A,1);
5391   ierr = MatPreallocated(A);CHKERRQ(ierr);
5392 
5393   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
5394   if (N > M) {
5395     ierr = MatMult(A,x,y);CHKERRQ(ierr);
5396   } else {
5397     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
5398   }
5399   PetscFunctionReturn(0);
5400 }
5401 
5402 #undef __FUNCT__
5403 #define __FUNCT__ "MatNullSpaceAttach"
5404 /*@C
5405    MatNullSpaceAttach - attaches a null space to a matrix.
5406         This null space will be removed from the resulting vector whenever
5407         MatMult() is called
5408 
5409    Collective on Mat
5410 
5411    Input Parameters:
5412 +  mat - the matrix
5413 -  nullsp - the null space object
5414 
5415    Level: developer
5416 
5417    Notes:
5418       Overwrites any previous null space that may have been attached
5419 
5420    Concepts: null space^attaching to matrix
5421 
5422 .seealso: MatCreate(), MatNullSpaceCreate()
5423 @*/
5424 PetscErrorCode PETSCMAT_DLLEXPORT MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
5425 {
5426   PetscErrorCode ierr;
5427 
5428   PetscFunctionBegin;
5429   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5430   PetscValidType(mat,1);
5431   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE,2);
5432   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5433 
5434   if (mat->nullsp) {
5435     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
5436   }
5437   mat->nullsp = nullsp;
5438   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
5439   PetscFunctionReturn(0);
5440 }
5441 
5442 #undef __FUNCT__
5443 #define __FUNCT__ "MatICCFactor"
5444 /*@
5445    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
5446 
5447    Collective on Mat
5448 
5449    Input Parameters:
5450 +  mat - the matrix
5451 .  row - row/column permutation
5452 .  fill - expected fill factor >= 1.0
5453 -  level - level of fill, for ICC(k)
5454 
5455    Notes:
5456    Probably really in-place only when level of fill is zero, otherwise allocates
5457    new space to store factored matrix and deletes previous memory.
5458 
5459    Most users should employ the simplified KSP interface for linear solvers
5460    instead of working directly with matrix algebra routines such as this.
5461    See, e.g., KSPCreate().
5462 
5463    Level: developer
5464 
5465    Concepts: matrices^incomplete Cholesky factorization
5466    Concepts: Cholesky factorization
5467 
5468 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5469 @*/
5470 PetscErrorCode PETSCMAT_DLLEXPORT MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5471 {
5472   PetscErrorCode ierr;
5473 
5474   PetscFunctionBegin;
5475   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5476   PetscValidType(mat,1);
5477   if (row) PetscValidHeaderSpecific(row,IS_COOKIE,2);
5478   PetscValidPointer(info,3);
5479   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5480   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5481   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5482   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5483   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5484   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5485   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5486   PetscFunctionReturn(0);
5487 }
5488 
5489 #undef __FUNCT__
5490 #define __FUNCT__ "MatSetValuesAdic"
5491 /*@
5492    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5493 
5494    Not Collective
5495 
5496    Input Parameters:
5497 +  mat - the matrix
5498 -  v - the values compute with ADIC
5499 
5500    Level: developer
5501 
5502    Notes:
5503      Must call MatSetColoring() before using this routine. Also this matrix must already
5504      have its nonzero pattern determined.
5505 
5506 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5507           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5508 @*/
5509 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdic(Mat mat,void *v)
5510 {
5511   PetscErrorCode ierr;
5512 
5513   PetscFunctionBegin;
5514   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5515   PetscValidType(mat,1);
5516   PetscValidPointer(mat,2);
5517 
5518   if (!mat->assembled) {
5519     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5520   }
5521   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5522   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5523   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5524   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5525   ierr = MatView_Private(mat);CHKERRQ(ierr);
5526   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5527   PetscFunctionReturn(0);
5528 }
5529 
5530 
5531 #undef __FUNCT__
5532 #define __FUNCT__ "MatSetColoring"
5533 /*@
5534    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5535 
5536    Not Collective
5537 
5538    Input Parameters:
5539 +  mat - the matrix
5540 -  coloring - the coloring
5541 
5542    Level: developer
5543 
5544 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5545           MatSetValues(), MatSetValuesAdic()
5546 @*/
5547 PetscErrorCode PETSCMAT_DLLEXPORT MatSetColoring(Mat mat,ISColoring coloring)
5548 {
5549   PetscErrorCode ierr;
5550 
5551   PetscFunctionBegin;
5552   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5553   PetscValidType(mat,1);
5554   PetscValidPointer(coloring,2);
5555 
5556   if (!mat->assembled) {
5557     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5558   }
5559   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5560   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5561   PetscFunctionReturn(0);
5562 }
5563 
5564 #undef __FUNCT__
5565 #define __FUNCT__ "MatSetValuesAdifor"
5566 /*@
5567    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5568 
5569    Not Collective
5570 
5571    Input Parameters:
5572 +  mat - the matrix
5573 .  nl - leading dimension of v
5574 -  v - the values compute with ADIFOR
5575 
5576    Level: developer
5577 
5578    Notes:
5579      Must call MatSetColoring() before using this routine. Also this matrix must already
5580      have its nonzero pattern determined.
5581 
5582 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5583           MatSetValues(), MatSetColoring()
5584 @*/
5585 PetscErrorCode PETSCMAT_DLLEXPORT MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
5586 {
5587   PetscErrorCode ierr;
5588 
5589   PetscFunctionBegin;
5590   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5591   PetscValidType(mat,1);
5592   PetscValidPointer(v,3);
5593 
5594   if (!mat->assembled) {
5595     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5596   }
5597   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5598   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5599   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5600   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5601   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5602   PetscFunctionReturn(0);
5603 }
5604 
5605 #undef __FUNCT__
5606 #define __FUNCT__ "MatDiagonalScaleLocal"
5607 /*@
5608    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5609          ghosted ones.
5610 
5611    Not Collective
5612 
5613    Input Parameters:
5614 +  mat - the matrix
5615 -  diag = the diagonal values, including ghost ones
5616 
5617    Level: developer
5618 
5619    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5620 
5621 .seealso: MatDiagonalScale()
5622 @*/
5623 PetscErrorCode PETSCMAT_DLLEXPORT MatDiagonalScaleLocal(Mat mat,Vec diag)
5624 {
5625   PetscErrorCode ierr;
5626   PetscMPIInt    size;
5627 
5628   PetscFunctionBegin;
5629   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5630   PetscValidHeaderSpecific(diag,VEC_COOKIE,2);
5631   PetscValidType(mat,1);
5632 
5633   if (!mat->assembled) {
5634     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
5635   }
5636   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5637   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5638   if (size == 1) {
5639     PetscInt n,m;
5640     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5641     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5642     if (m == n) {
5643       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5644     } else {
5645       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
5646     }
5647   } else {
5648     PetscErrorCode (*f)(Mat,Vec);
5649     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5650     if (f) {
5651       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5652     } else {
5653       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5654     }
5655   }
5656   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5657   ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr);
5658   PetscFunctionReturn(0);
5659 }
5660 
5661 #undef __FUNCT__
5662 #define __FUNCT__ "MatGetInertia"
5663 /*@
5664    MatGetInertia - Gets the inertia from a factored matrix
5665 
5666    Collective on Mat
5667 
5668    Input Parameter:
5669 .  mat - the matrix
5670 
5671    Output Parameters:
5672 +   nneg - number of negative eigenvalues
5673 .   nzero - number of zero eigenvalues
5674 -   npos - number of positive eigenvalues
5675 
5676    Level: advanced
5677 
5678    Notes: Matrix must have been factored by MatCholeskyFactor()
5679 
5680 
5681 @*/
5682 PetscErrorCode PETSCMAT_DLLEXPORT MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
5683 {
5684   PetscErrorCode ierr;
5685 
5686   PetscFunctionBegin;
5687   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5688   PetscValidType(mat,1);
5689   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5690   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5691   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5692   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5693   PetscFunctionReturn(0);
5694 }
5695 
5696 /* ----------------------------------------------------------------*/
5697 #undef __FUNCT__
5698 #define __FUNCT__ "MatSolves"
5699 /*@
5700    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5701 
5702    Collective on Mat and Vecs
5703 
5704    Input Parameters:
5705 +  mat - the factored matrix
5706 -  b - the right-hand-side vectors
5707 
5708    Output Parameter:
5709 .  x - the result vectors
5710 
5711    Notes:
5712    The vectors b and x cannot be the same.  I.e., one cannot
5713    call MatSolves(A,x,x).
5714 
5715    Notes:
5716    Most users should employ the simplified KSP interface for linear solvers
5717    instead of working directly with matrix algebra routines such as this.
5718    See, e.g., KSPCreate().
5719 
5720    Level: developer
5721 
5722    Concepts: matrices^triangular solves
5723 
5724 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
5725 @*/
5726 PetscErrorCode PETSCMAT_DLLEXPORT MatSolves(Mat mat,Vecs b,Vecs x)
5727 {
5728   PetscErrorCode ierr;
5729 
5730   PetscFunctionBegin;
5731   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5732   PetscValidType(mat,1);
5733   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
5734   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5735   if (!mat->M && !mat->N) PetscFunctionReturn(0);
5736 
5737   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5738   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5739   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5740   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
5741   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5742   PetscFunctionReturn(0);
5743 }
5744 
5745 #undef __FUNCT__
5746 #define __FUNCT__ "MatIsSymmetric"
5747 /*@
5748    MatIsSymmetric - Test whether a matrix is symmetric
5749 
5750    Collective on Mat
5751 
5752    Input Parameter:
5753 +  A - the matrix to test
5754 -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
5755 
5756    Output Parameters:
5757 .  flg - the result
5758 
5759    Level: intermediate
5760 
5761    Concepts: matrix^symmetry
5762 
5763 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
5764 @*/
5765 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
5766 {
5767   PetscErrorCode ierr;
5768 
5769   PetscFunctionBegin;
5770   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5771   PetscValidPointer(flg,2);
5772   if (!A->symmetric_set) {
5773     if (!A->ops->issymmetric) {
5774       MatType mattype;
5775       ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
5776       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
5777     }
5778     ierr = (*A->ops->issymmetric)(A,tol,&A->symmetric);CHKERRQ(ierr);
5779     A->symmetric_set = PETSC_TRUE;
5780     if (A->symmetric) {
5781       A->structurally_symmetric_set = PETSC_TRUE;
5782       A->structurally_symmetric     = PETSC_TRUE;
5783     }
5784   }
5785   *flg = A->symmetric;
5786   PetscFunctionReturn(0);
5787 }
5788 
5789 #undef __FUNCT__
5790 #define __FUNCT__ "MatIsSymmetricKnown"
5791 /*@
5792    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
5793 
5794    Collective on Mat
5795 
5796    Input Parameter:
5797 .  A - the matrix to check
5798 
5799    Output Parameters:
5800 +  set - if the symmetric flag is set (this tells you if the next flag is valid)
5801 -  flg - the result
5802 
5803    Level: advanced
5804 
5805    Concepts: matrix^symmetry
5806 
5807    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
5808          if you want it explicitly checked
5809 
5810 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
5811 @*/
5812 PetscErrorCode PETSCMAT_DLLEXPORT MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
5813 {
5814   PetscFunctionBegin;
5815   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5816   PetscValidPointer(set,2);
5817   PetscValidPointer(flg,3);
5818   if (A->symmetric_set) {
5819     *set = PETSC_TRUE;
5820     *flg = A->symmetric;
5821   } else {
5822     *set = PETSC_FALSE;
5823   }
5824   PetscFunctionReturn(0);
5825 }
5826 
5827 #undef __FUNCT__
5828 #define __FUNCT__ "MatIsHermitianKnown"
5829 /*@
5830    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
5831 
5832    Collective on Mat
5833 
5834    Input Parameter:
5835 .  A - the matrix to check
5836 
5837    Output Parameters:
5838 +  set - if the hermitian flag is set (this tells you if the next flag is valid)
5839 -  flg - the result
5840 
5841    Level: advanced
5842 
5843    Concepts: matrix^symmetry
5844 
5845    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
5846          if you want it explicitly checked
5847 
5848 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
5849 @*/
5850 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
5851 {
5852   PetscFunctionBegin;
5853   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5854   PetscValidPointer(set,2);
5855   PetscValidPointer(flg,3);
5856   if (A->hermitian_set) {
5857     *set = PETSC_TRUE;
5858     *flg = A->hermitian;
5859   } else {
5860     *set = PETSC_FALSE;
5861   }
5862   PetscFunctionReturn(0);
5863 }
5864 
5865 #undef __FUNCT__
5866 #define __FUNCT__ "MatIsStructurallySymmetric"
5867 /*@
5868    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
5869 
5870    Collective on Mat
5871 
5872    Input Parameter:
5873 .  A - the matrix to test
5874 
5875    Output Parameters:
5876 .  flg - the result
5877 
5878    Level: intermediate
5879 
5880    Concepts: matrix^symmetry
5881 
5882 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
5883 @*/
5884 PetscErrorCode PETSCMAT_DLLEXPORT MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
5885 {
5886   PetscErrorCode ierr;
5887 
5888   PetscFunctionBegin;
5889   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5890   PetscValidPointer(flg,2);
5891   if (!A->structurally_symmetric_set) {
5892     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
5893     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
5894     A->structurally_symmetric_set = PETSC_TRUE;
5895   }
5896   *flg = A->structurally_symmetric;
5897   PetscFunctionReturn(0);
5898 }
5899 
5900 #undef __FUNCT__
5901 #define __FUNCT__ "MatIsHermitian"
5902 /*@
5903    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
5904 
5905    Collective on Mat
5906 
5907    Input Parameter:
5908 .  A - the matrix to test
5909 
5910    Output Parameters:
5911 .  flg - the result
5912 
5913    Level: intermediate
5914 
5915    Concepts: matrix^symmetry
5916 
5917 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
5918 @*/
5919 PetscErrorCode PETSCMAT_DLLEXPORT MatIsHermitian(Mat A,PetscTruth *flg)
5920 {
5921   PetscErrorCode ierr;
5922 
5923   PetscFunctionBegin;
5924   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
5925   PetscValidPointer(flg,2);
5926   if (!A->hermitian_set) {
5927     if (!A->ops->ishermitian) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for being Hermitian");
5928     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
5929     A->hermitian_set = PETSC_TRUE;
5930     if (A->hermitian) {
5931       A->structurally_symmetric_set = PETSC_TRUE;
5932       A->structurally_symmetric     = PETSC_TRUE;
5933     }
5934   }
5935   *flg = A->hermitian;
5936   PetscFunctionReturn(0);
5937 }
5938 
5939 #undef __FUNCT__
5940 #define __FUNCT__ "MatStashGetInfo"
5941 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
5942 /*@
5943    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
5944        to be communicated to other processors during the MatAssemblyBegin/End() process
5945 
5946     Not collective
5947 
5948    Input Parameter:
5949 .   vec - the vector
5950 
5951    Output Parameters:
5952 +   nstash   - the size of the stash
5953 .   reallocs - the number of additional mallocs incurred.
5954 .   bnstash   - the size of the block stash
5955 -   breallocs - the number of additional mallocs incurred.in the block stash
5956 
5957    Level: advanced
5958 
5959 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
5960 
5961 @*/
5962 PetscErrorCode PETSCMAT_DLLEXPORT MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *brealloc)
5963 {
5964   PetscErrorCode ierr;
5965   PetscFunctionBegin;
5966   ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr);
5967   ierr = MatStashGetInfo_Private(&mat->bstash,nstash,reallocs);CHKERRQ(ierr);
5968   PetscFunctionReturn(0);
5969 }
5970 
5971 #undef __FUNCT__
5972 #define __FUNCT__ "MatGetVecs"
5973 /*@
5974    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
5975      parallel layout
5976 
5977    Collective on Mat
5978 
5979    Input Parameter:
5980 .  mat - the matrix
5981 
5982    Output Parameter:
5983 +   right - (optional) vector that the matrix can be multiplied against
5984 -   left - (optional) vector that the matrix vector product can be stored in
5985 
5986   Level: advanced
5987 
5988 .seealso: MatCreate()
5989 @*/
5990 PetscErrorCode PETSCMAT_DLLEXPORT MatGetVecs(Mat mat,Vec *right,Vec *left)
5991 {
5992   PetscErrorCode ierr;
5993 
5994   PetscFunctionBegin;
5995   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
5996   PetscValidType(mat,1);
5997   ierr = MatPreallocated(mat);CHKERRQ(ierr);
5998   if (mat->ops->getvecs) {
5999     ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr);
6000   } else {
6001     PetscMPIInt size;
6002     ierr = MPI_Comm_size(mat->comm, &size);CHKERRQ(ierr);
6003     if (right) {
6004       ierr = VecCreate(mat->comm,right);CHKERRQ(ierr);
6005       ierr = VecSetSizes(*right,mat->n,PETSC_DETERMINE);CHKERRQ(ierr);
6006       if (size > 1) {ierr = VecSetType(*right,VECMPI);CHKERRQ(ierr);}
6007       else {ierr = VecSetType(*right,VECSEQ);CHKERRQ(ierr);}
6008     }
6009     if (left) {
6010       ierr = VecCreate(mat->comm,left);CHKERRQ(ierr);
6011       ierr = VecSetSizes(*left,mat->m,PETSC_DETERMINE);CHKERRQ(ierr);
6012       if (size > 1) {ierr = VecSetType(*left,VECMPI);CHKERRQ(ierr);}
6013       else {ierr = VecSetType(*left,VECSEQ);CHKERRQ(ierr);}
6014     }
6015   }
6016   if (right) {ierr = VecSetBlockSize(*right,mat->bs);CHKERRQ(ierr);}
6017   if (left) {ierr = VecSetBlockSize(*left,mat->bs);CHKERRQ(ierr);}
6018   PetscFunctionReturn(0);
6019 }
6020 
6021 #undef __FUNCT__
6022 #define __FUNCT__ "MatFactorInfoInitialize"
6023 /*@C
6024    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
6025      with default values.
6026 
6027    Not Collective
6028 
6029    Input Parameters:
6030 .    info - the MatFactorInfo data structure
6031 
6032 
6033    Notes: The solvers are generally used through the KSP and PC objects, for example
6034           PCLU, PCILU, PCCHOLESKY, PCICC
6035 
6036    Level: developer
6037 
6038 .seealso: MatFactorInfo
6039 @*/
6040 
6041 PetscErrorCode PETSCMAT_DLLEXPORT MatFactorInfoInitialize(MatFactorInfo *info)
6042 {
6043   PetscErrorCode ierr;
6044 
6045   PetscFunctionBegin;
6046   ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr);
6047   PetscFunctionReturn(0);
6048 }
6049 
6050 #undef __FUNCT__
6051 #define __FUNCT__ "MatPtAP"
6052 /*@C
6053    MatPtAP - Creates the matrix projection C = P^T * A * P
6054 
6055    Collective on Mat
6056 
6057    Input Parameters:
6058 +  A - the matrix
6059 .  P - the projection matrix
6060 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6061 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
6062 
6063    Output Parameters:
6064 .  C - the product matrix
6065 
6066    Notes:
6067    C will be created and must be destroyed by the user with MatDestroy().
6068 
6069    This routine is currently only implemented for pairs of AIJ matrices and classes
6070    which inherit from AIJ.
6071 
6072    Level: intermediate
6073 
6074 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
6075 @*/
6076 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
6077 {
6078   PetscErrorCode ierr;
6079 
6080   PetscFunctionBegin;
6081   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6082   PetscValidType(A,1);
6083   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6084   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6085   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6086   PetscValidType(P,2);
6087   MatPreallocated(P);
6088   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6089   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6090   PetscValidPointer(C,3);
6091   if (P->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->M,A->N);
6092   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.0",fill);
6093   ierr = MatPreallocated(A);CHKERRQ(ierr);
6094 
6095   ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6096   ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr);
6097   ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr);
6098 
6099   PetscFunctionReturn(0);
6100 }
6101 
6102 #undef __FUNCT__
6103 #define __FUNCT__ "MatPtAPNumeric"
6104 /*@C
6105    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P
6106 
6107    Collective on Mat
6108 
6109    Input Parameters:
6110 +  A - the matrix
6111 -  P - the projection matrix
6112 
6113    Output Parameters:
6114 .  C - the product matrix
6115 
6116    Notes:
6117    C must have been created by calling MatPtAPSymbolic and must be destroyed by
6118    the user using MatDeatroy().
6119 
6120    This routine is currently only implemented for pairs of AIJ matrices and classes
6121    which inherit from AIJ.  C will be of type MATAIJ.
6122 
6123    Level: intermediate
6124 
6125 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
6126 @*/
6127 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPNumeric(Mat A,Mat P,Mat C)
6128 {
6129   PetscErrorCode ierr;
6130 
6131   PetscFunctionBegin;
6132   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6133   PetscValidType(A,1);
6134   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6135   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6136   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6137   PetscValidType(P,2);
6138   MatPreallocated(P);
6139   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6140   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6141   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6142   PetscValidType(C,3);
6143   MatPreallocated(C);
6144   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6145   if (P->N!=C->M) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->N,C->M);
6146   if (P->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->M,A->N);
6147   if (A->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->M,A->N);
6148   if (P->N!=C->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->N,C->N);
6149   ierr = MatPreallocated(A);CHKERRQ(ierr);
6150 
6151   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6152   ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr);
6153   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
6154   PetscFunctionReturn(0);
6155 }
6156 
6157 #undef __FUNCT__
6158 #define __FUNCT__ "MatPtAPSymbolic"
6159 /*@C
6160    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P
6161 
6162    Collective on Mat
6163 
6164    Input Parameters:
6165 +  A - the matrix
6166 -  P - the projection matrix
6167 
6168    Output Parameters:
6169 .  C - the (i,j) structure of the product matrix
6170 
6171    Notes:
6172    C will be created and must be destroyed by the user with MatDestroy().
6173 
6174    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6175    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
6176    this (i,j) structure by calling MatPtAPNumeric().
6177 
6178    Level: intermediate
6179 
6180 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
6181 @*/
6182 PetscErrorCode PETSCMAT_DLLEXPORT MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
6183 {
6184   PetscErrorCode ierr;
6185 
6186   PetscFunctionBegin;
6187   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6188   PetscValidType(A,1);
6189   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6190   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6191   PetscValidHeaderSpecific(P,MAT_COOKIE,2);
6192   PetscValidType(P,2);
6193   MatPreallocated(P);
6194   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6195   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6196   PetscValidPointer(C,3);
6197 
6198   if (P->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->M,A->N);
6199   if (A->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->M,A->N);
6200   ierr = MatPreallocated(A);CHKERRQ(ierr);
6201   ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6202   ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr);
6203   ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr);
6204 
6205   ierr = MatSetBlockSize(*C,A->bs);CHKERRQ(ierr);
6206 
6207   PetscFunctionReturn(0);
6208 }
6209 
6210 #undef __FUNCT__
6211 #define __FUNCT__ "MatMatMult"
6212 /*@
6213    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
6214 
6215    Collective on Mat
6216 
6217    Input Parameters:
6218 +  A - the left matrix
6219 .  B - the right matrix
6220 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6221 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6222 
6223    Output Parameters:
6224 .  C - the product matrix
6225 
6226    Notes:
6227    C will be created and must be destroyed by the user with MatDestroy().
6228 
6229    This routine is currently only implemented for pairs of AIJ matrices and classes
6230    which inherit from AIJ.  C will be of type MATAIJ.
6231 
6232    Level: intermediate
6233 
6234 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
6235 @*/
6236 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6237 {
6238   PetscErrorCode ierr;
6239   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6240   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6241 
6242   PetscFunctionBegin;
6243   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6244   PetscValidType(A,1);
6245   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6246   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6247   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6248   PetscValidType(B,2);
6249   MatPreallocated(B);
6250   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6251   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6252   PetscValidPointer(C,3);
6253   if (B->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->N);
6254   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.0",fill);
6255   ierr = MatPreallocated(A);CHKERRQ(ierr);
6256 
6257   /* For now, we do not dispatch based on the type of A and B */
6258   /* When implementations like _SeqAIJ_MAIJ exist, attack the multiple dispatch problem. */
6259   fA = A->ops->matmult;
6260   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for A of type %s",A->type_name);
6261   fB = B->ops->matmult;
6262   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",B->type_name);
6263   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6264 
6265   ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6266   ierr = (*A->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr);
6267   ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr);
6268 
6269   PetscFunctionReturn(0);
6270 }
6271 
6272 #undef __FUNCT__
6273 #define __FUNCT__ "MatMatMultSymbolic"
6274 /*@
6275    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
6276    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().
6277 
6278    Collective on Mat
6279 
6280    Input Parameters:
6281 +  A - the left matrix
6282 .  B - the right matrix
6283 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6284 
6285    Output Parameters:
6286 .  C - the matrix containing the ij structure of product matrix
6287 
6288    Notes:
6289    C will be created as a MATSEQAIJ matrix and must be destroyed by the user with MatDestroy().
6290 
6291    This routine is currently only implemented for SeqAIJ matrices and classes which inherit from SeqAIJ.
6292 
6293    Level: intermediate
6294 
6295 .seealso: MatMatMult(), MatMatMultNumeric()
6296 @*/
6297 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
6298 {
6299   PetscErrorCode ierr;
6300   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
6301   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
6302 
6303   PetscFunctionBegin;
6304   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6305   PetscValidType(A,1);
6306   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6307   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6308 
6309   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6310   PetscValidType(B,2);
6311   MatPreallocated(B);
6312   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6313   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6314   PetscValidPointer(C,3);
6315 
6316   if (B->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->N);
6317   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.0",fill);
6318   ierr = MatPreallocated(A);CHKERRQ(ierr);
6319 
6320   /* For now, we do not dispatch based on the type of A and P */
6321   /* When implementations like _SeqAIJ_MAIJ exist, attack the multiple dispatch problem. */
6322   Asymbolic = A->ops->matmultsymbolic;
6323   if (!Asymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for A of type %s",A->type_name);
6324   Bsymbolic = B->ops->matmultsymbolic;
6325   if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",B->type_name);
6326   if (Bsymbolic!=Asymbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6327 
6328   ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6329   ierr = (*Asymbolic)(A,B,fill,C);CHKERRQ(ierr);
6330   ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
6331 
6332   PetscFunctionReturn(0);
6333 }
6334 
6335 #undef __FUNCT__
6336 #define __FUNCT__ "MatMatMultNumeric"
6337 /*@
6338    MatMatMultNumeric - Performs the numeric matrix-matrix product.
6339    Call this routine after first calling MatMatMultSymbolic().
6340 
6341    Collective on Mat
6342 
6343    Input Parameters:
6344 +  A - the left matrix
6345 -  B - the right matrix
6346 
6347    Output Parameters:
6348 .  C - the product matrix, whose ij structure was defined from MatMatMultSymbolic().
6349 
6350    Notes:
6351    C must have been created with MatMatMultSymbolic.
6352 
6353    This routine is currently only implemented for SeqAIJ type matrices.
6354 
6355    Level: intermediate
6356 
6357 .seealso: MatMatMult(), MatMatMultSymbolic()
6358 @*/
6359 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultNumeric(Mat A,Mat B,Mat C)
6360 {
6361   PetscErrorCode ierr;
6362   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
6363   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
6364 
6365   PetscFunctionBegin;
6366 
6367   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6368   PetscValidType(A,1);
6369   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6370   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6371 
6372   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6373   PetscValidType(B,2);
6374   MatPreallocated(B);
6375   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6376   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6377 
6378   PetscValidHeaderSpecific(C,MAT_COOKIE,3);
6379   PetscValidType(C,3);
6380   MatPreallocated(C);
6381   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6382   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6383 
6384   if (B->N!=C->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->N,C->N);
6385   if (B->M!=A->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->N);
6386   if (A->M!=C->M) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->M,C->M);
6387   ierr = MatPreallocated(A);CHKERRQ(ierr);
6388 
6389   /* For now, we do not dispatch based on the type of A and B */
6390   /* When implementations like _SeqAIJ_MAIJ exist, attack the multiple dispatch problem. */
6391   Anumeric = A->ops->matmultnumeric;
6392   if (!Anumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for A of type %s",A->type_name);
6393   Bnumeric = B->ops->matmultnumeric;
6394   if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",B->type_name);
6395   if (Bnumeric!=Anumeric) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6396 
6397   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6398   ierr = (*Anumeric)(A,B,C);CHKERRQ(ierr);
6399   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
6400 
6401   PetscFunctionReturn(0);
6402 }
6403 
6404 #undef __FUNCT__
6405 #define __FUNCT__ "MatMatMultTranspose"
6406 /*@
6407    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.
6408 
6409    Collective on Mat
6410 
6411    Input Parameters:
6412 +  A - the left matrix
6413 .  B - the right matrix
6414 .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6415 -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B))
6416 
6417    Output Parameters:
6418 .  C - the product matrix
6419 
6420    Notes:
6421    C will be created and must be destroyed by the user with MatDestroy().
6422 
6423    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
6424    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.
6425 
6426    Level: intermediate
6427 
6428 .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
6429 @*/
6430 PetscErrorCode PETSCMAT_DLLEXPORT MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
6431 {
6432   PetscErrorCode ierr;
6433   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
6434   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
6435 
6436   PetscFunctionBegin;
6437   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
6438   PetscValidType(A,1);
6439   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6440   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6441   PetscValidHeaderSpecific(B,MAT_COOKIE,2);
6442   PetscValidType(B,2);
6443   MatPreallocated(B);
6444   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6445   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6446   PetscValidPointer(C,3);
6447   if (B->M!=A->M) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->M,A->M);
6448   if (fill <=0.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"fill=%g must be > 0.0",fill);
6449   ierr = MatPreallocated(A);CHKERRQ(ierr);
6450 
6451   fA = A->ops->matmulttranspose;
6452   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",A->type_name);
6453   fB = B->ops->matmulttranspose;
6454   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",B->type_name);
6455   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",A->type_name,B->type_name);
6456 
6457   ierr = PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6458   ierr = (*A->ops->matmulttranspose)(A,B,scall,fill,C);CHKERRQ(ierr);
6459   ierr = PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);CHKERRQ(ierr);
6460 
6461   PetscFunctionReturn(0);
6462 }
6463