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