xref: /petsc/src/mat/interface/matrix.c (revision fcca9d3d5c45103cafcd0f6bc9babe194d935ced)
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 "src/vec/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);
90   PetscValidType(mat);
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);
143   PetscValidIntPointer(ncols);
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);
227   PetscValidType(mat);
228   MatPreallocated(mat);
229   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mat->comm);
230   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE);
231   PetscCheckSameComm(mat,viewer);
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);
305   PetscValidType(mat);
306   MatPreallocated(mat);
307   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
308   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);}
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);
349   PetscValidType(mat);
350   MatPreallocated(mat);
351   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
352   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);}
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);
388   PetscValidType(mat);
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);
415   PetscValidType(A);
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);
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);
519   PetscValidType(mat);
520   MatPreallocated(mat);
521   PetscValidIntPointer(idxm);
522   PetscValidIntPointer(idxn);
523   PetscValidScalarPointer(v);
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);
624   PetscValidType(mat);
625   PetscValidIntPointer(idxm);
626   PetscValidIntPointer(idxn);
627   PetscValidScalarPointer(v);
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);
728   PetscValidType(mat);
729   PetscValidIntPointer(idxm);
730   PetscValidIntPointer(idxn);
731   PetscValidScalarPointer(v);
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);
793   PetscValidIntPointer(dims);
794   PetscValidIntPointer(starts);
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);
861   PetscValidType(mat);
862   MatPreallocated(mat);
863   PetscValidIntPointer(idxm);
864   PetscValidIntPointer(idxn);
865   PetscValidScalarPointer(v);
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);
925   PetscValidType(mat);
926   MatPreallocated(mat);
927   PetscValidIntPointer(idxm);
928   PetscValidIntPointer(idxn);
929   PetscValidScalarPointer(v);
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);
966   PetscValidType(x);
967   MatPreallocated(x);
968   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
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);
1009   PetscValidType(x);
1010   MatPreallocated(x);
1011   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
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);
1062   PetscValidType(mat);
1063   MatPreallocated(mat);
1064   PetscValidIntPointer(irow);
1065   PetscValidIntPointer(icol);
1066   PetscValidScalarPointer(y);
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);
1138   PetscValidType(mat);
1139   MatPreallocated(mat);
1140   PetscValidIntPointer(irow);
1141   PetscValidIntPointer(icol);
1142   PetscValidScalarPointer(y);
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);
1202   PetscValidType(mat);
1203   MatPreallocated(mat);
1204   PetscValidHeaderSpecific(x,VEC_COOKIE);
1205   PetscValidHeaderSpecific(y,VEC_COOKIE);
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);
1262   PetscValidType(mat);
1263   MatPreallocated(mat);
1264   PetscValidHeaderSpecific(x,VEC_COOKIE);
1265   PetscValidHeaderSpecific(y,VEC_COOKIE);
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);
1321   PetscValidType(mat);
1322   MatPreallocated(mat);
1323   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1324   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1325   PetscValidHeaderSpecific(v3,VEC_COOKIE);
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);
1373   PetscValidType(mat);
1374   MatPreallocated(mat);
1375   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1376   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1377   PetscValidHeaderSpecific(v3,VEC_COOKIE);
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);
1424   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1425   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1426   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1427   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1428   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1429   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1430   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1431 
1432   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1433   ierr = (*mat->ops->multconstrained)(mat,x,y); CHKERRQ(ierr);
1434   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1435   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1436 
1437   PetscFunctionReturn(0);
1438 }
1439 
1440 #undef __FUNCT__
1441 #define __FUNCT__ "MatMultTransposeConstrained"
1442 /*@
1443    MatMultTransposeConstrained - The inner multiplication routine for a
1444    constrained matrix P^T A^T P.
1445 
1446    Collective on Mat and Vec
1447 
1448    Input Parameters:
1449 +  mat - the matrix
1450 -  x   - the vector to be multilplied
1451 
1452    Output Parameters:
1453 .  y - the result
1454 
1455    Notes:
1456    The vectors x and y cannot be the same.  I.e., one cannot
1457    call MatMult(A,y,y).
1458 
1459    Level: beginner
1460 
1461 .keywords: matrix, multiply, matrix-vector product, constraint
1462 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1463 @*/
1464 int MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1465 {
1466   int ierr;
1467 
1468   PetscFunctionBegin;
1469   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1470   PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE);
1471   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1472   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1473   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1474   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1475   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1476 
1477   ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1478   ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr);
1479   ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr);
1480   ierr = PetscObjectIncreaseState((PetscObject)y); CHKERRQ(ierr);
1481 
1482   PetscFunctionReturn(0);
1483 }
1484 /* ------------------------------------------------------------*/
1485 #undef __FUNCT__
1486 #define __FUNCT__ "MatGetInfo"
1487 /*@C
1488    MatGetInfo - Returns information about matrix storage (number of
1489    nonzeros, memory, etc.).
1490 
1491    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1492    as the flag
1493 
1494    Input Parameters:
1495 .  mat - the matrix
1496 
1497    Output Parameters:
1498 +  flag - flag indicating the type of parameters to be returned
1499    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1500    MAT_GLOBAL_SUM - sum over all processors)
1501 -  info - matrix information context
1502 
1503    Notes:
1504    The MatInfo context contains a variety of matrix data, including
1505    number of nonzeros allocated and used, number of mallocs during
1506    matrix assembly, etc.  Additional information for factored matrices
1507    is provided (such as the fill ratio, number of mallocs during
1508    factorization, etc.).  Much of this info is printed to STDOUT
1509    when using the runtime options
1510 $       -log_info -mat_view_info
1511 
1512    Example for C/C++ Users:
1513    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1514    data within the MatInfo context.  For example,
1515 .vb
1516       MatInfo info;
1517       Mat     A;
1518       double  mal, nz_a, nz_u;
1519 
1520       MatGetInfo(A,MAT_LOCAL,&info);
1521       mal  = info.mallocs;
1522       nz_a = info.nz_allocated;
1523 .ve
1524 
1525    Example for Fortran Users:
1526    Fortran users should declare info as a double precision
1527    array of dimension MAT_INFO_SIZE, and then extract the parameters
1528    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1529    a complete list of parameter names.
1530 .vb
1531       double  precision info(MAT_INFO_SIZE)
1532       double  precision mal, nz_a
1533       Mat     A
1534       integer ierr
1535 
1536       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1537       mal = info(MAT_INFO_MALLOCS)
1538       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1539 .ve
1540 
1541     Level: intermediate
1542 
1543     Concepts: matrices^getting information on
1544 
1545 @*/
1546 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1547 {
1548   int ierr;
1549 
1550   PetscFunctionBegin;
1551   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1552   PetscValidType(mat);
1553   MatPreallocated(mat);
1554   PetscValidPointer(info);
1555   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1556   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1557   PetscFunctionReturn(0);
1558 }
1559 
1560 /* ----------------------------------------------------------*/
1561 #undef __FUNCT__
1562 #define __FUNCT__ "MatILUDTFactor"
1563 /*@C
1564    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1565 
1566    Collective on Mat
1567 
1568    Input Parameters:
1569 +  mat - the matrix
1570 .  info - information about the factorization to be done
1571 .  row - row permutation
1572 -  col - column permutation
1573 
1574    Output Parameters:
1575 .  fact - the factored matrix
1576 
1577    Level: developer
1578 
1579    Notes:
1580    Most users should employ the simplified KSP interface for linear solvers
1581    instead of working directly with matrix algebra routines such as this.
1582    See, e.g., KSPCreate().
1583 
1584    This is currently only supported for the SeqAIJ matrix format using code
1585    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1586    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1587    and thus can be distributed with PETSc.
1588 
1589     Concepts: matrices^ILUDT factorization
1590 
1591 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1592 @*/
1593 int MatILUDTFactor(Mat mat,MatFactorInfo *info,IS row,IS col,Mat *fact)
1594 {
1595   int ierr;
1596 
1597   PetscFunctionBegin;
1598   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1599   PetscValidType(mat);
1600   MatPreallocated(mat);
1601   PetscValidPointer(fact);
1602   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1603   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1604   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1605 
1606   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1607   ierr = (*mat->ops->iludtfactor)(mat,info,row,col,fact);CHKERRQ(ierr);
1608   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1609   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1610 
1611   PetscFunctionReturn(0);
1612 }
1613 
1614 #undef __FUNCT__
1615 #define __FUNCT__ "MatLUFactor"
1616 /*@
1617    MatLUFactor - Performs in-place LU factorization of matrix.
1618 
1619    Collective on Mat
1620 
1621    Input Parameters:
1622 +  mat - the matrix
1623 .  row - row permutation
1624 .  col - column permutation
1625 -  info - options for factorization, includes
1626 $          fill - expected fill as ratio of original fill.
1627 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1628 $                   Run with the option -log_info to determine an optimal value to use
1629 
1630    Notes:
1631    Most users should employ the simplified KSP interface for linear solvers
1632    instead of working directly with matrix algebra routines such as this.
1633    See, e.g., KSPCreate().
1634 
1635    This changes the state of the matrix to a factored matrix; it cannot be used
1636    for example with MatSetValues() unless one first calls MatSetUnfactored().
1637 
1638    Level: developer
1639 
1640    Concepts: matrices^LU factorization
1641 
1642 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1643           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo
1644 
1645 @*/
1646 int MatLUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1647 {
1648   int ierr;
1649 
1650   PetscFunctionBegin;
1651   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1652   PetscValidType(mat);
1653   MatPreallocated(mat);
1654   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1655   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1656   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1657 
1658   ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1659   ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr);
1660   ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr);
1661   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1662   PetscFunctionReturn(0);
1663 }
1664 
1665 #undef __FUNCT__
1666 #define __FUNCT__ "MatILUFactor"
1667 /*@
1668    MatILUFactor - Performs in-place ILU factorization of matrix.
1669 
1670    Collective on Mat
1671 
1672    Input Parameters:
1673 +  mat - the matrix
1674 .  row - row permutation
1675 .  col - column permutation
1676 -  info - structure containing
1677 $      levels - number of levels of fill.
1678 $      expected fill - as ratio of original fill.
1679 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1680                 missing diagonal entries)
1681 
1682    Notes:
1683    Probably really in-place only when level of fill is zero, otherwise allocates
1684    new space to store factored matrix and deletes previous memory.
1685 
1686    Most users should employ the simplified KSP interface for linear solvers
1687    instead of working directly with matrix algebra routines such as this.
1688    See, e.g., KSPCreate().
1689 
1690    Level: developer
1691 
1692    Concepts: matrices^ILU factorization
1693 
1694 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1695 @*/
1696 int MatILUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1697 {
1698   int ierr;
1699 
1700   PetscFunctionBegin;
1701   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1702   PetscValidType(mat);
1703   MatPreallocated(mat);
1704   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1705   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1706   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1707   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1708 
1709   ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1710   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
1711   ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr);
1712   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1713   PetscFunctionReturn(0);
1714 }
1715 
1716 #undef __FUNCT__
1717 #define __FUNCT__ "MatLUFactorSymbolic"
1718 /*@
1719    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1720    Call this routine before calling MatLUFactorNumeric().
1721 
1722    Collective on Mat
1723 
1724    Input Parameters:
1725 +  mat - the matrix
1726 .  row, col - row and column permutations
1727 -  info - options for factorization, includes
1728 $          fill - expected fill as ratio of original fill.
1729 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1730 $                   Run with the option -log_info to determine an optimal value to use
1731 
1732    Output Parameter:
1733 .  fact - new matrix that has been symbolically factored
1734 
1735    Notes:
1736    See the users manual for additional information about
1737    choosing the fill factor for better efficiency.
1738 
1739    Most users should employ the simplified KSP interface for linear solvers
1740    instead of working directly with matrix algebra routines such as this.
1741    See, e.g., KSPCreate().
1742 
1743    Level: developer
1744 
1745    Concepts: matrices^LU symbolic factorization
1746 
1747 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1748 @*/
1749 int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
1750 {
1751   int ierr;
1752 
1753   PetscFunctionBegin;
1754   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1755   PetscValidType(mat);
1756   MatPreallocated(mat);
1757   PetscValidPointer(fact);
1758   PetscValidHeaderSpecific(row,IS_COOKIE);
1759   PetscValidHeaderSpecific(col,IS_COOKIE);
1760   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1761   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1762   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);
1763 
1764   ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1765   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
1766   ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
1767   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1768   PetscFunctionReturn(0);
1769 }
1770 
1771 #undef __FUNCT__
1772 #define __FUNCT__ "MatLUFactorNumeric"
1773 /*@
1774    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1775    Call this routine after first calling MatLUFactorSymbolic().
1776 
1777    Collective on Mat
1778 
1779    Input Parameters:
1780 +  mat - the matrix
1781 -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()
1782 
1783    Notes:
1784    See MatLUFactor() for in-place factorization.  See
1785    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1786 
1787    Most users should employ the simplified KSP interface for linear solvers
1788    instead of working directly with matrix algebra routines such as this.
1789    See, e.g., KSPCreate().
1790 
1791    Level: developer
1792 
1793    Concepts: matrices^LU numeric factorization
1794 
1795 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1796 @*/
1797 int MatLUFactorNumeric(Mat mat,Mat *fact)
1798 {
1799   int        ierr;
1800 
1801   PetscFunctionBegin;
1802   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1803   PetscValidType(mat);
1804   MatPreallocated(mat);
1805   PetscValidPointer(fact);
1806   PetscValidHeaderSpecific(*fact,MAT_COOKIE);
1807   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1808   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1809     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1810             mat->M,(*fact)->M,mat->N,(*fact)->N);
1811   }
1812   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1813 
1814   ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1815   ierr = (*(*fact)->ops->lufactornumeric)(mat,fact);CHKERRQ(ierr);
1816   ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1817 
1818   ierr = MatView_Private(*fact);CHKERRQ(ierr);
1819   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1820   PetscFunctionReturn(0);
1821 }
1822 
1823 #undef __FUNCT__
1824 #define __FUNCT__ "MatCholeskyFactor"
1825 /*@
1826    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1827    symmetric matrix.
1828 
1829    Collective on Mat
1830 
1831    Input Parameters:
1832 +  mat - the matrix
1833 .  perm - row and column permutations
1834 -  f - expected fill as ratio of original fill
1835 
1836    Notes:
1837    See MatLUFactor() for the nonsymmetric case.  See also
1838    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
1839 
1840    Most users should employ the simplified KSP interface for linear solvers
1841    instead of working directly with matrix algebra routines such as this.
1842    See, e.g., KSPCreate().
1843 
1844    Level: developer
1845 
1846    Concepts: matrices^Cholesky factorization
1847 
1848 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1849           MatGetOrdering()
1850 
1851 @*/
1852 int MatCholeskyFactor(Mat mat,IS perm,MatFactorInfo *info)
1853 {
1854   int ierr;
1855 
1856   PetscFunctionBegin;
1857   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1858   PetscValidType(mat);
1859   MatPreallocated(mat);
1860   PetscValidHeaderSpecific(perm,IS_COOKIE);
1861   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1862   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1863   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1864   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1865 
1866   ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1867   ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr);
1868   ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr);
1869   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
1870   PetscFunctionReturn(0);
1871 }
1872 
1873 #undef __FUNCT__
1874 #define __FUNCT__ "MatCholeskyFactorSymbolic"
1875 /*@
1876    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1877    of a symmetric matrix.
1878 
1879    Collective on Mat
1880 
1881    Input Parameters:
1882 +  mat - the matrix
1883 .  perm - row and column permutations
1884 -  info - options for factorization, includes
1885 $          fill - expected fill as ratio of original fill.
1886 $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1887 $                   Run with the option -log_info to determine an optimal value to use
1888 
1889    Output Parameter:
1890 .  fact - the factored matrix
1891 
1892    Notes:
1893    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1894    MatCholeskyFactor() and MatCholeskyFactorNumeric().
1895 
1896    Most users should employ the simplified KSP interface for linear solvers
1897    instead of working directly with matrix algebra routines such as this.
1898    See, e.g., KSPCreate().
1899 
1900    Level: developer
1901 
1902    Concepts: matrices^Cholesky symbolic factorization
1903 
1904 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1905           MatGetOrdering()
1906 
1907 @*/
1908 int MatCholeskyFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
1909 {
1910   int ierr;
1911 
1912   PetscFunctionBegin;
1913   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1914   PetscValidType(mat);
1915   MatPreallocated(mat);
1916   PetscValidPointer(fact);
1917   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1918   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1919   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1920   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1921 
1922   ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1923   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
1924   ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
1925   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1926   PetscFunctionReturn(0);
1927 }
1928 
1929 #undef __FUNCT__
1930 #define __FUNCT__ "MatCholeskyFactorNumeric"
1931 /*@
1932    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1933    of a symmetric matrix. Call this routine after first calling
1934    MatCholeskyFactorSymbolic().
1935 
1936    Collective on Mat
1937 
1938    Input Parameter:
1939 .  mat - the initial matrix
1940 
1941    Output Parameter:
1942 .  fact - the factored matrix
1943 
1944    Notes:
1945    Most users should employ the simplified KSP interface for linear solvers
1946    instead of working directly with matrix algebra routines such as this.
1947    See, e.g., KSPCreate().
1948 
1949    Level: developer
1950 
1951    Concepts: matrices^Cholesky numeric factorization
1952 
1953 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1954 @*/
1955 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1956 {
1957   int ierr;
1958 
1959   PetscFunctionBegin;
1960   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1961   PetscValidType(mat);
1962   MatPreallocated(mat);
1963   PetscValidPointer(fact);
1964   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1965   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1966   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1967     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1968             mat->M,(*fact)->M,mat->N,(*fact)->N);
1969   }
1970 
1971   ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1972   ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,fact);CHKERRQ(ierr);
1973   ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr);
1974   ierr = PetscObjectIncreaseState((PetscObject)*fact); CHKERRQ(ierr);
1975   PetscFunctionReturn(0);
1976 }
1977 
1978 /* ----------------------------------------------------------------*/
1979 #undef __FUNCT__
1980 #define __FUNCT__ "MatSolve"
1981 /*@
1982    MatSolve - Solves A x = b, given a factored matrix.
1983 
1984    Collective on Mat and Vec
1985 
1986    Input Parameters:
1987 +  mat - the factored matrix
1988 -  b - the right-hand-side vector
1989 
1990    Output Parameter:
1991 .  x - the result vector
1992 
1993    Notes:
1994    The vectors b and x cannot be the same.  I.e., one cannot
1995    call MatSolve(A,x,x).
1996 
1997    Notes:
1998    Most users should employ the simplified KSP interface for linear solvers
1999    instead of working directly with matrix algebra routines such as this.
2000    See, e.g., KSPCreate().
2001 
2002    Level: developer
2003 
2004    Concepts: matrices^triangular solves
2005 
2006 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2007 @*/
2008 int MatSolve(Mat mat,Vec b,Vec x)
2009 {
2010   int ierr;
2011 
2012   PetscFunctionBegin;
2013   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2014   PetscValidType(mat);
2015   MatPreallocated(mat);
2016   PetscValidHeaderSpecific(b,VEC_COOKIE);
2017   PetscValidHeaderSpecific(x,VEC_COOKIE);
2018   PetscCheckSameComm(mat,b);
2019   PetscCheckSameComm(mat,x);
2020   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2021   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2022   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2023   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2024   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2025   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
2026 
2027   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2028   ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2029   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
2030   ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr);
2031   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2032   PetscFunctionReturn(0);
2033 }
2034 
2035 #undef __FUNCT__
2036 #define __FUNCT__ "MatForwardSolve"
2037 /* @
2038    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
2039 
2040    Collective on Mat and Vec
2041 
2042    Input Parameters:
2043 +  mat - the factored matrix
2044 -  b - the right-hand-side vector
2045 
2046    Output Parameter:
2047 .  x - the result vector
2048 
2049    Notes:
2050    MatSolve() should be used for most applications, as it performs
2051    a forward solve followed by a backward solve.
2052 
2053    The vectors b and x cannot be the same.  I.e., one cannot
2054    call MatForwardSolve(A,x,x).
2055 
2056    Most users should employ the simplified KSP interface for linear solvers
2057    instead of working directly with matrix algebra routines such as this.
2058    See, e.g., KSPCreate().
2059 
2060    Level: developer
2061 
2062    Concepts: matrices^forward solves
2063 
2064 .seealso: MatSolve(), MatBackwardSolve()
2065 @ */
2066 int MatForwardSolve(Mat mat,Vec b,Vec x)
2067 {
2068   int ierr;
2069 
2070   PetscFunctionBegin;
2071   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2072   PetscValidType(mat);
2073   MatPreallocated(mat);
2074   PetscValidHeaderSpecific(b,VEC_COOKIE);
2075   PetscValidHeaderSpecific(x,VEC_COOKIE);
2076   PetscCheckSameComm(mat,b);
2077   PetscCheckSameComm(mat,x);
2078   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2079   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2080   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2081   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2082   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2083   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2084 
2085   ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2086   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
2087   ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr);
2088   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2089   PetscFunctionReturn(0);
2090 }
2091 
2092 #undef __FUNCT__
2093 #define __FUNCT__ "MatBackwardSolve"
2094 /* @
2095    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
2096 
2097    Collective on Mat and Vec
2098 
2099    Input Parameters:
2100 +  mat - the factored matrix
2101 -  b - the right-hand-side vector
2102 
2103    Output Parameter:
2104 .  x - the result vector
2105 
2106    Notes:
2107    MatSolve() should be used for most applications, as it performs
2108    a forward solve followed by a backward solve.
2109 
2110    The vectors b and x cannot be the same.  I.e., one cannot
2111    call MatBackwardSolve(A,x,x).
2112 
2113    Most users should employ the simplified KSP interface for linear solvers
2114    instead of working directly with matrix algebra routines such as this.
2115    See, e.g., KSPCreate().
2116 
2117    Level: developer
2118 
2119    Concepts: matrices^backward solves
2120 
2121 .seealso: MatSolve(), MatForwardSolve()
2122 @ */
2123 int MatBackwardSolve(Mat mat,Vec b,Vec x)
2124 {
2125   int ierr;
2126 
2127   PetscFunctionBegin;
2128   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2129   PetscValidType(mat);
2130   MatPreallocated(mat);
2131   PetscValidHeaderSpecific(b,VEC_COOKIE);
2132   PetscValidHeaderSpecific(x,VEC_COOKIE);
2133   PetscCheckSameComm(mat,b);
2134   PetscCheckSameComm(mat,x);
2135   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2136   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2137   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2138   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2139   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2140   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2141 
2142   ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2143   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
2144   ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr);
2145   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2146   PetscFunctionReturn(0);
2147 }
2148 
2149 #undef __FUNCT__
2150 #define __FUNCT__ "MatSolveAdd"
2151 /*@
2152    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
2153 
2154    Collective on Mat and Vec
2155 
2156    Input Parameters:
2157 +  mat - the factored matrix
2158 .  b - the right-hand-side vector
2159 -  y - the vector to be added to
2160 
2161    Output Parameter:
2162 .  x - the result vector
2163 
2164    Notes:
2165    The vectors b and x cannot be the same.  I.e., one cannot
2166    call MatSolveAdd(A,x,y,x).
2167 
2168    Most users should employ the simplified KSP interface for linear solvers
2169    instead of working directly with matrix algebra routines such as this.
2170    See, e.g., KSPCreate().
2171 
2172    Level: developer
2173 
2174    Concepts: matrices^triangular solves
2175 
2176 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2177 @*/
2178 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2179 {
2180   PetscScalar one = 1.0;
2181   Vec    tmp;
2182   int    ierr;
2183 
2184   PetscFunctionBegin;
2185   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2186   PetscValidType(mat);
2187   MatPreallocated(mat);
2188   PetscValidHeaderSpecific(y,VEC_COOKIE);
2189   PetscValidHeaderSpecific(b,VEC_COOKIE);
2190   PetscValidHeaderSpecific(x,VEC_COOKIE);
2191   PetscCheckSameComm(mat,b);
2192   PetscCheckSameComm(mat,y);
2193   PetscCheckSameComm(mat,x);
2194   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2195   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2196   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2197   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2198   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
2199   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2200   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2201 
2202   ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2203   if (mat->ops->solveadd)  {
2204     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
2205   } else {
2206     /* do the solve then the add manually */
2207     if (x != y) {
2208       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2209       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2210     } else {
2211       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2212       PetscLogObjectParent(mat,tmp);
2213       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2214       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
2215       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2216       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2217     }
2218   }
2219   ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr);
2220   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2221   PetscFunctionReturn(0);
2222 }
2223 
2224 #undef __FUNCT__
2225 #define __FUNCT__ "MatSolveTranspose"
2226 /*@
2227    MatSolveTranspose - Solves A' x = b, given a factored matrix.
2228 
2229    Collective on Mat and Vec
2230 
2231    Input Parameters:
2232 +  mat - the factored matrix
2233 -  b - the right-hand-side vector
2234 
2235    Output Parameter:
2236 .  x - the result vector
2237 
2238    Notes:
2239    The vectors b and x cannot be the same.  I.e., one cannot
2240    call MatSolveTranspose(A,x,x).
2241 
2242    Most users should employ the simplified KSP interface for linear solvers
2243    instead of working directly with matrix algebra routines such as this.
2244    See, e.g., KSPCreate().
2245 
2246    Level: developer
2247 
2248    Concepts: matrices^triangular solves
2249 
2250 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2251 @*/
2252 int MatSolveTranspose(Mat mat,Vec b,Vec x)
2253 {
2254   int ierr;
2255 
2256   PetscFunctionBegin;
2257   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2258   PetscValidType(mat);
2259   MatPreallocated(mat);
2260   PetscValidHeaderSpecific(b,VEC_COOKIE);
2261   PetscValidHeaderSpecific(x,VEC_COOKIE);
2262   PetscCheckSameComm(mat,b);
2263   PetscCheckSameComm(mat,x);
2264   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2265   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2266   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2267   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2268   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2269 
2270   ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2271   ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr);
2272   ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr);
2273   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2274   PetscFunctionReturn(0);
2275 }
2276 
2277 #undef __FUNCT__
2278 #define __FUNCT__ "MatSolveTransposeAdd"
2279 /*@
2280    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
2281                       factored matrix.
2282 
2283    Collective on Mat and Vec
2284 
2285    Input Parameters:
2286 +  mat - the factored matrix
2287 .  b - the right-hand-side vector
2288 -  y - the vector to be added to
2289 
2290    Output Parameter:
2291 .  x - the result vector
2292 
2293    Notes:
2294    The vectors b and x cannot be the same.  I.e., one cannot
2295    call MatSolveTransposeAdd(A,x,y,x).
2296 
2297    Most users should employ the simplified KSP interface for linear solvers
2298    instead of working directly with matrix algebra routines such as this.
2299    See, e.g., KSPCreate().
2300 
2301    Level: developer
2302 
2303    Concepts: matrices^triangular solves
2304 
2305 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2306 @*/
2307 int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2308 {
2309   PetscScalar one = 1.0;
2310   int         ierr;
2311   Vec         tmp;
2312 
2313   PetscFunctionBegin;
2314   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2315   PetscValidType(mat);
2316   MatPreallocated(mat);
2317   PetscValidHeaderSpecific(y,VEC_COOKIE);
2318   PetscValidHeaderSpecific(b,VEC_COOKIE);
2319   PetscValidHeaderSpecific(x,VEC_COOKIE);
2320   PetscCheckSameComm(mat,b);
2321   PetscCheckSameComm(mat,y);
2322   PetscCheckSameComm(mat,x);
2323   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2324   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2325   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2326   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2327   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
2328   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);
2329 
2330   ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2331   if (mat->ops->solvetransposeadd) {
2332     ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr);
2333   } else {
2334     /* do the solve then the add manually */
2335     if (x != y) {
2336       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2337       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
2338     } else {
2339       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
2340       PetscLogObjectParent(mat,tmp);
2341       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
2342       ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr);
2343       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
2344       ierr = VecDestroy(tmp);CHKERRQ(ierr);
2345     }
2346   }
2347   ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr);
2348   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2349   PetscFunctionReturn(0);
2350 }
2351 /* ----------------------------------------------------------------*/
2352 
2353 #undef __FUNCT__
2354 #define __FUNCT__ "MatRelax"
2355 /*@
2356    MatRelax - Computes one relaxation sweep.
2357 
2358    Collective on Mat and Vec
2359 
2360    Input Parameters:
2361 +  mat - the matrix
2362 .  b - the right hand side
2363 .  omega - the relaxation factor
2364 .  flag - flag indicating the type of SOR (see below)
2365 .  shift -  diagonal shift
2366 -  its - the number of iterations
2367 -  lits - the number of local iterations
2368 
2369    Output Parameters:
2370 .  x - the solution (can contain an initial guess)
2371 
2372    SOR Flags:
2373 .     SOR_FORWARD_SWEEP - forward SOR
2374 .     SOR_BACKWARD_SWEEP - backward SOR
2375 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2376 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
2377 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
2378 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2379 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
2380          upper/lower triangular part of matrix to
2381          vector (with omega)
2382 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
2383 
2384    Notes:
2385    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2386    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
2387    on each processor.
2388 
2389    Application programmers will not generally use MatRelax() directly,
2390    but instead will employ the KSP/PC interface.
2391 
2392    Notes for Advanced Users:
2393    The flags are implemented as bitwise inclusive or operations.
2394    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2395    to specify a zero initial guess for SSOR.
2396 
2397    Most users should employ the simplified KSP interface for linear solvers
2398    instead of working directly with matrix algebra routines such as this.
2399    See, e.g., KSPCreate().
2400 
2401    Level: developer
2402 
2403    Concepts: matrices^relaxation
2404    Concepts: matrices^SOR
2405    Concepts: matrices^Gauss-Seidel
2406 
2407 @*/
2408 int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2409 {
2410   int ierr;
2411 
2412   PetscFunctionBegin;
2413   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2414   PetscValidType(mat);
2415   MatPreallocated(mat);
2416   PetscValidHeaderSpecific(b,VEC_COOKIE);
2417   PetscValidHeaderSpecific(x,VEC_COOKIE);
2418   PetscCheckSameComm(mat,b);
2419   PetscCheckSameComm(mat,x);
2420   if (!mat->ops->relax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2421   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2422   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2423   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2424   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2425   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2426 
2427   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2428   ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2429   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2430   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2431   PetscFunctionReturn(0);
2432 }
2433 
2434 #undef __FUNCT__
2435 #define __FUNCT__ "MatCopy_Basic"
2436 /*
2437       Default matrix copy routine.
2438 */
2439 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2440 {
2441   int         ierr,i,rstart,rend,nz,*cwork;
2442   PetscScalar *vwork;
2443 
2444   PetscFunctionBegin;
2445   ierr = MatZeroEntries(B);CHKERRQ(ierr);
2446   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2447   for (i=rstart; i<rend; i++) {
2448     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2449     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2450     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2451   }
2452   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2453   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2454   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2455   PetscFunctionReturn(0);
2456 }
2457 
2458 #undef __FUNCT__
2459 #define __FUNCT__ "MatCopy"
2460 /*@C
2461    MatCopy - Copys a matrix to another matrix.
2462 
2463    Collective on Mat
2464 
2465    Input Parameters:
2466 +  A - the matrix
2467 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2468 
2469    Output Parameter:
2470 .  B - where the copy is put
2471 
2472    Notes:
2473    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
2474    same nonzero pattern or the routine will crash.
2475 
2476    MatCopy() copies the matrix entries of a matrix to another existing
2477    matrix (after first zeroing the second matrix).  A related routine is
2478    MatConvert(), which first creates a new matrix and then copies the data.
2479 
2480    Level: intermediate
2481 
2482    Concepts: matrices^copying
2483 
2484 .seealso: MatConvert(), MatDuplicate()
2485 
2486 @*/
2487 int MatCopy(Mat A,Mat B,MatStructure str)
2488 {
2489   int ierr;
2490 
2491   PetscFunctionBegin;
2492   PetscValidHeaderSpecific(A,MAT_COOKIE);
2493   PetscValidHeaderSpecific(B,MAT_COOKIE);
2494   PetscValidType(A);
2495   MatPreallocated(A);
2496   PetscValidType(B);
2497   MatPreallocated(B);
2498   PetscCheckSameComm(A,B);
2499   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2500   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501   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,
2502                                              A->N,B->N);
2503 
2504   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2505   if (A->ops->copy) {
2506     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2507   } else { /* generic conversion */
2508     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2509   }
2510   if (A->mapping) {
2511     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
2512     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
2513   }
2514   if (A->bmapping) {
2515     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
2516     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
2517   }
2518   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2519   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2520   PetscFunctionReturn(0);
2521 }
2522 
2523 #include "petscsys.h"
2524 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2525 PetscFList MatConvertList              = 0;
2526 
2527 #undef __FUNCT__
2528 #define __FUNCT__ "MatConvertRegister"
2529 /*@C
2530     MatConvertRegister - Allows one to register a routine that converts a sparse matrix
2531         from one format to another.
2532 
2533   Not Collective
2534 
2535   Input Parameters:
2536 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2537 -   Converter - the function that reads the matrix from the binary file.
2538 
2539   Level: developer
2540 
2541 .seealso: MatConvertRegisterAll(), MatConvert()
2542 
2543 @*/
2544 int MatConvertRegister(const char sname[],const char path[],const char name[],int (*function)(Mat,MatType,Mat*))
2545 {
2546   int  ierr;
2547   char fullname[PETSC_MAX_PATH_LEN];
2548 
2549   PetscFunctionBegin;
2550   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2551   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2552   PetscFunctionReturn(0);
2553 }
2554 
2555 #undef __FUNCT__
2556 #define __FUNCT__ "MatConvert"
2557 /*@C
2558    MatConvert - Converts a matrix to another matrix, either of the same
2559    or different type.
2560 
2561    Collective on Mat
2562 
2563    Input Parameters:
2564 +  mat - the matrix
2565 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2566    same type as the original matrix.
2567 
2568    Output Parameter:
2569 .  M - pointer to place new matrix
2570 
2571    Notes:
2572    MatConvert() first creates a new matrix and then copies the data from
2573    the first matrix.  A related routine is MatCopy(), which copies the matrix
2574    entries of one matrix to another already existing matrix context.
2575 
2576    Level: intermediate
2577 
2578    Concepts: matrices^converting between storage formats
2579 
2580 .seealso: MatCopy(), MatDuplicate()
2581 @*/
2582 int MatConvert(Mat mat,const MatType newtype,Mat *M)
2583 {
2584   int        ierr;
2585   PetscTruth sametype,issame,flg;
2586   char       convname[256],mtype[256];
2587 
2588   PetscFunctionBegin;
2589   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2590   PetscValidType(mat);
2591   MatPreallocated(mat);
2592   PetscValidPointer(M);
2593   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2594   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2595 
2596   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
2597   if (flg) {
2598     newtype = mtype;
2599   }
2600   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2601 
2602   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
2603   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
2604   if ((sametype || issame) && mat->ops->duplicate) {
2605     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
2606   } else {
2607     int (*conv)(Mat,const MatType,Mat*)=PETSC_NULL;
2608     /*
2609        Order of precedence:
2610        1) See if a specialized converter is known to the current matrix.
2611        2) See if a specialized converter is known to the desired matrix class.
2612        3) See if a good general converter is registered for the desired class
2613           (as of 6/27/03 only MATMPIADJ falls into this category).
2614        4) See if a good general converter is known for the current matrix.
2615        5) Use a really basic converter.
2616     */
2617     ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
2618     ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
2619     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
2620     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
2621     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
2622     ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2623     if (!conv) {
2624       Mat B;
2625       ierr = MatCreate(mat->comm,0,0,0,0,&B);CHKERRQ(ierr);
2626       ierr = MatSetType(B,newtype);CHKERRQ(ierr);
2627       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2628       ierr = MatDestroy(B);CHKERRQ(ierr);
2629       if (!conv) {
2630         if (!MatConvertRegisterAllCalled) {
2631           ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2632         }
2633         ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr);
2634         if (!conv) {
2635           if (mat->ops->convert) {
2636             conv = mat->ops->convert;
2637           } else {
2638             conv = MatConvert_Basic;
2639           }
2640         }
2641       }
2642     }
2643     ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2644   }
2645   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2646   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2647   PetscFunctionReturn(0);
2648 }
2649 
2650 
2651 #undef __FUNCT__
2652 #define __FUNCT__ "MatDuplicate"
2653 /*@C
2654    MatDuplicate - Duplicates a matrix including the non-zero structure.
2655 
2656    Collective on Mat
2657 
2658    Input Parameters:
2659 +  mat - the matrix
2660 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2661         values as well or not
2662 
2663    Output Parameter:
2664 .  M - pointer to place new matrix
2665 
2666    Level: intermediate
2667 
2668    Concepts: matrices^duplicating
2669 
2670 .seealso: MatCopy(), MatConvert()
2671 @*/
2672 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2673 {
2674   int ierr;
2675 
2676   PetscFunctionBegin;
2677   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2678   PetscValidType(mat);
2679   MatPreallocated(mat);
2680   PetscValidPointer(M);
2681   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2682   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2683 
2684   *M  = 0;
2685   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2686   if (!mat->ops->duplicate) {
2687     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2688   }
2689   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
2690   if (mat->mapping) {
2691     ierr = MatSetLocalToGlobalMapping(*M,mat->mapping);CHKERRQ(ierr);
2692   }
2693   if (mat->bmapping) {
2694     ierr = MatSetLocalToGlobalMappingBlock(*M,mat->mapping);CHKERRQ(ierr);
2695   }
2696   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2697   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2698   PetscFunctionReturn(0);
2699 }
2700 
2701 #undef __FUNCT__
2702 #define __FUNCT__ "MatGetDiagonal"
2703 /*@
2704    MatGetDiagonal - Gets the diagonal of a matrix.
2705 
2706    Collective on Mat and Vec
2707 
2708    Input Parameters:
2709 +  mat - the matrix
2710 -  v - the vector for storing the diagonal
2711 
2712    Output Parameter:
2713 .  v - the diagonal of the matrix
2714 
2715    Notes:
2716    For the SeqAIJ matrix format, this routine may also be called
2717    on a LU factored matrix; in that case it routines the reciprocal of
2718    the diagonal entries in U. It returns the entries permuted by the
2719    row and column permutation used during the symbolic factorization.
2720 
2721    Level: intermediate
2722 
2723    Concepts: matrices^accessing diagonals
2724 
2725 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2726 @*/
2727 int MatGetDiagonal(Mat mat,Vec v)
2728 {
2729   int ierr;
2730 
2731   PetscFunctionBegin;
2732   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2733   PetscValidType(mat);
2734   MatPreallocated(mat);
2735   PetscValidHeaderSpecific(v,VEC_COOKIE);
2736   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2737   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2738   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2739 
2740   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
2741   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2742   PetscFunctionReturn(0);
2743 }
2744 
2745 #undef __FUNCT__
2746 #define __FUNCT__ "MatGetRowMax"
2747 /*@
2748    MatGetRowMax - Gets the maximum value (in absolute value) of each
2749         row of the matrix
2750 
2751    Collective on Mat and Vec
2752 
2753    Input Parameters:
2754 .  mat - the matrix
2755 
2756    Output Parameter:
2757 .  v - the vector for storing the maximums
2758 
2759    Level: intermediate
2760 
2761    Concepts: matrices^getting row maximums
2762 
2763 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2764 @*/
2765 int MatGetRowMax(Mat mat,Vec v)
2766 {
2767   int ierr;
2768 
2769   PetscFunctionBegin;
2770   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2771   PetscValidType(mat);
2772   MatPreallocated(mat);
2773   PetscValidHeaderSpecific(v,VEC_COOKIE);
2774   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2775   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2776   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2777 
2778   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
2779   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2780   PetscFunctionReturn(0);
2781 }
2782 
2783 #undef __FUNCT__
2784 #define __FUNCT__ "MatTranspose"
2785 /*@C
2786    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2787 
2788    Collective on Mat
2789 
2790    Input Parameter:
2791 .  mat - the matrix to transpose
2792 
2793    Output Parameters:
2794 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2795 
2796    Level: intermediate
2797 
2798    Concepts: matrices^transposing
2799 
2800 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
2801 @*/
2802 int MatTranspose(Mat mat,Mat *B)
2803 {
2804   int ierr;
2805 
2806   PetscFunctionBegin;
2807   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2808   PetscValidType(mat);
2809   MatPreallocated(mat);
2810   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2811   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2812   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2813 
2814   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2815   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2816   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2817   if (B) {ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);}
2818   PetscFunctionReturn(0);
2819 }
2820 
2821 #undef __FUNCT__
2822 #define __FUNCT__ "MatIsTranspose"
2823 /*@C
2824    MatIsTranspose - Test whether a matrix is another one's transpose,
2825         or its own, in which case it tests symmetry.
2826 
2827    Collective on Mat
2828 
2829    Input Parameter:
2830 +  A - the matrix to test
2831 -  B - the matrix to test against, this can equal the first parameter
2832 
2833    Output Parameters:
2834 .  flg - the result
2835 
2836    Notes:
2837    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
2838    has a running time of the order of the number of nonzeros; the parallel
2839    test involves parallel copies of the block-offdiagonal parts of the matrix.
2840 
2841    Level: intermediate
2842 
2843    Concepts: matrices^transposing, matrix^symmetry
2844 
2845 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
2846 @*/
2847 int MatIsTranspose(Mat A,Mat B,PetscTruth *flg)
2848 {
2849   int ierr,(*f)(Mat,Mat,PetscTruth*),(*g)(Mat,Mat,PetscTruth*);
2850 
2851   PetscFunctionBegin;
2852   PetscValidHeaderSpecific(A,MAT_COOKIE);
2853   PetscValidHeaderSpecific(B,MAT_COOKIE);
2854   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
2855   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
2856   if (f && g) {
2857     if (f==g) {
2858       ierr = (*f)(A,B,flg);CHKERRQ(ierr);
2859     } else {
2860       SETERRQ(1,"Matrices do not have the same comparator for symmetry test");
2861     }
2862   }
2863   PetscFunctionReturn(0);
2864 }
2865 
2866 #undef __FUNCT__
2867 #define __FUNCT__ "MatPermute"
2868 /*@C
2869    MatPermute - Creates a new matrix with rows and columns permuted from the
2870    original.
2871 
2872    Collective on Mat
2873 
2874    Input Parameters:
2875 +  mat - the matrix to permute
2876 .  row - row permutation, each processor supplies only the permutation for its rows
2877 -  col - column permutation, each processor needs the entire column permutation, that is
2878          this is the same size as the total number of columns in the matrix
2879 
2880    Output Parameters:
2881 .  B - the permuted matrix
2882 
2883    Level: advanced
2884 
2885    Concepts: matrices^permuting
2886 
2887 .seealso: MatGetOrdering()
2888 @*/
2889 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2890 {
2891   int ierr;
2892 
2893   PetscFunctionBegin;
2894   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2895   PetscValidType(mat);
2896   MatPreallocated(mat);
2897   PetscValidHeaderSpecific(row,IS_COOKIE);
2898   PetscValidHeaderSpecific(col,IS_COOKIE);
2899   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2900   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2901   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2902   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2903   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
2904   PetscFunctionReturn(0);
2905 }
2906 
2907 #undef __FUNCT__
2908 #define __FUNCT__ "MatPermuteSparsify"
2909 /*@C
2910   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
2911   original and sparsified to the prescribed tolerance.
2912 
2913   Collective on Mat
2914 
2915   Input Parameters:
2916 + A    - The matrix to permute
2917 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2918 . frac - The half-bandwidth as a fraction of the total size, or 0.0
2919 . tol  - The drop tolerance
2920 . rowp - The row permutation
2921 - colp - The column permutation
2922 
2923   Output Parameter:
2924 . B    - The permuted, sparsified matrix
2925 
2926   Level: advanced
2927 
2928   Note:
2929   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2930   restrict the half-bandwidth of the resulting matrix to 5% of the
2931   total matrix size.
2932 
2933 .keywords: matrix, permute, sparsify
2934 
2935 .seealso: MatGetOrdering(), MatPermute()
2936 @*/
2937 int MatPermuteSparsify(Mat A, int band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
2938 {
2939   IS           irowp, icolp;
2940   int         *rows, *cols;
2941   int          M, N, locRowStart, locRowEnd;
2942   int          nz, newNz;
2943   int         *cwork, *cnew;
2944   PetscScalar *vwork, *vnew;
2945   int          bw, size;
2946   int          row, locRow, newRow, col, newCol;
2947   int          ierr;
2948 
2949   PetscFunctionBegin;
2950   PetscValidHeaderSpecific(A,    MAT_COOKIE);
2951   PetscValidHeaderSpecific(rowp, IS_COOKIE);
2952   PetscValidHeaderSpecific(colp, IS_COOKIE);
2953   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
2954   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
2955   if (!A->ops->permutesparsify) {
2956     ierr = MatGetSize(A, &M, &N);                                                                         CHKERRQ(ierr);
2957     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);                                             CHKERRQ(ierr);
2958     ierr = ISGetSize(rowp, &size);                                                                        CHKERRQ(ierr);
2959     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
2960     ierr = ISGetSize(colp, &size);                                                                        CHKERRQ(ierr);
2961     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
2962     ierr = ISInvertPermutation(rowp, 0, &irowp);                                                          CHKERRQ(ierr);
2963     ierr = ISGetIndices(irowp, &rows);                                                                    CHKERRQ(ierr);
2964     ierr = ISInvertPermutation(colp, 0, &icolp);                                                          CHKERRQ(ierr);
2965     ierr = ISGetIndices(icolp, &cols);                                                                    CHKERRQ(ierr);
2966     ierr = PetscMalloc(N * sizeof(int),         &cnew);                                                   CHKERRQ(ierr);
2967     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);                                                   CHKERRQ(ierr);
2968 
2969     /* Setup bandwidth to include */
2970     if (band == PETSC_DECIDE) {
2971       if (frac <= 0.0)
2972         bw = (int) (M * 0.05);
2973       else
2974         bw = (int) (M * frac);
2975     } else {
2976       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
2977       bw = band;
2978     }
2979 
2980     /* Put values into new matrix */
2981     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);                                                    CHKERRQ(ierr);
2982     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
2983       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);                                                      CHKERRQ(ierr);
2984       newRow   = rows[locRow]+locRowStart;
2985       for(col = 0, newNz = 0; col < nz; col++) {
2986         newCol = cols[cwork[col]];
2987         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
2988           cnew[newNz] = newCol;
2989           vnew[newNz] = vwork[col];
2990           newNz++;
2991         }
2992       }
2993       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);                              CHKERRQ(ierr);
2994       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);                                                  CHKERRQ(ierr);
2995     }
2996     ierr = PetscFree(cnew);                                                                               CHKERRQ(ierr);
2997     ierr = PetscFree(vnew);                                                                               CHKERRQ(ierr);
2998     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);                                                      CHKERRQ(ierr);
2999     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);                                                        CHKERRQ(ierr);
3000     ierr = ISRestoreIndices(irowp, &rows);                                                                CHKERRQ(ierr);
3001     ierr = ISRestoreIndices(icolp, &cols);                                                                CHKERRQ(ierr);
3002     ierr = ISDestroy(irowp);                                                                              CHKERRQ(ierr);
3003     ierr = ISDestroy(icolp);                                                                              CHKERRQ(ierr);
3004   } else {
3005     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);                                 CHKERRQ(ierr);
3006   }
3007   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
3008   PetscFunctionReturn(0);
3009 }
3010 
3011 #undef __FUNCT__
3012 #define __FUNCT__ "MatEqual"
3013 /*@
3014    MatEqual - Compares two matrices.
3015 
3016    Collective on Mat
3017 
3018    Input Parameters:
3019 +  A - the first matrix
3020 -  B - the second matrix
3021 
3022    Output Parameter:
3023 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3024 
3025    Level: intermediate
3026 
3027    Concepts: matrices^equality between
3028 @*/
3029 int MatEqual(Mat A,Mat B,PetscTruth *flg)
3030 {
3031   int ierr;
3032 
3033   PetscFunctionBegin;
3034   PetscValidHeaderSpecific(A,MAT_COOKIE);
3035   PetscValidHeaderSpecific(B,MAT_COOKIE);
3036   PetscValidType(A);
3037   MatPreallocated(A);
3038   PetscValidType(B);
3039   MatPreallocated(B);
3040   PetscValidIntPointer(flg);
3041   PetscCheckSameComm(A,B);
3042   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3043   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3044   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);
3045   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
3046   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",B->type_name);
3047   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);
3048   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
3049   PetscFunctionReturn(0);
3050 }
3051 
3052 #undef __FUNCT__
3053 #define __FUNCT__ "MatDiagonalScale"
3054 /*@
3055    MatDiagonalScale - Scales a matrix on the left and right by diagonal
3056    matrices that are stored as vectors.  Either of the two scaling
3057    matrices can be PETSC_NULL.
3058 
3059    Collective on Mat
3060 
3061    Input Parameters:
3062 +  mat - the matrix to be scaled
3063 .  l - the left scaling vector (or PETSC_NULL)
3064 -  r - the right scaling vector (or PETSC_NULL)
3065 
3066    Notes:
3067    MatDiagonalScale() computes A = LAR, where
3068    L = a diagonal matrix, R = a diagonal matrix
3069 
3070    Level: intermediate
3071 
3072    Concepts: matrices^diagonal scaling
3073    Concepts: diagonal scaling of matrices
3074 
3075 .seealso: MatScale()
3076 @*/
3077 int MatDiagonalScale(Mat mat,Vec l,Vec r)
3078 {
3079   int ierr;
3080 
3081   PetscFunctionBegin;
3082   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3083   PetscValidType(mat);
3084   MatPreallocated(mat);
3085   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3086   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE);PetscCheckSameComm(mat,l);}
3087   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE);PetscCheckSameComm(mat,r);}
3088   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3089   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3090 
3091   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3092   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
3093   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3094   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3095   PetscFunctionReturn(0);
3096 }
3097 
3098 #undef __FUNCT__
3099 #define __FUNCT__ "MatScale"
3100 /*@
3101     MatScale - Scales all elements of a matrix by a given number.
3102 
3103     Collective on Mat
3104 
3105     Input Parameters:
3106 +   mat - the matrix to be scaled
3107 -   a  - the scaling value
3108 
3109     Output Parameter:
3110 .   mat - the scaled matrix
3111 
3112     Level: intermediate
3113 
3114     Concepts: matrices^scaling all entries
3115 
3116 .seealso: MatDiagonalScale()
3117 @*/
3118 int MatScale(const PetscScalar *a,Mat mat)
3119 {
3120   int ierr;
3121 
3122   PetscFunctionBegin;
3123   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3124   PetscValidType(mat);
3125   MatPreallocated(mat);
3126   PetscValidScalarPointer(a);
3127   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3128   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3129   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3130 
3131   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3132   ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr);
3133   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3134   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3135   PetscFunctionReturn(0);
3136 }
3137 
3138 #undef __FUNCT__
3139 #define __FUNCT__ "MatNorm"
3140 /*@
3141    MatNorm - Calculates various norms of a matrix.
3142 
3143    Collective on Mat
3144 
3145    Input Parameters:
3146 +  mat - the matrix
3147 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
3148 
3149    Output Parameters:
3150 .  nrm - the resulting norm
3151 
3152    Level: intermediate
3153 
3154    Concepts: matrices^norm
3155    Concepts: norm^of matrix
3156 @*/
3157 int MatNorm(Mat mat,NormType type,PetscReal *nrm)
3158 {
3159   int ierr;
3160 
3161   PetscFunctionBegin;
3162   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3163   PetscValidType(mat);
3164   MatPreallocated(mat);
3165   PetscValidScalarPointer(nrm);
3166 
3167   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3168   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3169   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3170   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
3171   PetscFunctionReturn(0);
3172 }
3173 
3174 /*
3175      This variable is used to prevent counting of MatAssemblyBegin() that
3176    are called from within a MatAssemblyEnd().
3177 */
3178 static int MatAssemblyEnd_InUse = 0;
3179 #undef __FUNCT__
3180 #define __FUNCT__ "MatAssemblyBegin"
3181 /*@
3182    MatAssemblyBegin - Begins assembling the matrix.  This routine should
3183    be called after completing all calls to MatSetValues().
3184 
3185    Collective on Mat
3186 
3187    Input Parameters:
3188 +  mat - the matrix
3189 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3190 
3191    Notes:
3192    MatSetValues() generally caches the values.  The matrix is ready to
3193    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3194    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3195    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3196    using the matrix.
3197 
3198    Level: beginner
3199 
3200    Concepts: matrices^assembling
3201 
3202 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
3203 @*/
3204 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
3205 {
3206   int ierr;
3207 
3208   PetscFunctionBegin;
3209   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3210   PetscValidType(mat);
3211   MatPreallocated(mat);
3212   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
3213   if (mat->assembled) {
3214     mat->was_assembled = PETSC_TRUE;
3215     mat->assembled     = PETSC_FALSE;
3216   }
3217   if (!MatAssemblyEnd_InUse) {
3218     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3219     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3220     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3221   } else {
3222     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3223   }
3224   PetscFunctionReturn(0);
3225 }
3226 
3227 #undef __FUNCT__
3228 #define __FUNCT__ "MatAssembed"
3229 /*@
3230    MatAssembled - Indicates if a matrix has been assembled and is ready for
3231      use; for example, in matrix-vector product.
3232 
3233    Collective on Mat
3234 
3235    Input Parameter:
3236 .  mat - the matrix
3237 
3238    Output Parameter:
3239 .  assembled - PETSC_TRUE or PETSC_FALSE
3240 
3241    Level: advanced
3242 
3243    Concepts: matrices^assembled?
3244 
3245 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3246 @*/
3247 int MatAssembled(Mat mat,PetscTruth *assembled)
3248 {
3249   PetscFunctionBegin;
3250   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3251   PetscValidType(mat);
3252   MatPreallocated(mat);
3253   *assembled = mat->assembled;
3254   PetscFunctionReturn(0);
3255 }
3256 
3257 #undef __FUNCT__
3258 #define __FUNCT__ "MatView_Private"
3259 /*
3260     Processes command line options to determine if/how a matrix
3261   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3262 */
3263 int MatView_Private(Mat mat)
3264 {
3265   int               ierr;
3266   PetscTruth        flg;
3267   static PetscTruth incall = PETSC_FALSE;
3268 
3269   PetscFunctionBegin;
3270   if (incall) PetscFunctionReturn(0);
3271   incall = PETSC_TRUE;
3272   ierr = PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
3273     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);CHKERRQ(ierr);
3274     if (flg) {
3275       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
3276       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3277       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3278     }
3279     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);CHKERRQ(ierr);
3280     if (flg) {
3281       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
3282       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3283       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3284     }
3285     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);CHKERRQ(ierr);
3286     if (flg) {
3287       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3288     }
3289     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);CHKERRQ(ierr);
3290     if (flg) {
3291       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3292       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3293       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3294     }
3295     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);CHKERRQ(ierr);
3296     if (flg) {
3297       ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3298       ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3299     }
3300     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);CHKERRQ(ierr);
3301     if (flg) {
3302       ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3303       ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3304     }
3305   ierr = PetscOptionsEnd();CHKERRQ(ierr);
3306   /* cannot have inside PetscOptionsBegin() because uses PetscOptionsBegin() */
3307   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3308   if (flg) {
3309     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3310     if (flg) {
3311       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3312     }
3313     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3314     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3315     if (flg) {
3316       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3317     }
3318   }
3319   incall = PETSC_FALSE;
3320   PetscFunctionReturn(0);
3321 }
3322 
3323 #undef __FUNCT__
3324 #define __FUNCT__ "MatAssemblyEnd"
3325 /*@
3326    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3327    be called after MatAssemblyBegin().
3328 
3329    Collective on Mat
3330 
3331    Input Parameters:
3332 +  mat - the matrix
3333 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3334 
3335    Options Database Keys:
3336 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3337 .  -mat_view_info_detailed - Prints more detailed info
3338 .  -mat_view - Prints matrix in ASCII format
3339 .  -mat_view_matlab - Prints matrix in Matlab format
3340 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3341 .  -display <name> - Sets display name (default is host)
3342 .  -draw_pause <sec> - Sets number of seconds to pause after display
3343 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
3344 .  -viewer_socket_machine <machine>
3345 .  -viewer_socket_port <port>
3346 .  -mat_view_binary - save matrix to file in binary format
3347 -  -viewer_binary_filename <name>
3348 
3349    Notes:
3350    MatSetValues() generally caches the values.  The matrix is ready to
3351    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3352    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3353    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3354    using the matrix.
3355 
3356    Level: beginner
3357 
3358 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
3359 @*/
3360 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3361 {
3362   int        ierr;
3363   static int inassm = 0;
3364   PetscTruth flg;
3365 
3366   PetscFunctionBegin;
3367   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3368   PetscValidType(mat);
3369   MatPreallocated(mat);
3370 
3371   inassm++;
3372   MatAssemblyEnd_InUse++;
3373   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3374     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3375     if (mat->ops->assemblyend) {
3376       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3377     }
3378     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3379   } else {
3380     if (mat->ops->assemblyend) {
3381       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3382     }
3383   }
3384 
3385   /* Flush assembly is not a true assembly */
3386   if (type != MAT_FLUSH_ASSEMBLY) {
3387     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3388   }
3389   mat->insertmode = NOT_SET_VALUES;
3390   MatAssemblyEnd_InUse--;
3391   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3392   if (!mat->symmetric_eternal) {
3393     mat->symmetric_set              = PETSC_FALSE;
3394     mat->hermitian_set              = PETSC_FALSE;
3395     mat->structurally_symmetric_set = PETSC_FALSE;
3396   }
3397   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3398     ierr = MatView_Private(mat);CHKERRQ(ierr);
3399   }
3400   inassm--;
3401   ierr = PetscOptionsHasName(mat->prefix,"-help",&flg);CHKERRQ(ierr);
3402   if (flg) {
3403     ierr = MatPrintHelp(mat);CHKERRQ(ierr);
3404   }
3405   PetscFunctionReturn(0);
3406 }
3407 
3408 
3409 #undef __FUNCT__
3410 #define __FUNCT__ "MatCompress"
3411 /*@
3412    MatCompress - Tries to store the matrix in as little space as
3413    possible.  May fail if memory is already fully used, since it
3414    tries to allocate new space.
3415 
3416    Collective on Mat
3417 
3418    Input Parameters:
3419 .  mat - the matrix
3420 
3421    Level: advanced
3422 
3423 @*/
3424 int MatCompress(Mat mat)
3425 {
3426   int ierr;
3427 
3428   PetscFunctionBegin;
3429   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3430   PetscValidType(mat);
3431   MatPreallocated(mat);
3432   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3433   PetscFunctionReturn(0);
3434 }
3435 
3436 #undef __FUNCT__
3437 #define __FUNCT__ "MatSetOption"
3438 /*@
3439    MatSetOption - Sets a parameter option for a matrix. Some options
3440    may be specific to certain storage formats.  Some options
3441    determine how values will be inserted (or added). Sorted,
3442    row-oriented input will generally assemble the fastest. The default
3443    is row-oriented, nonsorted input.
3444 
3445    Collective on Mat
3446 
3447    Input Parameters:
3448 +  mat - the matrix
3449 -  option - the option, one of those listed below (and possibly others),
3450              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3451 
3452    Options Describing Matrix Structure:
3453 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3454 .    MAT_HERMITIAN - transpose is the complex conjugation
3455 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3456 .    MAT_NOT_SYMMETRIC - not symmetric in value
3457 .    MAT_NOT_HERMITIAN - transpose is not the complex conjugation
3458 .    MAT_NOT_STRUCTURALLY_SYMMETRIC - not symmetric nonzero structure
3459 .    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
3460                             you set to be kept with all future use of the matrix
3461                             including after MatAssemblyBegin/End() which could
3462                             potentially change the symmetry structure, i.e. you
3463                             KNOW the matrix will ALWAYS have the property you set.
3464 -    MAT_NOT_SYMMETRY_ETERNAL - if MatAssemblyBegin/End() is called then the
3465                                 flags you set will be dropped (in case potentially
3466                                 the symmetry etc was lost).
3467 
3468    Options For Use with MatSetValues():
3469    Insert a logically dense subblock, which can be
3470 +    MAT_ROW_ORIENTED - row-oriented (default)
3471 .    MAT_COLUMN_ORIENTED - column-oriented
3472 .    MAT_ROWS_SORTED - sorted by row
3473 .    MAT_ROWS_UNSORTED - not sorted by row (default)
3474 .    MAT_COLUMNS_SORTED - sorted by column
3475 -    MAT_COLUMNS_UNSORTED - not sorted by column (default)
3476 
3477    Not these options reflect the data you pass in with MatSetValues(); it has
3478    nothing to do with how the data is stored internally in the matrix
3479    data structure.
3480 
3481    When (re)assembling a matrix, we can restrict the input for
3482    efficiency/debugging purposes.  These options include
3483 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3484         allowed if they generate a new nonzero
3485 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3486 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3487          they generate a nonzero in a new diagonal (for block diagonal format only)
3488 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3489 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3490 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3491 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
3492 
3493    Notes:
3494    Some options are relevant only for particular matrix types and
3495    are thus ignored by others.  Other options are not supported by
3496    certain matrix types and will generate an error message if set.
3497 
3498    If using a Fortran 77 module to compute a matrix, one may need to
3499    use the column-oriented option (or convert to the row-oriented
3500    format).
3501 
3502    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
3503    that would generate a new entry in the nonzero structure is instead
3504    ignored.  Thus, if memory has not alredy been allocated for this particular
3505    data, then the insertion is ignored. For dense matrices, in which
3506    the entire array is allocated, no entries are ever ignored.
3507    Set after the first MatAssemblyEnd()
3508 
3509    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
3510    that would generate a new entry in the nonzero structure instead produces
3511    an error. (Currently supported for AIJ and BAIJ formats only.)
3512    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3513    KSPSetOperators() to ensure that the nonzero pattern truely does
3514    remain unchanged. Set after the first MatAssemblyEnd()
3515 
3516    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
3517    that would generate a new entry that has not been preallocated will
3518    instead produce an error. (Currently supported for AIJ and BAIJ formats
3519    only.) This is a useful flag when debugging matrix memory preallocation.
3520 
3521    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
3522    other processors should be dropped, rather than stashed.
3523    This is useful if you know that the "owning" processor is also
3524    always generating the correct matrix entries, so that PETSc need
3525    not transfer duplicate entries generated on another processor.
3526 
3527    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3528    searches during matrix assembly. When this flag is set, the hash table
3529    is created during the first Matrix Assembly. This hash table is
3530    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3531    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
3532    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3533    supported by MATMPIBAIJ format only.
3534 
3535    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
3536    are kept in the nonzero structure
3537 
3538    MAT_IGNORE_ZERO_ENTRIES - for AIJ matrices this will stop zero values from creating
3539    a zero location in the matrix
3540 
3541    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
3542    ROWBS matrix types
3543 
3544    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
3545    with AIJ and ROWBS matrix types
3546 
3547    Level: intermediate
3548 
3549    Concepts: matrices^setting options
3550 
3551 @*/
3552 int MatSetOption(Mat mat,MatOption op)
3553 {
3554   int ierr;
3555 
3556   PetscFunctionBegin;
3557   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3558   PetscValidType(mat);
3559   MatPreallocated(mat);
3560   switch (op) {
3561   case MAT_SYMMETRIC:
3562     mat->symmetric                  = PETSC_TRUE;
3563     mat->structurally_symmetric     = PETSC_TRUE;
3564     mat->symmetric_set              = PETSC_TRUE;
3565     mat->structurally_symmetric_set = PETSC_TRUE;
3566     break;
3567   case MAT_HERMITIAN:
3568     mat->hermitian                  = PETSC_TRUE;
3569     mat->structurally_symmetric     = PETSC_TRUE;
3570     mat->hermitian_set              = PETSC_TRUE;
3571     mat->structurally_symmetric_set = PETSC_TRUE;
3572     break;
3573   case MAT_STRUCTURALLY_SYMMETRIC:
3574     mat->structurally_symmetric     = PETSC_TRUE;
3575     mat->structurally_symmetric_set = PETSC_TRUE;
3576     break;
3577   case MAT_NOT_SYMMETRIC:
3578     mat->symmetric                  = PETSC_FALSE;
3579     mat->symmetric_set              = PETSC_TRUE;
3580     break;
3581   case MAT_NOT_HERMITIAN:
3582     mat->hermitian                  = PETSC_FALSE;
3583     mat->hermitian_set              = PETSC_TRUE;
3584     break;
3585   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
3586     mat->structurally_symmetric     = PETSC_FALSE;
3587     mat->structurally_symmetric_set = PETSC_TRUE;
3588     break;
3589   case MAT_SYMMETRY_ETERNAL:
3590     mat->symmetric_eternal          = PETSC_TRUE;
3591   case MAT_NOT_SYMMETRY_ETERNAL:
3592     mat->symmetric_eternal          = PETSC_FALSE;
3593   default:
3594     break;
3595   }
3596   if (mat->ops->setoption) {
3597     ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);
3598   }
3599   PetscFunctionReturn(0);
3600 }
3601 
3602 #undef __FUNCT__
3603 #define __FUNCT__ "MatZeroEntries"
3604 /*@
3605    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3606    this routine retains the old nonzero structure.
3607 
3608    Collective on Mat
3609 
3610    Input Parameters:
3611 .  mat - the matrix
3612 
3613    Level: intermediate
3614 
3615    Concepts: matrices^zeroing
3616 
3617 .seealso: MatZeroRows()
3618 @*/
3619 int MatZeroEntries(Mat mat)
3620 {
3621   int ierr;
3622 
3623   PetscFunctionBegin;
3624   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3625   PetscValidType(mat);
3626   MatPreallocated(mat);
3627   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3628   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3629 
3630   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3631   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
3632   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3633   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3634   PetscFunctionReturn(0);
3635 }
3636 
3637 #undef __FUNCT__
3638 #define __FUNCT__ "MatZeroRows"
3639 /*@C
3640    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3641    of a set of rows of a matrix.
3642 
3643    Collective on Mat
3644 
3645    Input Parameters:
3646 +  mat - the matrix
3647 .  is - index set of rows to remove
3648 -  diag - pointer to value put in all diagonals of eliminated rows.
3649           Note that diag is not a pointer to an array, but merely a
3650           pointer to a single value.
3651 
3652    Notes:
3653    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3654    but does not release memory.  For the dense and block diagonal
3655    formats this does not alter the nonzero structure.
3656 
3657    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3658    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3659    merely zeroed.
3660 
3661    The user can set a value in the diagonal entry (or for the AIJ and
3662    row formats can optionally remove the main diagonal entry from the
3663    nonzero structure as well, by passing a null pointer (PETSC_NULL
3664    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3665 
3666    For the parallel case, all processes that share the matrix (i.e.,
3667    those in the communicator used for matrix creation) MUST call this
3668    routine, regardless of whether any rows being zeroed are owned by
3669    them.
3670 
3671    Level: intermediate
3672 
3673    Concepts: matrices^zeroing rows
3674 
3675 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3676 @*/
3677 int MatZeroRows(Mat mat,IS is,const PetscScalar *diag)
3678 {
3679   int ierr;
3680 
3681   PetscFunctionBegin;
3682   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3683   PetscValidType(mat);
3684   MatPreallocated(mat);
3685   PetscValidHeaderSpecific(is,IS_COOKIE);
3686   if (diag) PetscValidScalarPointer(diag);
3687   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3688   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3689   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3690 
3691   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
3692   ierr = MatView_Private(mat);CHKERRQ(ierr);
3693   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3694   PetscFunctionReturn(0);
3695 }
3696 
3697 #undef __FUNCT__
3698 #define __FUNCT__ "MatZeroRowsLocal"
3699 /*@C
3700    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3701    of a set of rows of a matrix; using local numbering of rows.
3702 
3703    Collective on Mat
3704 
3705    Input Parameters:
3706 +  mat - the matrix
3707 .  is - index set of rows to remove
3708 -  diag - pointer to value put in all diagonals of eliminated rows.
3709           Note that diag is not a pointer to an array, but merely a
3710           pointer to a single value.
3711 
3712    Notes:
3713    Before calling MatZeroRowsLocal(), the user must first set the
3714    local-to-global mapping by calling MatSetLocalToGlobalMapping().
3715 
3716    For the AIJ matrix formats this removes the old nonzero structure,
3717    but does not release memory.  For the dense and block diagonal
3718    formats this does not alter the nonzero structure.
3719 
3720    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3721    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3722    merely zeroed.
3723 
3724    The user can set a value in the diagonal entry (or for the AIJ and
3725    row formats can optionally remove the main diagonal entry from the
3726    nonzero structure as well, by passing a null pointer (PETSC_NULL
3727    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3728 
3729    Level: intermediate
3730 
3731    Concepts: matrices^zeroing
3732 
3733 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3734 @*/
3735 int MatZeroRowsLocal(Mat mat,IS is,const PetscScalar *diag)
3736 {
3737   int ierr;
3738   IS  newis;
3739 
3740   PetscFunctionBegin;
3741   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3742   PetscValidType(mat);
3743   MatPreallocated(mat);
3744   PetscValidHeaderSpecific(is,IS_COOKIE);
3745   if (diag) PetscValidScalarPointer(diag);
3746   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3747   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3748 
3749   if (mat->ops->zerorowslocal) {
3750     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3751   } else {
3752     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3753     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3754     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3755     ierr = ISDestroy(newis);CHKERRQ(ierr);
3756   }
3757   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3758   PetscFunctionReturn(0);
3759 }
3760 
3761 #undef __FUNCT__
3762 #define __FUNCT__ "MatGetSize"
3763 /*@
3764    MatGetSize - Returns the numbers of rows and columns in a matrix.
3765 
3766    Not Collective
3767 
3768    Input Parameter:
3769 .  mat - the matrix
3770 
3771    Output Parameters:
3772 +  m - the number of global rows
3773 -  n - the number of global columns
3774 
3775    Level: beginner
3776 
3777    Concepts: matrices^size
3778 
3779 .seealso: MatGetLocalSize()
3780 @*/
3781 int MatGetSize(Mat mat,int *m,int* n)
3782 {
3783   PetscFunctionBegin;
3784   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3785   if (m) *m = mat->M;
3786   if (n) *n = mat->N;
3787   PetscFunctionReturn(0);
3788 }
3789 
3790 #undef __FUNCT__
3791 #define __FUNCT__ "MatGetLocalSize"
3792 /*@
3793    MatGetLocalSize - Returns the number of rows and columns in a matrix
3794    stored locally.  This information may be implementation dependent, so
3795    use with care.
3796 
3797    Not Collective
3798 
3799    Input Parameters:
3800 .  mat - the matrix
3801 
3802    Output Parameters:
3803 +  m - the number of local rows
3804 -  n - the number of local columns
3805 
3806    Level: beginner
3807 
3808    Concepts: matrices^local size
3809 
3810 .seealso: MatGetSize()
3811 @*/
3812 int MatGetLocalSize(Mat mat,int *m,int* n)
3813 {
3814   PetscFunctionBegin;
3815   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3816   if (m) *m = mat->m;
3817   if (n) *n = mat->n;
3818   PetscFunctionReturn(0);
3819 }
3820 
3821 #undef __FUNCT__
3822 #define __FUNCT__ "MatGetOwnershipRange"
3823 /*@
3824    MatGetOwnershipRange - Returns the range of matrix rows owned by
3825    this processor, assuming that the matrix is laid out with the first
3826    n1 rows on the first processor, the next n2 rows on the second, etc.
3827    For certain parallel layouts this range may not be well defined.
3828 
3829    Not Collective
3830 
3831    Input Parameters:
3832 .  mat - the matrix
3833 
3834    Output Parameters:
3835 +  m - the global index of the first local row
3836 -  n - one more than the global index of the last local row
3837 
3838    Level: beginner
3839 
3840    Concepts: matrices^row ownership
3841 @*/
3842 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3843 {
3844   int ierr;
3845 
3846   PetscFunctionBegin;
3847   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3848   PetscValidType(mat);
3849   MatPreallocated(mat);
3850   if (m) PetscValidIntPointer(m);
3851   if (n) PetscValidIntPointer(n);
3852   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3853   PetscFunctionReturn(0);
3854 }
3855 
3856 #undef __FUNCT__
3857 #define __FUNCT__ "MatILUFactorSymbolic"
3858 /*@
3859    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3860    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3861    to complete the factorization.
3862 
3863    Collective on Mat
3864 
3865    Input Parameters:
3866 +  mat - the matrix
3867 .  row - row permutation
3868 .  column - column permutation
3869 -  info - structure containing
3870 $      levels - number of levels of fill.
3871 $      expected fill - as ratio of original fill.
3872 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3873                 missing diagonal entries)
3874 
3875    Output Parameters:
3876 .  fact - new matrix that has been symbolically factored
3877 
3878    Notes:
3879    See the users manual for additional information about
3880    choosing the fill factor for better efficiency.
3881 
3882    Most users should employ the simplified KSP interface for linear solvers
3883    instead of working directly with matrix algebra routines such as this.
3884    See, e.g., KSPCreate().
3885 
3886    Level: developer
3887 
3888   Concepts: matrices^symbolic LU factorization
3889   Concepts: matrices^factorization
3890   Concepts: LU^symbolic factorization
3891 
3892 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3893           MatGetOrdering(), MatFactorInfo
3894 
3895 @*/
3896 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
3897 {
3898   int ierr;
3899 
3900   PetscFunctionBegin;
3901   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3902   PetscValidType(mat);
3903   MatPreallocated(mat);
3904   PetscValidPointer(fact);
3905   PetscValidHeaderSpecific(row,IS_COOKIE);
3906   PetscValidHeaderSpecific(col,IS_COOKIE);
3907   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels);
3908   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3909   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3910   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3911   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3912 
3913   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3914   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3915   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3916   PetscFunctionReturn(0);
3917 }
3918 
3919 #undef __FUNCT__
3920 #define __FUNCT__ "MatICCFactorSymbolic"
3921 /*@
3922    MatICCFactorSymbolic - Performs symbolic incomplete
3923    Cholesky factorization for a symmetric matrix.  Use
3924    MatCholeskyFactorNumeric() to complete the factorization.
3925 
3926    Collective on Mat
3927 
3928    Input Parameters:
3929 +  mat - the matrix
3930 .  perm - row and column permutation
3931 -  info - structure containing
3932 $      levels - number of levels of fill.
3933 $      expected fill - as ratio of original fill.
3934 
3935    Output Parameter:
3936 .  fact - the factored matrix
3937 
3938    Notes:
3939    Currently only no-fill factorization is supported.
3940 
3941    Most users should employ the simplified KSP interface for linear solvers
3942    instead of working directly with matrix algebra routines such as this.
3943    See, e.g., KSPCreate().
3944 
3945    Level: developer
3946 
3947   Concepts: matrices^symbolic incomplete Cholesky factorization
3948   Concepts: matrices^factorization
3949   Concepts: Cholsky^symbolic factorization
3950 
3951 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3952 @*/
3953 int MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
3954 {
3955   int ierr;
3956 
3957   PetscFunctionBegin;
3958   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3959   PetscValidType(mat);
3960   MatPreallocated(mat);
3961   PetscValidPointer(fact);
3962   PetscValidHeaderSpecific(perm,IS_COOKIE);
3963   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3964   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %d",(int) info->levels);
3965   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3966   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
3967   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3968 
3969   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3970   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
3971   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
3972   PetscFunctionReturn(0);
3973 }
3974 
3975 #undef __FUNCT__
3976 #define __FUNCT__ "MatGetArray"
3977 /*@C
3978    MatGetArray - Returns a pointer to the element values in the matrix.
3979    The result of this routine is dependent on the underlying matrix data
3980    structure, and may not even work for certain matrix types.  You MUST
3981    call MatRestoreArray() when you no longer need to access the array.
3982 
3983    Not Collective
3984 
3985    Input Parameter:
3986 .  mat - the matrix
3987 
3988    Output Parameter:
3989 .  v - the location of the values
3990 
3991 
3992    Fortran Note:
3993    This routine is used differently from Fortran, e.g.,
3994 .vb
3995         Mat         mat
3996         PetscScalar mat_array(1)
3997         PetscOffset i_mat
3998         int         ierr
3999         call MatGetArray(mat,mat_array,i_mat,ierr)
4000 
4001   C  Access first local entry in matrix; note that array is
4002   C  treated as one dimensional
4003         value = mat_array(i_mat + 1)
4004 
4005         [... other code ...]
4006         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4007 .ve
4008 
4009    See the Fortran chapter of the users manual and
4010    petsc/src/mat/examples/tests for details.
4011 
4012    Level: advanced
4013 
4014    Concepts: matrices^access array
4015 
4016 .seealso: MatRestoreArray(), MatGetArrayF90()
4017 @*/
4018 int MatGetArray(Mat mat,PetscScalar *v[])
4019 {
4020   int ierr;
4021 
4022   PetscFunctionBegin;
4023   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4024   PetscValidType(mat);
4025   MatPreallocated(mat);
4026   PetscValidPointer(v);
4027   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4028   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
4029   PetscFunctionReturn(0);
4030 }
4031 
4032 #undef __FUNCT__
4033 #define __FUNCT__ "MatRestoreArray"
4034 /*@C
4035    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
4036 
4037    Not Collective
4038 
4039    Input Parameter:
4040 +  mat - the matrix
4041 -  v - the location of the values
4042 
4043    Fortran Note:
4044    This routine is used differently from Fortran, e.g.,
4045 .vb
4046         Mat         mat
4047         PetscScalar mat_array(1)
4048         PetscOffset i_mat
4049         int         ierr
4050         call MatGetArray(mat,mat_array,i_mat,ierr)
4051 
4052   C  Access first local entry in matrix; note that array is
4053   C  treated as one dimensional
4054         value = mat_array(i_mat + 1)
4055 
4056         [... other code ...]
4057         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4058 .ve
4059 
4060    See the Fortran chapter of the users manual and
4061    petsc/src/mat/examples/tests for details
4062 
4063    Level: advanced
4064 
4065 .seealso: MatGetArray(), MatRestoreArrayF90()
4066 @*/
4067 int MatRestoreArray(Mat mat,PetscScalar *v[])
4068 {
4069   int ierr;
4070 
4071   PetscFunctionBegin;
4072   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4073   PetscValidType(mat);
4074   MatPreallocated(mat);
4075   PetscValidPointer(v);
4076 #if defined(PETSC_USE_BOPT_g)
4077   CHKMEMQ;
4078 #endif
4079   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4080   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
4081   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
4082   PetscFunctionReturn(0);
4083 }
4084 
4085 #undef __FUNCT__
4086 #define __FUNCT__ "MatGetSubMatrices"
4087 /*@C
4088    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4089    points to an array of valid matrices, they may be reused to store the new
4090    submatrices.
4091 
4092    Collective on Mat
4093 
4094    Input Parameters:
4095 +  mat - the matrix
4096 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4097 .  irow, icol - index sets of rows and columns to extract
4098 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4099 
4100    Output Parameter:
4101 .  submat - the array of submatrices
4102 
4103    Notes:
4104    MatGetSubMatrices() can extract only sequential submatrices
4105    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4106    to extract a parallel submatrix.
4107 
4108    When extracting submatrices from a parallel matrix, each processor can
4109    form a different submatrix by setting the rows and columns of its
4110    individual index sets according to the local submatrix desired.
4111 
4112    When finished using the submatrices, the user should destroy
4113    them with MatDestroyMatrices().
4114 
4115    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
4116    original matrix has not changed from that last call to MatGetSubMatrices().
4117 
4118    This routine creates the matrices in submat; you should NOT create them before
4119    calling it. It also allocates the array of matrix pointers submat.
4120 
4121    Fortran Note:
4122    The Fortran interface is slightly different from that given below; it
4123    requires one to pass in  as submat a Mat (integer) array of size at least m.
4124 
4125    Level: advanced
4126 
4127    Concepts: matrices^accessing submatrices
4128    Concepts: submatrices
4129 
4130 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4131 @*/
4132 int MatGetSubMatrices(Mat mat,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4133 {
4134   int        ierr;
4135 
4136   PetscFunctionBegin;
4137   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4138   PetscValidType(mat);
4139   MatPreallocated(mat);
4140   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4141   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4142   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4143 
4144   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4145   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
4146   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4147   PetscFunctionReturn(0);
4148 }
4149 
4150 #undef __FUNCT__
4151 #define __FUNCT__ "MatDestroyMatrices"
4152 /*@C
4153    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
4154 
4155    Collective on Mat
4156 
4157    Input Parameters:
4158 +  n - the number of local matrices
4159 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4160                        sequence of MatGetSubMatrices())
4161 
4162    Level: advanced
4163 
4164     Notes: Frees not only the matrices, but also the array that contains the matrices
4165 
4166 .seealso: MatGetSubMatrices()
4167 @*/
4168 int MatDestroyMatrices(int n,Mat *mat[])
4169 {
4170   int ierr,i;
4171 
4172   PetscFunctionBegin;
4173   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
4174   PetscValidPointer(mat);
4175   for (i=0; i<n; i++) {
4176     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
4177   }
4178   /* memory is allocated even if n = 0 */
4179   ierr = PetscFree(*mat);CHKERRQ(ierr);
4180   PetscFunctionReturn(0);
4181 }
4182 
4183 #undef __FUNCT__
4184 #define __FUNCT__ "MatIncreaseOverlap"
4185 /*@
4186    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4187    replaces the index sets by larger ones that represent submatrices with
4188    additional overlap.
4189 
4190    Collective on Mat
4191 
4192    Input Parameters:
4193 +  mat - the matrix
4194 .  n   - the number of index sets
4195 .  is  - the array of index sets (these index sets will changed during the call)
4196 -  ov  - the additional overlap requested
4197 
4198    Level: developer
4199 
4200    Concepts: overlap
4201    Concepts: ASM^computing overlap
4202 
4203 .seealso: MatGetSubMatrices()
4204 @*/
4205 int MatIncreaseOverlap(Mat mat,int n,IS is[],int ov)
4206 {
4207   int ierr;
4208 
4209   PetscFunctionBegin;
4210   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4211   PetscValidType(mat);
4212   MatPreallocated(mat);
4213   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4214   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4215 
4216   if (!ov) PetscFunctionReturn(0);
4217   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4218   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4219   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
4220   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4221   PetscFunctionReturn(0);
4222 }
4223 
4224 #undef __FUNCT__
4225 #define __FUNCT__ "MatPrintHelp"
4226 /*@
4227    MatPrintHelp - Prints all the options for the matrix.
4228 
4229    Collective on Mat
4230 
4231    Input Parameter:
4232 .  mat - the matrix
4233 
4234    Options Database Keys:
4235 +  -help - Prints matrix options
4236 -  -h - Prints matrix options
4237 
4238    Level: developer
4239 
4240 .seealso: MatCreate(), MatCreateXXX()
4241 @*/
4242 int MatPrintHelp(Mat mat)
4243 {
4244   static PetscTruth called = PETSC_FALSE;
4245   int               ierr;
4246 
4247   PetscFunctionBegin;
4248   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4249   PetscValidType(mat);
4250   MatPreallocated(mat);
4251 
4252   if (!called) {
4253     if (mat->ops->printhelp) {
4254       ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
4255     }
4256     called = PETSC_TRUE;
4257   }
4258   PetscFunctionReturn(0);
4259 }
4260 
4261 #undef __FUNCT__
4262 #define __FUNCT__ "MatGetBlockSize"
4263 /*@
4264    MatGetBlockSize - Returns the matrix block size; useful especially for the
4265    block row and block diagonal formats.
4266 
4267    Not Collective
4268 
4269    Input Parameter:
4270 .  mat - the matrix
4271 
4272    Output Parameter:
4273 .  bs - block size
4274 
4275    Notes:
4276    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4277    Block row formats are MATSEQBAIJ, MATMPIBAIJ
4278 
4279    Level: intermediate
4280 
4281    Concepts: matrices^block size
4282 
4283 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4284 @*/
4285 int MatGetBlockSize(Mat mat,int *bs)
4286 {
4287   int ierr;
4288 
4289   PetscFunctionBegin;
4290   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4291   PetscValidType(mat);
4292   MatPreallocated(mat);
4293   PetscValidIntPointer(bs);
4294   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4295   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
4296   PetscFunctionReturn(0);
4297 }
4298 
4299 #undef __FUNCT__
4300 #define __FUNCT__ "MatGetRowIJ"
4301 /*@C
4302     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4303 
4304    Collective on Mat
4305 
4306     Input Parameters:
4307 +   mat - the matrix
4308 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4309 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4310                 symmetrized
4311 
4312     Output Parameters:
4313 +   n - number of rows in the (possibly compressed) matrix
4314 .   ia - the row pointers
4315 .   ja - the column indices
4316 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4317 
4318     Level: developer
4319 
4320 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4321 @*/
4322 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4323 {
4324   int ierr;
4325 
4326   PetscFunctionBegin;
4327   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4328   PetscValidType(mat);
4329   MatPreallocated(mat);
4330   if (ia) PetscValidIntPointer(ia);
4331   if (ja) PetscValidIntPointer(ja);
4332   PetscValidIntPointer(done);
4333   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4334   else {
4335     *done = PETSC_TRUE;
4336     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4337   }
4338   PetscFunctionReturn(0);
4339 }
4340 
4341 #undef __FUNCT__
4342 #define __FUNCT__ "MatGetColumnIJ"
4343 /*@C
4344     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4345 
4346     Collective on Mat
4347 
4348     Input Parameters:
4349 +   mat - the matrix
4350 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4351 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4352                 symmetrized
4353 
4354     Output Parameters:
4355 +   n - number of columns in the (possibly compressed) matrix
4356 .   ia - the column pointers
4357 .   ja - the row indices
4358 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4359 
4360     Level: developer
4361 
4362 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4363 @*/
4364 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4365 {
4366   int ierr;
4367 
4368   PetscFunctionBegin;
4369   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4370   PetscValidType(mat);
4371   MatPreallocated(mat);
4372   if (ia) PetscValidIntPointer(ia);
4373   if (ja) PetscValidIntPointer(ja);
4374   PetscValidIntPointer(done);
4375 
4376   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4377   else {
4378     *done = PETSC_TRUE;
4379     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4380   }
4381   PetscFunctionReturn(0);
4382 }
4383 
4384 #undef __FUNCT__
4385 #define __FUNCT__ "MatRestoreRowIJ"
4386 /*@C
4387     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4388     MatGetRowIJ().
4389 
4390     Collective on Mat
4391 
4392     Input Parameters:
4393 +   mat - the matrix
4394 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4395 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4396                 symmetrized
4397 
4398     Output Parameters:
4399 +   n - size of (possibly compressed) matrix
4400 .   ia - the row pointers
4401 .   ja - the column indices
4402 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4403 
4404     Level: developer
4405 
4406 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4407 @*/
4408 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4409 {
4410   int ierr;
4411 
4412   PetscFunctionBegin;
4413   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4414   PetscValidType(mat);
4415   MatPreallocated(mat);
4416   if (ia) PetscValidIntPointer(ia);
4417   if (ja) PetscValidIntPointer(ja);
4418   PetscValidIntPointer(done);
4419 
4420   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4421   else {
4422     *done = PETSC_TRUE;
4423     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4424   }
4425   PetscFunctionReturn(0);
4426 }
4427 
4428 #undef __FUNCT__
4429 #define __FUNCT__ "MatRestoreColumnIJ"
4430 /*@C
4431     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4432     MatGetColumnIJ().
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 - size of (possibly compressed) matrix
4444 .   ia - the column pointers
4445 .   ja - the row indices
4446 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4447 
4448     Level: developer
4449 
4450 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4451 @*/
4452 int MatRestoreColumnIJ(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);
4458   PetscValidType(mat);
4459   MatPreallocated(mat);
4460   if (ia) PetscValidIntPointer(ia);
4461   if (ja) PetscValidIntPointer(ja);
4462   PetscValidIntPointer(done);
4463 
4464   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4465   else {
4466     *done = PETSC_TRUE;
4467     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4468   }
4469   PetscFunctionReturn(0);
4470 }
4471 
4472 #undef __FUNCT__
4473 #define __FUNCT__ "MatColoringPatch"
4474 /*@C
4475     MatColoringPatch -Used inside matrix coloring routines that
4476     use MatGetRowIJ() and/or MatGetColumnIJ().
4477 
4478     Collective on Mat
4479 
4480     Input Parameters:
4481 +   mat - the matrix
4482 .   n   - number of colors
4483 -   colorarray - array indicating color for each column
4484 
4485     Output Parameters:
4486 .   iscoloring - coloring generated using colorarray information
4487 
4488     Level: developer
4489 
4490 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4491 
4492 @*/
4493 int MatColoringPatch(Mat mat,int n,int ncolors,const ISColoringValue colorarray[],ISColoring *iscoloring)
4494 {
4495   int ierr;
4496 
4497   PetscFunctionBegin;
4498   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4499   PetscValidType(mat);
4500   MatPreallocated(mat);
4501   PetscValidIntPointer(colorarray);
4502 
4503   if (!mat->ops->coloringpatch){
4504     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4505   } else {
4506     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4507   }
4508   PetscFunctionReturn(0);
4509 }
4510 
4511 
4512 #undef __FUNCT__
4513 #define __FUNCT__ "MatSetUnfactored"
4514 /*@
4515    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4516 
4517    Collective on Mat
4518 
4519    Input Parameter:
4520 .  mat - the factored matrix to be reset
4521 
4522    Notes:
4523    This routine should be used only with factored matrices formed by in-place
4524    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4525    format).  This option can save memory, for example, when solving nonlinear
4526    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4527    ILU(0) preconditioner.
4528 
4529    Note that one can specify in-place ILU(0) factorization by calling
4530 .vb
4531      PCType(pc,PCILU);
4532      PCILUSeUseInPlace(pc);
4533 .ve
4534    or by using the options -pc_type ilu -pc_ilu_in_place
4535 
4536    In-place factorization ILU(0) can also be used as a local
4537    solver for the blocks within the block Jacobi or additive Schwarz
4538    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4539    of these preconditioners in the users manual for details on setting
4540    local solver options.
4541 
4542    Most users should employ the simplified KSP interface for linear solvers
4543    instead of working directly with matrix algebra routines such as this.
4544    See, e.g., KSPCreate().
4545 
4546    Level: developer
4547 
4548 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4549 
4550    Concepts: matrices^unfactored
4551 
4552 @*/
4553 int MatSetUnfactored(Mat mat)
4554 {
4555   int ierr;
4556 
4557   PetscFunctionBegin;
4558   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4559   PetscValidType(mat);
4560   MatPreallocated(mat);
4561   mat->factor = 0;
4562   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4563   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4564   PetscFunctionReturn(0);
4565 }
4566 
4567 /*MC
4568     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4569 
4570     Synopsis:
4571     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4572 
4573     Not collective
4574 
4575     Input Parameter:
4576 .   x - matrix
4577 
4578     Output Parameters:
4579 +   xx_v - the Fortran90 pointer to the array
4580 -   ierr - error code
4581 
4582     Example of Usage:
4583 .vb
4584       PetscScalar, pointer xx_v(:)
4585       ....
4586       call MatGetArrayF90(x,xx_v,ierr)
4587       a = xx_v(3)
4588       call MatRestoreArrayF90(x,xx_v,ierr)
4589 .ve
4590 
4591     Notes:
4592     Not yet supported for all F90 compilers
4593 
4594     Level: advanced
4595 
4596 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4597 
4598     Concepts: matrices^accessing array
4599 
4600 M*/
4601 
4602 /*MC
4603     MatRestoreArrayF90 - Restores a matrix array that has been
4604     accessed with MatGetArrayF90().
4605 
4606     Synopsis:
4607     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4608 
4609     Not collective
4610 
4611     Input Parameters:
4612 +   x - matrix
4613 -   xx_v - the Fortran90 pointer to the array
4614 
4615     Output Parameter:
4616 .   ierr - error code
4617 
4618     Example of Usage:
4619 .vb
4620        PetscScalar, pointer xx_v(:)
4621        ....
4622        call MatGetArrayF90(x,xx_v,ierr)
4623        a = xx_v(3)
4624        call MatRestoreArrayF90(x,xx_v,ierr)
4625 .ve
4626 
4627     Notes:
4628     Not yet supported for all F90 compilers
4629 
4630     Level: advanced
4631 
4632 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4633 
4634 M*/
4635 
4636 
4637 #undef __FUNCT__
4638 #define __FUNCT__ "MatGetSubMatrix"
4639 /*@
4640     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4641                       as the original matrix.
4642 
4643     Collective on Mat
4644 
4645     Input Parameters:
4646 +   mat - the original matrix
4647 .   isrow - rows this processor should obtain
4648 .   iscol - columns for all processors you wish to keep
4649 .   csize - number of columns "local" to this processor (does nothing for sequential
4650             matrices). This should match the result from VecGetLocalSize(x,...) if you
4651             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4652 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4653 
4654     Output Parameter:
4655 .   newmat - the new submatrix, of the same type as the old
4656 
4657     Level: advanced
4658 
4659     Notes: the iscol argument MUST be the same on each processor. You might be
4660     able to create the iscol argument with ISAllGather().
4661 
4662       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4663    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4664    to this routine with a mat of the same nonzero structure will reuse the matrix
4665    generated the first time.
4666 
4667     Concepts: matrices^submatrices
4668 
4669 .seealso: MatGetSubMatrices(), ISAllGather()
4670 @*/
4671 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4672 {
4673   int     ierr, size;
4674   Mat     *local;
4675 
4676   PetscFunctionBegin;
4677   PetscValidType(mat);
4678   MatPreallocated(mat);
4679   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4680   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4681 
4682   /* if original matrix is on just one processor then use submatrix generated */
4683   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4684     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4685     PetscFunctionReturn(0);
4686   } else if (!mat->ops->getsubmatrix && size == 1) {
4687     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4688     *newmat = *local;
4689     ierr    = PetscFree(local);CHKERRQ(ierr);
4690     PetscFunctionReturn(0);
4691   }
4692 
4693   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4694   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4695   ierr = PetscObjectIncreaseState((PetscObject)*newmat); CHKERRQ(ierr);
4696   PetscFunctionReturn(0);
4697 }
4698 
4699 #undef __FUNCT__
4700 #define __FUNCT__ "MatGetPetscMaps"
4701 /*@C
4702    MatGetPetscMaps - Returns the maps associated with the matrix.
4703 
4704    Not Collective
4705 
4706    Input Parameter:
4707 .  mat - the matrix
4708 
4709    Output Parameters:
4710 +  rmap - the row (right) map
4711 -  cmap - the column (left) map
4712 
4713    Level: developer
4714 
4715    Concepts: maps^getting from matrix
4716 
4717 @*/
4718 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4719 {
4720   int ierr;
4721 
4722   PetscFunctionBegin;
4723   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4724   PetscValidType(mat);
4725   MatPreallocated(mat);
4726   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4727   PetscFunctionReturn(0);
4728 }
4729 
4730 /*
4731       Version that works for all PETSc matrices
4732 */
4733 #undef __FUNCT__
4734 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4735 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4736 {
4737   PetscFunctionBegin;
4738   if (rmap) *rmap = mat->rmap;
4739   if (cmap) *cmap = mat->cmap;
4740   PetscFunctionReturn(0);
4741 }
4742 
4743 #undef __FUNCT__
4744 #define __FUNCT__ "MatSetStashInitialSize"
4745 /*@
4746    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4747    used during the assembly process to store values that belong to
4748    other processors.
4749 
4750    Not Collective
4751 
4752    Input Parameters:
4753 +  mat   - the matrix
4754 .  size  - the initial size of the stash.
4755 -  bsize - the initial size of the block-stash(if used).
4756 
4757    Options Database Keys:
4758 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4759 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4760 
4761    Level: intermediate
4762 
4763    Notes:
4764      The block-stash is used for values set with VecSetValuesBlocked() while
4765      the stash is used for values set with VecSetValues()
4766 
4767      Run with the option -log_info and look for output of the form
4768      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4769      to determine the appropriate value, MM, to use for size and
4770      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4771      to determine the value, BMM to use for bsize
4772 
4773    Concepts: stash^setting matrix size
4774    Concepts: matrices^stash
4775 
4776 @*/
4777 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4778 {
4779   int ierr;
4780 
4781   PetscFunctionBegin;
4782   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4783   PetscValidType(mat);
4784   MatPreallocated(mat);
4785   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4786   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4787   PetscFunctionReturn(0);
4788 }
4789 
4790 #undef __FUNCT__
4791 #define __FUNCT__ "MatInterpolateAdd"
4792 /*@
4793    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4794      the matrix
4795 
4796    Collective on Mat
4797 
4798    Input Parameters:
4799 +  mat   - the matrix
4800 .  x,y - the vectors
4801 -  w - where the result is stored
4802 
4803    Level: intermediate
4804 
4805    Notes:
4806     w may be the same vector as y.
4807 
4808     This allows one to use either the restriction or interpolation (its transpose)
4809     matrix to do the interpolation
4810 
4811     Concepts: interpolation
4812 
4813 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4814 
4815 @*/
4816 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4817 {
4818   int M,N,ierr;
4819 
4820   PetscFunctionBegin;
4821   PetscValidType(A);
4822   MatPreallocated(A);
4823   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4824   if (N > M) {
4825     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4826   } else {
4827     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4828   }
4829   PetscFunctionReturn(0);
4830 }
4831 
4832 #undef __FUNCT__
4833 #define __FUNCT__ "MatInterpolate"
4834 /*@
4835    MatInterpolate - y = A*x or A'*x depending on the shape of
4836      the matrix
4837 
4838    Collective on Mat
4839 
4840    Input Parameters:
4841 +  mat   - the matrix
4842 -  x,y - the vectors
4843 
4844    Level: intermediate
4845 
4846    Notes:
4847     This allows one to use either the restriction or interpolation (its transpose)
4848     matrix to do the interpolation
4849 
4850    Concepts: matrices^interpolation
4851 
4852 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4853 
4854 @*/
4855 int MatInterpolate(Mat A,Vec x,Vec y)
4856 {
4857   int M,N,ierr;
4858 
4859   PetscFunctionBegin;
4860   PetscValidType(A);
4861   MatPreallocated(A);
4862   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4863   if (N > M) {
4864     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4865   } else {
4866     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4867   }
4868   PetscFunctionReturn(0);
4869 }
4870 
4871 #undef __FUNCT__
4872 #define __FUNCT__ "MatRestrict"
4873 /*@
4874    MatRestrict - y = A*x or A'*x
4875 
4876    Collective on Mat
4877 
4878    Input Parameters:
4879 +  mat   - the matrix
4880 -  x,y - the vectors
4881 
4882    Level: intermediate
4883 
4884    Notes:
4885     This allows one to use either the restriction or interpolation (its transpose)
4886     matrix to do the restriction
4887 
4888    Concepts: matrices^restriction
4889 
4890 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4891 
4892 @*/
4893 int MatRestrict(Mat A,Vec x,Vec y)
4894 {
4895   int M,N,ierr;
4896 
4897   PetscFunctionBegin;
4898   PetscValidType(A);
4899   MatPreallocated(A);
4900   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4901   if (N > M) {
4902     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4903   } else {
4904     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4905   }
4906   PetscFunctionReturn(0);
4907 }
4908 
4909 #undef __FUNCT__
4910 #define __FUNCT__ "MatNullSpaceAttach"
4911 /*@C
4912    MatNullSpaceAttach - attaches a null space to a matrix.
4913         This null space will be removed from the resulting vector whenever
4914         MatMult() is called
4915 
4916    Collective on Mat
4917 
4918    Input Parameters:
4919 +  mat - the matrix
4920 -  nullsp - the null space object
4921 
4922    Level: developer
4923 
4924    Notes:
4925       Overwrites any previous null space that may have been attached
4926 
4927    Concepts: null space^attaching to matrix
4928 
4929 .seealso: MatCreate(), MatNullSpaceCreate()
4930 @*/
4931 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
4932 {
4933   int ierr;
4934 
4935   PetscFunctionBegin;
4936   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4937   PetscValidType(mat);
4938   MatPreallocated(mat);
4939   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE);
4940 
4941   if (mat->nullsp) {
4942     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
4943   }
4944   mat->nullsp = nullsp;
4945   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
4946   PetscFunctionReturn(0);
4947 }
4948 
4949 #undef __FUNCT__
4950 #define __FUNCT__ "MatICCFactor"
4951 /*@
4952    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
4953 
4954    Collective on Mat
4955 
4956    Input Parameters:
4957 +  mat - the matrix
4958 .  row - row/column permutation
4959 .  fill - expected fill factor >= 1.0
4960 -  level - level of fill, for ICC(k)
4961 
4962    Notes:
4963    Probably really in-place only when level of fill is zero, otherwise allocates
4964    new space to store factored matrix and deletes previous memory.
4965 
4966    Most users should employ the simplified KSP interface for linear solvers
4967    instead of working directly with matrix algebra routines such as this.
4968    See, e.g., KSPCreate().
4969 
4970    Level: developer
4971 
4972    Concepts: matrices^incomplete Cholesky factorization
4973    Concepts: Cholesky factorization
4974 
4975 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
4976 @*/
4977 int MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
4978 {
4979   int ierr;
4980 
4981   PetscFunctionBegin;
4982   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4983   PetscValidType(mat);
4984   MatPreallocated(mat);
4985   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
4986   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4987   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4988   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4989   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
4990   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
4991   PetscFunctionReturn(0);
4992 }
4993 
4994 #undef __FUNCT__
4995 #define __FUNCT__ "MatSetValuesAdic"
4996 /*@
4997    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
4998 
4999    Not Collective
5000 
5001    Input Parameters:
5002 +  mat - the matrix
5003 -  v - the values compute with ADIC
5004 
5005    Level: developer
5006 
5007    Notes:
5008      Must call MatSetColoring() before using this routine. Also this matrix must already
5009      have its nonzero pattern determined.
5010 
5011 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5012           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5013 @*/
5014 int MatSetValuesAdic(Mat mat,void *v)
5015 {
5016   int ierr;
5017 
5018   PetscFunctionBegin;
5019   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5020   PetscValidType(mat);
5021 
5022   if (!mat->assembled) {
5023     SETERRQ(1,"Matrix must be already assembled");
5024   }
5025   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5026   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5027   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5028   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5029   ierr = MatView_Private(mat);CHKERRQ(ierr);
5030   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5031   PetscFunctionReturn(0);
5032 }
5033 
5034 
5035 #undef __FUNCT__
5036 #define __FUNCT__ "MatSetColoring"
5037 /*@
5038    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5039 
5040    Not Collective
5041 
5042    Input Parameters:
5043 +  mat - the matrix
5044 -  coloring - the coloring
5045 
5046    Level: developer
5047 
5048 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5049           MatSetValues(), MatSetValuesAdic()
5050 @*/
5051 int MatSetColoring(Mat mat,ISColoring coloring)
5052 {
5053   int ierr;
5054 
5055   PetscFunctionBegin;
5056   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5057   PetscValidType(mat);
5058 
5059   if (!mat->assembled) {
5060     SETERRQ(1,"Matrix must be already assembled");
5061   }
5062   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5063   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5064   PetscFunctionReturn(0);
5065 }
5066 
5067 #undef __FUNCT__
5068 #define __FUNCT__ "MatSetValuesAdifor"
5069 /*@
5070    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5071 
5072    Not Collective
5073 
5074    Input Parameters:
5075 +  mat - the matrix
5076 .  nl - leading dimension of v
5077 -  v - the values compute with ADIFOR
5078 
5079    Level: developer
5080 
5081    Notes:
5082      Must call MatSetColoring() before using this routine. Also this matrix must already
5083      have its nonzero pattern determined.
5084 
5085 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5086           MatSetValues(), MatSetColoring()
5087 @*/
5088 int MatSetValuesAdifor(Mat mat,int nl,void *v)
5089 {
5090   int ierr;
5091 
5092   PetscFunctionBegin;
5093   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5094   PetscValidType(mat);
5095 
5096   if (!mat->assembled) {
5097     SETERRQ(1,"Matrix must be already assembled");
5098   }
5099   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5100   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5101   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5102   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5103   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5104   PetscFunctionReturn(0);
5105 }
5106 
5107 EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec);
5108 EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec);
5109 
5110 #undef __FUNCT__
5111 #define __FUNCT__ "MatDiagonalScaleLocal"
5112 /*@
5113    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5114          ghosted ones.
5115 
5116    Not Collective
5117 
5118    Input Parameters:
5119 +  mat - the matrix
5120 -  diag = the diagonal values, including ghost ones
5121 
5122    Level: developer
5123 
5124    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5125 
5126 .seealso: MatDiagonalScale()
5127 @*/
5128 int MatDiagonalScaleLocal(Mat mat,Vec diag)
5129 {
5130   int        ierr,size;
5131 
5132   PetscFunctionBegin;
5133   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5134   PetscValidHeaderSpecific(diag,VEC_COOKIE);
5135   PetscValidType(mat);
5136 
5137   if (!mat->assembled) {
5138     SETERRQ(1,"Matrix must be already assembled");
5139   }
5140   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5141   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5142   if (size == 1) {
5143     int n,m;
5144     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5145     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5146     if (m == n) {
5147       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5148     } else {
5149       SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions");
5150     }
5151   } else {
5152     int (*f)(Mat,Vec);
5153     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5154     if (f) {
5155       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5156     } else {
5157       SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5158     }
5159   }
5160   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5161   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5162   PetscFunctionReturn(0);
5163 }
5164 
5165 #undef __FUNCT__
5166 #define __FUNCT__ "MatGetInertia"
5167 /*@
5168    MatGetInertia - Gets the inertia from a factored matrix
5169 
5170    Collective on Mat
5171 
5172    Input Parameter:
5173 .  mat - the matrix
5174 
5175    Output Parameters:
5176 +   nneg - number of negative eigenvalues
5177 .   nzero - number of zero eigenvalues
5178 -   npos - number of positive eigenvalues
5179 
5180    Level: advanced
5181 
5182    Notes: Matrix must have been factored by MatCholeskyFactor()
5183 
5184 
5185 @*/
5186 int MatGetInertia(Mat mat,int *nneg,int *nzero,int *npos)
5187 {
5188   int        ierr;
5189 
5190   PetscFunctionBegin;
5191   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5192   PetscValidType(mat);
5193   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5194   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5195   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5196   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5197   PetscFunctionReturn(0);
5198 }
5199 
5200 /* ----------------------------------------------------------------*/
5201 #undef __FUNCT__
5202 #define __FUNCT__ "MatSolves"
5203 /*@
5204    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5205 
5206    Collective on Mat and Vecs
5207 
5208    Input Parameters:
5209 +  mat - the factored matrix
5210 -  b - the right-hand-side vectors
5211 
5212    Output Parameter:
5213 .  x - the result vectors
5214 
5215    Notes:
5216    The vectors b and x cannot be the same.  I.e., one cannot
5217    call MatSolves(A,x,x).
5218 
5219    Notes:
5220    Most users should employ the simplified KSP interface for linear solvers
5221    instead of working directly with matrix algebra routines such as this.
5222    See, e.g., KSPCreate().
5223 
5224    Level: developer
5225 
5226    Concepts: matrices^triangular solves
5227 
5228 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
5229 @*/
5230 int MatSolves(Mat mat,Vecs b,Vecs x)
5231 {
5232   int ierr;
5233 
5234   PetscFunctionBegin;
5235   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5236   PetscValidType(mat);
5237   MatPreallocated(mat);
5238   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
5239   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5240   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
5241 
5242   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5243   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5244   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
5245   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5246   PetscFunctionReturn(0);
5247 }
5248 
5249 #undef __FUNCT__
5250 #define __FUNCT__ "MatIsSymmetric"
5251 /*@C
5252    MatIsSymmetric - Test whether a matrix is symmetric
5253 
5254    Collective on Mat
5255 
5256    Input Parameter:
5257 .  A - the matrix to test
5258 
5259    Output Parameters:
5260 .  flg - the result
5261 
5262    Level: intermediate
5263 
5264    Concepts: matrix^symmetry
5265 
5266 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption()
5267 @*/
5268 int MatIsSymmetric(Mat A,PetscTruth *flg)
5269 {
5270   int ierr;
5271 
5272   PetscFunctionBegin;
5273   PetscValidHeaderSpecific(A,MAT_COOKIE);
5274   if (!A->symmetric_set) {
5275     if (!A->ops->issymmetric) SETERRQ(1,"Matrix does not support checking for symmetric");
5276     ierr = (*A->ops->issymmetric)(A,&A->symmetric);CHKERRQ(ierr);
5277     A->symmetric_set = PETSC_TRUE;
5278     if (A->symmetric) {
5279       A->structurally_symmetric_set = PETSC_TRUE;
5280       A->structurally_symmetric     = PETSC_TRUE;
5281     }
5282   }
5283   *flg = A->symmetric;
5284   PetscFunctionReturn(0);
5285 }
5286 
5287 #undef __FUNCT__
5288 #define __FUNCT__ "MatIsStructurallySymmetric"
5289 /*@C
5290    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
5291 
5292    Collective on Mat
5293 
5294    Input Parameter:
5295 .  A - the matrix to test
5296 
5297    Output Parameters:
5298 .  flg - the result
5299 
5300    Level: intermediate
5301 
5302    Concepts: matrix^symmetry
5303 
5304 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
5305 @*/
5306 int MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
5307 {
5308   int ierr;
5309 
5310   PetscFunctionBegin;
5311   PetscValidHeaderSpecific(A,MAT_COOKIE);
5312   if (!A->structurally_symmetric_set) {
5313     if (!A->ops->isstructurallysymmetric) SETERRQ(1,"Matrix does not support checking for structural symmetric");
5314     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
5315     A->structurally_symmetric_set = PETSC_TRUE;
5316   }
5317   *flg = A->structurally_symmetric;
5318   PetscFunctionReturn(0);
5319 }
5320 
5321 #undef __FUNCT__
5322 #define __FUNCT__ "MatIsHermitian"
5323 /*@C
5324    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
5325 
5326    Collective on Mat
5327 
5328    Input Parameter:
5329 .  A - the matrix to test
5330 
5331    Output Parameters:
5332 .  flg - the result
5333 
5334    Level: intermediate
5335 
5336    Concepts: matrix^symmetry
5337 
5338 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
5339 @*/
5340 int MatIsHermitian(Mat A,PetscTruth *flg)
5341 {
5342   int ierr;
5343 
5344   PetscFunctionBegin;
5345   PetscValidHeaderSpecific(A,MAT_COOKIE);
5346   if (!A->hermitian_set) {
5347     if (!A->ops->ishermitian) SETERRQ(1,"Matrix does not support checking for being Hermitian");
5348     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
5349     A->hermitian_set = PETSC_TRUE;
5350     if (A->hermitian) {
5351       A->structurally_symmetric_set = PETSC_TRUE;
5352       A->structurally_symmetric     = PETSC_TRUE;
5353     }
5354   }
5355   *flg = A->hermitian;
5356   PetscFunctionReturn(0);
5357 }
5358