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