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