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