xref: /petsc/src/mat/interface/matrix.c (revision a1d92eed66694224bc6faa1ab6e88dc1bb90150d)
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 relaxation (SOR, Gauss-Seidel) sweeps.
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__ "MatPBRelax"
2436 /*@
2437    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.
2438 
2439    Collective on Mat and Vec
2440 
2441    See MatRelax() for usage
2442 
2443    For multi-component PDEs where the Jacobian is stored in a point block format
2444    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at
2445    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
2446    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.
2447 
2448    Level: developer
2449 
2450 @*/
2451 int MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2452 {
2453   int ierr;
2454 
2455   PetscFunctionBegin;
2456   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2457   PetscValidType(mat);
2458   MatPreallocated(mat);
2459   PetscValidHeaderSpecific(b,VEC_COOKIE);
2460   PetscValidHeaderSpecific(x,VEC_COOKIE);
2461   PetscCheckSameComm(mat,b);
2462   PetscCheckSameComm(mat,x);
2463   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2464   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2465   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2466   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2467   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2468   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2469 
2470   ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2471   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr);
2472   ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr);
2473   ierr = PetscObjectIncreaseState((PetscObject)x); CHKERRQ(ierr);
2474   PetscFunctionReturn(0);
2475 }
2476 
2477 #undef __FUNCT__
2478 #define __FUNCT__ "MatCopy_Basic"
2479 /*
2480       Default matrix copy routine.
2481 */
2482 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2483 {
2484   int         ierr,i,rstart,rend,nz,*cwork;
2485   PetscScalar *vwork;
2486 
2487   PetscFunctionBegin;
2488   ierr = MatZeroEntries(B);CHKERRQ(ierr);
2489   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
2490   for (i=rstart; i<rend; i++) {
2491     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2492     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
2493     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
2494   }
2495   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2496   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2497   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2498   PetscFunctionReturn(0);
2499 }
2500 
2501 #undef __FUNCT__
2502 #define __FUNCT__ "MatCopy"
2503 /*@C
2504    MatCopy - Copys a matrix to another matrix.
2505 
2506    Collective on Mat
2507 
2508    Input Parameters:
2509 +  A - the matrix
2510 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
2511 
2512    Output Parameter:
2513 .  B - where the copy is put
2514 
2515    Notes:
2516    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
2517    same nonzero pattern or the routine will crash.
2518 
2519    MatCopy() copies the matrix entries of a matrix to another existing
2520    matrix (after first zeroing the second matrix).  A related routine is
2521    MatConvert(), which first creates a new matrix and then copies the data.
2522 
2523    Level: intermediate
2524 
2525    Concepts: matrices^copying
2526 
2527 .seealso: MatConvert(), MatDuplicate()
2528 
2529 @*/
2530 int MatCopy(Mat A,Mat B,MatStructure str)
2531 {
2532   int ierr;
2533 
2534   PetscFunctionBegin;
2535   PetscValidHeaderSpecific(A,MAT_COOKIE);
2536   PetscValidHeaderSpecific(B,MAT_COOKIE);
2537   PetscValidType(A);
2538   MatPreallocated(A);
2539   PetscValidType(B);
2540   MatPreallocated(B);
2541   PetscCheckSameComm(A,B);
2542   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2543   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2544   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,
2545                                              A->N,B->N);
2546 
2547   ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2548   if (A->ops->copy) {
2549     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2550   } else { /* generic conversion */
2551     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2552   }
2553   if (A->mapping) {
2554     if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);B->mapping = 0;}
2555     ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr);
2556   }
2557   if (A->bmapping) {
2558     if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);B->bmapping = 0;}
2559     ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr);
2560   }
2561   ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr);
2562   ierr = PetscObjectIncreaseState((PetscObject)B); CHKERRQ(ierr);
2563   PetscFunctionReturn(0);
2564 }
2565 
2566 #include "petscsys.h"
2567 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2568 PetscFList MatConvertList              = 0;
2569 
2570 #undef __FUNCT__
2571 #define __FUNCT__ "MatConvertRegister"
2572 /*@C
2573     MatConvertRegister - Allows one to register a routine that converts a sparse matrix
2574         from one format to another.
2575 
2576   Not Collective
2577 
2578   Input Parameters:
2579 +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2580 -   Converter - the function that reads the matrix from the binary file.
2581 
2582   Level: developer
2583 
2584 .seealso: MatConvertRegisterAll(), MatConvert()
2585 
2586 @*/
2587 int MatConvertRegister(const char sname[],const char path[],const char name[],int (*function)(Mat,MatType,Mat*))
2588 {
2589   int  ierr;
2590   char fullname[PETSC_MAX_PATH_LEN];
2591 
2592   PetscFunctionBegin;
2593   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2594   ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2595   PetscFunctionReturn(0);
2596 }
2597 
2598 #undef __FUNCT__
2599 #define __FUNCT__ "MatConvert"
2600 /*@C
2601    MatConvert - Converts a matrix to another matrix, either of the same
2602    or different type.
2603 
2604    Collective on Mat
2605 
2606    Input Parameters:
2607 +  mat - the matrix
2608 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2609    same type as the original matrix.
2610 
2611    Output Parameter:
2612 .  M - pointer to place new matrix
2613 
2614    Notes:
2615    MatConvert() first creates a new matrix and then copies the data from
2616    the first matrix.  A related routine is MatCopy(), which copies the matrix
2617    entries of one matrix to another already existing matrix context.
2618 
2619    Level: intermediate
2620 
2621    Concepts: matrices^converting between storage formats
2622 
2623 .seealso: MatCopy(), MatDuplicate()
2624 @*/
2625 int MatConvert(Mat mat,const MatType newtype,Mat *M)
2626 {
2627   int        ierr;
2628   PetscTruth sametype,issame,flg;
2629   char       convname[256],mtype[256];
2630 
2631   PetscFunctionBegin;
2632   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2633   PetscValidType(mat);
2634   MatPreallocated(mat);
2635   PetscValidPointer(M);
2636   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2637   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2638 
2639   ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr);
2640   if (flg) {
2641     newtype = mtype;
2642   }
2643   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2644 
2645   ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
2646   ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr);
2647   if ((sametype || issame) && mat->ops->duplicate) {
2648     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
2649   } else {
2650     int (*conv)(Mat,const MatType,Mat*)=PETSC_NULL;
2651     /*
2652        Order of precedence:
2653        1) See if a specialized converter is known to the current matrix.
2654        2) See if a specialized converter is known to the desired matrix class.
2655        3) See if a good general converter is registered for the desired class
2656           (as of 6/27/03 only MATMPIADJ falls into this category).
2657        4) See if a good general converter is known for the current matrix.
2658        5) Use a really basic converter.
2659     */
2660     ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr);
2661     ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr);
2662     ierr = PetscStrcat(convname,"_");CHKERRQ(ierr);
2663     ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr);
2664     ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr);
2665     ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2666     if (!conv) {
2667       Mat B;
2668       ierr = MatCreate(mat->comm,0,0,0,0,&B);CHKERRQ(ierr);
2669       ierr = MatSetType(B,newtype);CHKERRQ(ierr);
2670       ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr);
2671       ierr = MatDestroy(B);CHKERRQ(ierr);
2672       if (!conv) {
2673         if (!MatConvertRegisterAllCalled) {
2674           ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr);
2675         }
2676         ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr);
2677         if (!conv) {
2678           if (mat->ops->convert) {
2679             conv = mat->ops->convert;
2680           } else {
2681             conv = MatConvert_Basic;
2682           }
2683         }
2684       }
2685     }
2686     ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr);
2687   }
2688   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2689   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2690   PetscFunctionReturn(0);
2691 }
2692 
2693 
2694 #undef __FUNCT__
2695 #define __FUNCT__ "MatDuplicate"
2696 /*@C
2697    MatDuplicate - Duplicates a matrix including the non-zero structure.
2698 
2699    Collective on Mat
2700 
2701    Input Parameters:
2702 +  mat - the matrix
2703 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2704         values as well or not
2705 
2706    Output Parameter:
2707 .  M - pointer to place new matrix
2708 
2709    Level: intermediate
2710 
2711    Concepts: matrices^duplicating
2712 
2713 .seealso: MatCopy(), MatConvert()
2714 @*/
2715 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2716 {
2717   int ierr;
2718 
2719   PetscFunctionBegin;
2720   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2721   PetscValidType(mat);
2722   MatPreallocated(mat);
2723   PetscValidPointer(M);
2724   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2725   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2726 
2727   *M  = 0;
2728   ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2729   if (!mat->ops->duplicate) {
2730     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2731   }
2732   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
2733   if (mat->mapping) {
2734     ierr = MatSetLocalToGlobalMapping(*M,mat->mapping);CHKERRQ(ierr);
2735   }
2736   if (mat->bmapping) {
2737     ierr = MatSetLocalToGlobalMappingBlock(*M,mat->mapping);CHKERRQ(ierr);
2738   }
2739   ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr);
2740   ierr = PetscObjectIncreaseState((PetscObject)*M); CHKERRQ(ierr);
2741   PetscFunctionReturn(0);
2742 }
2743 
2744 #undef __FUNCT__
2745 #define __FUNCT__ "MatGetDiagonal"
2746 /*@
2747    MatGetDiagonal - Gets the diagonal of a matrix.
2748 
2749    Collective on Mat and Vec
2750 
2751    Input Parameters:
2752 +  mat - the matrix
2753 -  v - the vector for storing the diagonal
2754 
2755    Output Parameter:
2756 .  v - the diagonal of the matrix
2757 
2758    Notes:
2759    For the SeqAIJ matrix format, this routine may also be called
2760    on a LU factored matrix; in that case it routines the reciprocal of
2761    the diagonal entries in U. It returns the entries permuted by the
2762    row and column permutation used during the symbolic factorization.
2763 
2764    Level: intermediate
2765 
2766    Concepts: matrices^accessing diagonals
2767 
2768 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2769 @*/
2770 int MatGetDiagonal(Mat mat,Vec v)
2771 {
2772   int ierr;
2773 
2774   PetscFunctionBegin;
2775   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2776   PetscValidType(mat);
2777   MatPreallocated(mat);
2778   PetscValidHeaderSpecific(v,VEC_COOKIE);
2779   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2780   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2781   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2782 
2783   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
2784   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2785   PetscFunctionReturn(0);
2786 }
2787 
2788 #undef __FUNCT__
2789 #define __FUNCT__ "MatGetRowMax"
2790 /*@
2791    MatGetRowMax - Gets the maximum value (in absolute value) of each
2792         row of the matrix
2793 
2794    Collective on Mat and Vec
2795 
2796    Input Parameters:
2797 .  mat - the matrix
2798 
2799    Output Parameter:
2800 .  v - the vector for storing the maximums
2801 
2802    Level: intermediate
2803 
2804    Concepts: matrices^getting row maximums
2805 
2806 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2807 @*/
2808 int MatGetRowMax(Mat mat,Vec v)
2809 {
2810   int ierr;
2811 
2812   PetscFunctionBegin;
2813   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2814   PetscValidType(mat);
2815   MatPreallocated(mat);
2816   PetscValidHeaderSpecific(v,VEC_COOKIE);
2817   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2818   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2819   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2820 
2821   ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr);
2822   ierr = PetscObjectIncreaseState((PetscObject)v); CHKERRQ(ierr);
2823   PetscFunctionReturn(0);
2824 }
2825 
2826 #undef __FUNCT__
2827 #define __FUNCT__ "MatTranspose"
2828 /*@C
2829    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2830 
2831    Collective on Mat
2832 
2833    Input Parameter:
2834 .  mat - the matrix to transpose
2835 
2836    Output Parameters:
2837 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2838 
2839    Level: intermediate
2840 
2841    Concepts: matrices^transposing
2842 
2843 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
2844 @*/
2845 int MatTranspose(Mat mat,Mat *B)
2846 {
2847   int ierr;
2848 
2849   PetscFunctionBegin;
2850   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2851   PetscValidType(mat);
2852   MatPreallocated(mat);
2853   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2854   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2855   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2856 
2857   ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2858   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2859   ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr);
2860   if (B) {ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);}
2861   PetscFunctionReturn(0);
2862 }
2863 
2864 #undef __FUNCT__
2865 #define __FUNCT__ "MatIsTranspose"
2866 /*@C
2867    MatIsTranspose - Test whether a matrix is another one's transpose,
2868         or its own, in which case it tests symmetry.
2869 
2870    Collective on Mat
2871 
2872    Input Parameter:
2873 +  A - the matrix to test
2874 -  B - the matrix to test against, this can equal the first parameter
2875 
2876    Output Parameters:
2877 .  flg - the result
2878 
2879    Notes:
2880    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
2881    has a running time of the order of the number of nonzeros; the parallel
2882    test involves parallel copies of the block-offdiagonal parts of the matrix.
2883 
2884    Level: intermediate
2885 
2886    Concepts: matrices^transposing, matrix^symmetry
2887 
2888 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
2889 @*/
2890 int MatIsTranspose(Mat A,Mat B,PetscTruth *flg)
2891 {
2892   int ierr,(*f)(Mat,Mat,PetscTruth*),(*g)(Mat,Mat,PetscTruth*);
2893 
2894   PetscFunctionBegin;
2895   PetscValidHeaderSpecific(A,MAT_COOKIE);
2896   PetscValidHeaderSpecific(B,MAT_COOKIE);
2897   ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr);
2898   ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr);
2899   if (f && g) {
2900     if (f==g) {
2901       ierr = (*f)(A,B,flg);CHKERRQ(ierr);
2902     } else {
2903       SETERRQ(1,"Matrices do not have the same comparator for symmetry test");
2904     }
2905   }
2906   PetscFunctionReturn(0);
2907 }
2908 
2909 #undef __FUNCT__
2910 #define __FUNCT__ "MatPermute"
2911 /*@C
2912    MatPermute - Creates a new matrix with rows and columns permuted from the
2913    original.
2914 
2915    Collective on Mat
2916 
2917    Input Parameters:
2918 +  mat - the matrix to permute
2919 .  row - row permutation, each processor supplies only the permutation for its rows
2920 -  col - column permutation, each processor needs the entire column permutation, that is
2921          this is the same size as the total number of columns in the matrix
2922 
2923    Output Parameters:
2924 .  B - the permuted matrix
2925 
2926    Level: advanced
2927 
2928    Concepts: matrices^permuting
2929 
2930 .seealso: MatGetOrdering()
2931 @*/
2932 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2933 {
2934   int ierr;
2935 
2936   PetscFunctionBegin;
2937   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2938   PetscValidType(mat);
2939   MatPreallocated(mat);
2940   PetscValidHeaderSpecific(row,IS_COOKIE);
2941   PetscValidHeaderSpecific(col,IS_COOKIE);
2942   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2943   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2944   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2945   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2946   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
2947   PetscFunctionReturn(0);
2948 }
2949 
2950 #undef __FUNCT__
2951 #define __FUNCT__ "MatPermuteSparsify"
2952 /*@C
2953   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the
2954   original and sparsified to the prescribed tolerance.
2955 
2956   Collective on Mat
2957 
2958   Input Parameters:
2959 + A    - The matrix to permute
2960 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2961 . frac - The half-bandwidth as a fraction of the total size, or 0.0
2962 . tol  - The drop tolerance
2963 . rowp - The row permutation
2964 - colp - The column permutation
2965 
2966   Output Parameter:
2967 . B    - The permuted, sparsified matrix
2968 
2969   Level: advanced
2970 
2971   Note:
2972   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2973   restrict the half-bandwidth of the resulting matrix to 5% of the
2974   total matrix size.
2975 
2976 .keywords: matrix, permute, sparsify
2977 
2978 .seealso: MatGetOrdering(), MatPermute()
2979 @*/
2980 int MatPermuteSparsify(Mat A, int band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
2981 {
2982   IS           irowp, icolp;
2983   int         *rows, *cols;
2984   int          M, N, locRowStart, locRowEnd;
2985   int          nz, newNz;
2986   int         *cwork, *cnew;
2987   PetscScalar *vwork, *vnew;
2988   int          bw, size;
2989   int          row, locRow, newRow, col, newCol;
2990   int          ierr;
2991 
2992   PetscFunctionBegin;
2993   PetscValidHeaderSpecific(A,    MAT_COOKIE);
2994   PetscValidHeaderSpecific(rowp, IS_COOKIE);
2995   PetscValidHeaderSpecific(colp, IS_COOKIE);
2996   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
2997   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
2998   if (!A->ops->permutesparsify) {
2999     ierr = MatGetSize(A, &M, &N);                                                                         CHKERRQ(ierr);
3000     ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd);                                             CHKERRQ(ierr);
3001     ierr = ISGetSize(rowp, &size);                                                                        CHKERRQ(ierr);
3002     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
3003     ierr = ISGetSize(colp, &size);                                                                        CHKERRQ(ierr);
3004     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
3005     ierr = ISInvertPermutation(rowp, 0, &irowp);                                                          CHKERRQ(ierr);
3006     ierr = ISGetIndices(irowp, &rows);                                                                    CHKERRQ(ierr);
3007     ierr = ISInvertPermutation(colp, 0, &icolp);                                                          CHKERRQ(ierr);
3008     ierr = ISGetIndices(icolp, &cols);                                                                    CHKERRQ(ierr);
3009     ierr = PetscMalloc(N * sizeof(int),         &cnew);                                                   CHKERRQ(ierr);
3010     ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew);                                                   CHKERRQ(ierr);
3011 
3012     /* Setup bandwidth to include */
3013     if (band == PETSC_DECIDE) {
3014       if (frac <= 0.0)
3015         bw = (int) (M * 0.05);
3016       else
3017         bw = (int) (M * frac);
3018     } else {
3019       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3020       bw = band;
3021     }
3022 
3023     /* Put values into new matrix */
3024     ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);                                                    CHKERRQ(ierr);
3025     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3026       ierr = MatGetRow(A, row, &nz, &cwork, &vwork);                                                      CHKERRQ(ierr);
3027       newRow   = rows[locRow]+locRowStart;
3028       for(col = 0, newNz = 0; col < nz; col++) {
3029         newCol = cols[cwork[col]];
3030         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3031           cnew[newNz] = newCol;
3032           vnew[newNz] = vwork[col];
3033           newNz++;
3034         }
3035       }
3036       ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);                              CHKERRQ(ierr);
3037       ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork);                                                  CHKERRQ(ierr);
3038     }
3039     ierr = PetscFree(cnew);                                                                               CHKERRQ(ierr);
3040     ierr = PetscFree(vnew);                                                                               CHKERRQ(ierr);
3041     ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);                                                      CHKERRQ(ierr);
3042     ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);                                                        CHKERRQ(ierr);
3043     ierr = ISRestoreIndices(irowp, &rows);                                                                CHKERRQ(ierr);
3044     ierr = ISRestoreIndices(icolp, &cols);                                                                CHKERRQ(ierr);
3045     ierr = ISDestroy(irowp);                                                                              CHKERRQ(ierr);
3046     ierr = ISDestroy(icolp);                                                                              CHKERRQ(ierr);
3047   } else {
3048     ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);                                 CHKERRQ(ierr);
3049   }
3050   ierr = PetscObjectIncreaseState((PetscObject)*B); CHKERRQ(ierr);
3051   PetscFunctionReturn(0);
3052 }
3053 
3054 #undef __FUNCT__
3055 #define __FUNCT__ "MatEqual"
3056 /*@
3057    MatEqual - Compares two matrices.
3058 
3059    Collective on Mat
3060 
3061    Input Parameters:
3062 +  A - the first matrix
3063 -  B - the second matrix
3064 
3065    Output Parameter:
3066 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
3067 
3068    Level: intermediate
3069 
3070    Concepts: matrices^equality between
3071 @*/
3072 int MatEqual(Mat A,Mat B,PetscTruth *flg)
3073 {
3074   int ierr;
3075 
3076   PetscFunctionBegin;
3077   PetscValidHeaderSpecific(A,MAT_COOKIE);
3078   PetscValidHeaderSpecific(B,MAT_COOKIE);
3079   PetscValidType(A);
3080   MatPreallocated(A);
3081   PetscValidType(B);
3082   MatPreallocated(B);
3083   PetscValidIntPointer(flg);
3084   PetscCheckSameComm(A,B);
3085   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3086   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3087   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);
3088   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
3089   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",B->type_name);
3090   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);
3091   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
3092   PetscFunctionReturn(0);
3093 }
3094 
3095 #undef __FUNCT__
3096 #define __FUNCT__ "MatDiagonalScale"
3097 /*@
3098    MatDiagonalScale - Scales a matrix on the left and right by diagonal
3099    matrices that are stored as vectors.  Either of the two scaling
3100    matrices can be PETSC_NULL.
3101 
3102    Collective on Mat
3103 
3104    Input Parameters:
3105 +  mat - the matrix to be scaled
3106 .  l - the left scaling vector (or PETSC_NULL)
3107 -  r - the right scaling vector (or PETSC_NULL)
3108 
3109    Notes:
3110    MatDiagonalScale() computes A = LAR, where
3111    L = a diagonal matrix, R = a diagonal matrix
3112 
3113    Level: intermediate
3114 
3115    Concepts: matrices^diagonal scaling
3116    Concepts: diagonal scaling of matrices
3117 
3118 .seealso: MatScale()
3119 @*/
3120 int MatDiagonalScale(Mat mat,Vec l,Vec r)
3121 {
3122   int ierr;
3123 
3124   PetscFunctionBegin;
3125   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3126   PetscValidType(mat);
3127   MatPreallocated(mat);
3128   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3129   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE);PetscCheckSameComm(mat,l);}
3130   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE);PetscCheckSameComm(mat,r);}
3131   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3132   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3133 
3134   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3135   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
3136   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3137   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3138   PetscFunctionReturn(0);
3139 }
3140 
3141 #undef __FUNCT__
3142 #define __FUNCT__ "MatScale"
3143 /*@
3144     MatScale - Scales all elements of a matrix by a given number.
3145 
3146     Collective on Mat
3147 
3148     Input Parameters:
3149 +   mat - the matrix to be scaled
3150 -   a  - the scaling value
3151 
3152     Output Parameter:
3153 .   mat - the scaled matrix
3154 
3155     Level: intermediate
3156 
3157     Concepts: matrices^scaling all entries
3158 
3159 .seealso: MatDiagonalScale()
3160 @*/
3161 int MatScale(const PetscScalar *a,Mat mat)
3162 {
3163   int ierr;
3164 
3165   PetscFunctionBegin;
3166   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3167   PetscValidType(mat);
3168   MatPreallocated(mat);
3169   PetscValidScalarPointer(a);
3170   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3171   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3172   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3173 
3174   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3175   ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr);
3176   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
3177   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3178   PetscFunctionReturn(0);
3179 }
3180 
3181 #undef __FUNCT__
3182 #define __FUNCT__ "MatNorm"
3183 /*@
3184    MatNorm - Calculates various norms of a matrix.
3185 
3186    Collective on Mat
3187 
3188    Input Parameters:
3189 +  mat - the matrix
3190 -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
3191 
3192    Output Parameters:
3193 .  nrm - the resulting norm
3194 
3195    Level: intermediate
3196 
3197    Concepts: matrices^norm
3198    Concepts: norm^of matrix
3199 @*/
3200 int MatNorm(Mat mat,NormType type,PetscReal *nrm)
3201 {
3202   int ierr;
3203 
3204   PetscFunctionBegin;
3205   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3206   PetscValidType(mat);
3207   MatPreallocated(mat);
3208   PetscValidScalarPointer(nrm);
3209 
3210   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3211   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3212   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3213   ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr);
3214   PetscFunctionReturn(0);
3215 }
3216 
3217 /*
3218      This variable is used to prevent counting of MatAssemblyBegin() that
3219    are called from within a MatAssemblyEnd().
3220 */
3221 static int MatAssemblyEnd_InUse = 0;
3222 #undef __FUNCT__
3223 #define __FUNCT__ "MatAssemblyBegin"
3224 /*@
3225    MatAssemblyBegin - Begins assembling the matrix.  This routine should
3226    be called after completing all calls to MatSetValues().
3227 
3228    Collective on Mat
3229 
3230    Input Parameters:
3231 +  mat - the matrix
3232 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3233 
3234    Notes:
3235    MatSetValues() generally caches the values.  The matrix is ready to
3236    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3237    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3238    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3239    using the matrix.
3240 
3241    Level: beginner
3242 
3243    Concepts: matrices^assembling
3244 
3245 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
3246 @*/
3247 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
3248 {
3249   int ierr;
3250 
3251   PetscFunctionBegin;
3252   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3253   PetscValidType(mat);
3254   MatPreallocated(mat);
3255   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
3256   if (mat->assembled) {
3257     mat->was_assembled = PETSC_TRUE;
3258     mat->assembled     = PETSC_FALSE;
3259   }
3260   if (!MatAssemblyEnd_InUse) {
3261     ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3262     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3263     ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr);
3264   } else {
3265     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
3266   }
3267   PetscFunctionReturn(0);
3268 }
3269 
3270 #undef __FUNCT__
3271 #define __FUNCT__ "MatAssembed"
3272 /*@
3273    MatAssembled - Indicates if a matrix has been assembled and is ready for
3274      use; for example, in matrix-vector product.
3275 
3276    Collective on Mat
3277 
3278    Input Parameter:
3279 .  mat - the matrix
3280 
3281    Output Parameter:
3282 .  assembled - PETSC_TRUE or PETSC_FALSE
3283 
3284    Level: advanced
3285 
3286    Concepts: matrices^assembled?
3287 
3288 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3289 @*/
3290 int MatAssembled(Mat mat,PetscTruth *assembled)
3291 {
3292   PetscFunctionBegin;
3293   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3294   PetscValidType(mat);
3295   MatPreallocated(mat);
3296   *assembled = mat->assembled;
3297   PetscFunctionReturn(0);
3298 }
3299 
3300 #undef __FUNCT__
3301 #define __FUNCT__ "MatView_Private"
3302 /*
3303     Processes command line options to determine if/how a matrix
3304   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3305 */
3306 int MatView_Private(Mat mat)
3307 {
3308   int               ierr;
3309   PetscTruth        flg;
3310   static PetscTruth incall = PETSC_FALSE;
3311 
3312   PetscFunctionBegin;
3313   if (incall) PetscFunctionReturn(0);
3314   incall = PETSC_TRUE;
3315   ierr = PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");CHKERRQ(ierr);
3316     ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);CHKERRQ(ierr);
3317     if (flg) {
3318       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr);
3319       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3320       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3321     }
3322     ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);CHKERRQ(ierr);
3323     if (flg) {
3324       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr);
3325       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3326       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3327     }
3328     ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);CHKERRQ(ierr);
3329     if (flg) {
3330       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3331     }
3332     ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);CHKERRQ(ierr);
3333     if (flg) {
3334       ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr);
3335       ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3336       ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
3337     }
3338     ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);CHKERRQ(ierr);
3339     if (flg) {
3340       ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3341       ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
3342     }
3343     ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);CHKERRQ(ierr);
3344     if (flg) {
3345       ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3346       ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr);
3347     }
3348   ierr = PetscOptionsEnd();CHKERRQ(ierr);
3349   /* cannot have inside PetscOptionsBegin() because uses PetscOptionsBegin() */
3350   ierr = PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
3351   if (flg) {
3352     ierr = PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
3353     if (flg) {
3354       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
3355     }
3356     ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3357     ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3358     if (flg) {
3359       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
3360     }
3361   }
3362   incall = PETSC_FALSE;
3363   PetscFunctionReturn(0);
3364 }
3365 
3366 #undef __FUNCT__
3367 #define __FUNCT__ "MatAssemblyEnd"
3368 /*@
3369    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3370    be called after MatAssemblyBegin().
3371 
3372    Collective on Mat
3373 
3374    Input Parameters:
3375 +  mat - the matrix
3376 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3377 
3378    Options Database Keys:
3379 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3380 .  -mat_view_info_detailed - Prints more detailed info
3381 .  -mat_view - Prints matrix in ASCII format
3382 .  -mat_view_matlab - Prints matrix in Matlab format
3383 .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3384 .  -display <name> - Sets display name (default is host)
3385 .  -draw_pause <sec> - Sets number of seconds to pause after display
3386 .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
3387 .  -viewer_socket_machine <machine>
3388 .  -viewer_socket_port <port>
3389 .  -mat_view_binary - save matrix to file in binary format
3390 -  -viewer_binary_filename <name>
3391 
3392    Notes:
3393    MatSetValues() generally caches the values.  The matrix is ready to
3394    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3395    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3396    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3397    using the matrix.
3398 
3399    Level: beginner
3400 
3401 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
3402 @*/
3403 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3404 {
3405   int        ierr;
3406   static int inassm = 0;
3407   PetscTruth flg;
3408 
3409   PetscFunctionBegin;
3410   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3411   PetscValidType(mat);
3412   MatPreallocated(mat);
3413 
3414   inassm++;
3415   MatAssemblyEnd_InUse++;
3416   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3417     ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3418     if (mat->ops->assemblyend) {
3419       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3420     }
3421     ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr);
3422   } else {
3423     if (mat->ops->assemblyend) {
3424       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
3425     }
3426   }
3427 
3428   /* Flush assembly is not a true assembly */
3429   if (type != MAT_FLUSH_ASSEMBLY) {
3430     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3431   }
3432   mat->insertmode = NOT_SET_VALUES;
3433   MatAssemblyEnd_InUse--;
3434   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3435   if (!mat->symmetric_eternal) {
3436     mat->symmetric_set              = PETSC_FALSE;
3437     mat->hermitian_set              = PETSC_FALSE;
3438     mat->structurally_symmetric_set = PETSC_FALSE;
3439   }
3440   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3441     ierr = MatView_Private(mat);CHKERRQ(ierr);
3442   }
3443   inassm--;
3444   ierr = PetscOptionsHasName(mat->prefix,"-help",&flg);CHKERRQ(ierr);
3445   if (flg) {
3446     ierr = MatPrintHelp(mat);CHKERRQ(ierr);
3447   }
3448   PetscFunctionReturn(0);
3449 }
3450 
3451 
3452 #undef __FUNCT__
3453 #define __FUNCT__ "MatCompress"
3454 /*@
3455    MatCompress - Tries to store the matrix in as little space as
3456    possible.  May fail if memory is already fully used, since it
3457    tries to allocate new space.
3458 
3459    Collective on Mat
3460 
3461    Input Parameters:
3462 .  mat - the matrix
3463 
3464    Level: advanced
3465 
3466 @*/
3467 int MatCompress(Mat mat)
3468 {
3469   int ierr;
3470 
3471   PetscFunctionBegin;
3472   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3473   PetscValidType(mat);
3474   MatPreallocated(mat);
3475   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
3476   PetscFunctionReturn(0);
3477 }
3478 
3479 #undef __FUNCT__
3480 #define __FUNCT__ "MatSetOption"
3481 /*@
3482    MatSetOption - Sets a parameter option for a matrix. Some options
3483    may be specific to certain storage formats.  Some options
3484    determine how values will be inserted (or added). Sorted,
3485    row-oriented input will generally assemble the fastest. The default
3486    is row-oriented, nonsorted input.
3487 
3488    Collective on Mat
3489 
3490    Input Parameters:
3491 +  mat - the matrix
3492 -  option - the option, one of those listed below (and possibly others),
3493              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
3494 
3495    Options Describing Matrix Structure:
3496 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3497 .    MAT_HERMITIAN - transpose is the complex conjugation
3498 .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3499 .    MAT_NOT_SYMMETRIC - not symmetric in value
3500 .    MAT_NOT_HERMITIAN - transpose is not the complex conjugation
3501 .    MAT_NOT_STRUCTURALLY_SYMMETRIC - not symmetric nonzero structure
3502 .    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
3503                             you set to be kept with all future use of the matrix
3504                             including after MatAssemblyBegin/End() which could
3505                             potentially change the symmetry structure, i.e. you
3506                             KNOW the matrix will ALWAYS have the property you set.
3507 -    MAT_NOT_SYMMETRY_ETERNAL - if MatAssemblyBegin/End() is called then the
3508                                 flags you set will be dropped (in case potentially
3509                                 the symmetry etc was lost).
3510 
3511    Options For Use with MatSetValues():
3512    Insert a logically dense subblock, which can be
3513 +    MAT_ROW_ORIENTED - row-oriented (default)
3514 .    MAT_COLUMN_ORIENTED - column-oriented
3515 .    MAT_ROWS_SORTED - sorted by row
3516 .    MAT_ROWS_UNSORTED - not sorted by row (default)
3517 .    MAT_COLUMNS_SORTED - sorted by column
3518 -    MAT_COLUMNS_UNSORTED - not sorted by column (default)
3519 
3520    Not these options reflect the data you pass in with MatSetValues(); it has
3521    nothing to do with how the data is stored internally in the matrix
3522    data structure.
3523 
3524    When (re)assembling a matrix, we can restrict the input for
3525    efficiency/debugging purposes.  These options include
3526 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3527         allowed if they generate a new nonzero
3528 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3529 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3530          they generate a nonzero in a new diagonal (for block diagonal format only)
3531 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3532 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3533 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3534 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
3535 
3536    Notes:
3537    Some options are relevant only for particular matrix types and
3538    are thus ignored by others.  Other options are not supported by
3539    certain matrix types and will generate an error message if set.
3540 
3541    If using a Fortran 77 module to compute a matrix, one may need to
3542    use the column-oriented option (or convert to the row-oriented
3543    format).
3544 
3545    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
3546    that would generate a new entry in the nonzero structure is instead
3547    ignored.  Thus, if memory has not alredy been allocated for this particular
3548    data, then the insertion is ignored. For dense matrices, in which
3549    the entire array is allocated, no entries are ever ignored.
3550    Set after the first MatAssemblyEnd()
3551 
3552    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
3553    that would generate a new entry in the nonzero structure instead produces
3554    an error. (Currently supported for AIJ and BAIJ formats only.)
3555    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3556    KSPSetOperators() to ensure that the nonzero pattern truely does
3557    remain unchanged. Set after the first MatAssemblyEnd()
3558 
3559    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
3560    that would generate a new entry that has not been preallocated will
3561    instead produce an error. (Currently supported for AIJ and BAIJ formats
3562    only.) This is a useful flag when debugging matrix memory preallocation.
3563 
3564    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
3565    other processors should be dropped, rather than stashed.
3566    This is useful if you know that the "owning" processor is also
3567    always generating the correct matrix entries, so that PETSc need
3568    not transfer duplicate entries generated on another processor.
3569 
3570    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3571    searches during matrix assembly. When this flag is set, the hash table
3572    is created during the first Matrix Assembly. This hash table is
3573    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3574    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
3575    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3576    supported by MATMPIBAIJ format only.
3577 
3578    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
3579    are kept in the nonzero structure
3580 
3581    MAT_IGNORE_ZERO_ENTRIES - for AIJ matrices this will stop zero values from creating
3582    a zero location in the matrix
3583 
3584    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
3585    ROWBS matrix types
3586 
3587    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
3588    with AIJ and ROWBS matrix types
3589 
3590    Level: intermediate
3591 
3592    Concepts: matrices^setting options
3593 
3594 @*/
3595 int MatSetOption(Mat mat,MatOption op)
3596 {
3597   int ierr;
3598 
3599   PetscFunctionBegin;
3600   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3601   PetscValidType(mat);
3602   MatPreallocated(mat);
3603   switch (op) {
3604   case MAT_SYMMETRIC:
3605     mat->symmetric                  = PETSC_TRUE;
3606     mat->structurally_symmetric     = PETSC_TRUE;
3607     mat->symmetric_set              = PETSC_TRUE;
3608     mat->structurally_symmetric_set = PETSC_TRUE;
3609     break;
3610   case MAT_HERMITIAN:
3611     mat->hermitian                  = PETSC_TRUE;
3612     mat->structurally_symmetric     = PETSC_TRUE;
3613     mat->hermitian_set              = PETSC_TRUE;
3614     mat->structurally_symmetric_set = PETSC_TRUE;
3615     break;
3616   case MAT_STRUCTURALLY_SYMMETRIC:
3617     mat->structurally_symmetric     = PETSC_TRUE;
3618     mat->structurally_symmetric_set = PETSC_TRUE;
3619     break;
3620   case MAT_NOT_SYMMETRIC:
3621     mat->symmetric                  = PETSC_FALSE;
3622     mat->symmetric_set              = PETSC_TRUE;
3623     break;
3624   case MAT_NOT_HERMITIAN:
3625     mat->hermitian                  = PETSC_FALSE;
3626     mat->hermitian_set              = PETSC_TRUE;
3627     break;
3628   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
3629     mat->structurally_symmetric     = PETSC_FALSE;
3630     mat->structurally_symmetric_set = PETSC_TRUE;
3631     break;
3632   case MAT_SYMMETRY_ETERNAL:
3633     mat->symmetric_eternal          = PETSC_TRUE;
3634   case MAT_NOT_SYMMETRY_ETERNAL:
3635     mat->symmetric_eternal          = PETSC_FALSE;
3636   default:
3637     break;
3638   }
3639   if (mat->ops->setoption) {
3640     ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);
3641   }
3642   PetscFunctionReturn(0);
3643 }
3644 
3645 #undef __FUNCT__
3646 #define __FUNCT__ "MatZeroEntries"
3647 /*@
3648    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3649    this routine retains the old nonzero structure.
3650 
3651    Collective on Mat
3652 
3653    Input Parameters:
3654 .  mat - the matrix
3655 
3656    Level: intermediate
3657 
3658    Concepts: matrices^zeroing
3659 
3660 .seealso: MatZeroRows()
3661 @*/
3662 int MatZeroEntries(Mat mat)
3663 {
3664   int ierr;
3665 
3666   PetscFunctionBegin;
3667   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3668   PetscValidType(mat);
3669   MatPreallocated(mat);
3670   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3671   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3672 
3673   ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3674   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
3675   ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr);
3676   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3677   PetscFunctionReturn(0);
3678 }
3679 
3680 #undef __FUNCT__
3681 #define __FUNCT__ "MatZeroRows"
3682 /*@C
3683    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3684    of a set of rows of a matrix.
3685 
3686    Collective on Mat
3687 
3688    Input Parameters:
3689 +  mat - the matrix
3690 .  is - index set of rows to remove
3691 -  diag - pointer to value put in all diagonals of eliminated rows.
3692           Note that diag is not a pointer to an array, but merely a
3693           pointer to a single value.
3694 
3695    Notes:
3696    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3697    but does not release memory.  For the dense and block diagonal
3698    formats this does not alter the nonzero structure.
3699 
3700    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3701    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3702    merely zeroed.
3703 
3704    The user can set a value in the diagonal entry (or for the AIJ and
3705    row formats can optionally remove the main diagonal entry from the
3706    nonzero structure as well, by passing a null pointer (PETSC_NULL
3707    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3708 
3709    For the parallel case, all processes that share the matrix (i.e.,
3710    those in the communicator used for matrix creation) MUST call this
3711    routine, regardless of whether any rows being zeroed are owned by
3712    them.
3713 
3714    Level: intermediate
3715 
3716    Concepts: matrices^zeroing rows
3717 
3718 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3719 @*/
3720 int MatZeroRows(Mat mat,IS is,const PetscScalar *diag)
3721 {
3722   int ierr;
3723 
3724   PetscFunctionBegin;
3725   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3726   PetscValidType(mat);
3727   MatPreallocated(mat);
3728   PetscValidHeaderSpecific(is,IS_COOKIE);
3729   if (diag) PetscValidScalarPointer(diag);
3730   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3731   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3732   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3733 
3734   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
3735   ierr = MatView_Private(mat);CHKERRQ(ierr);
3736   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3737   PetscFunctionReturn(0);
3738 }
3739 
3740 #undef __FUNCT__
3741 #define __FUNCT__ "MatZeroRowsLocal"
3742 /*@C
3743    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3744    of a set of rows of a matrix; using local numbering of rows.
3745 
3746    Collective on Mat
3747 
3748    Input Parameters:
3749 +  mat - the matrix
3750 .  is - index set of rows to remove
3751 -  diag - pointer to value put in all diagonals of eliminated rows.
3752           Note that diag is not a pointer to an array, but merely a
3753           pointer to a single value.
3754 
3755    Notes:
3756    Before calling MatZeroRowsLocal(), the user must first set the
3757    local-to-global mapping by calling MatSetLocalToGlobalMapping().
3758 
3759    For the AIJ matrix formats this removes the old nonzero structure,
3760    but does not release memory.  For the dense and block diagonal
3761    formats this does not alter the nonzero structure.
3762 
3763    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3764    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3765    merely zeroed.
3766 
3767    The user can set a value in the diagonal entry (or for the AIJ and
3768    row formats can optionally remove the main diagonal entry from the
3769    nonzero structure as well, by passing a null pointer (PETSC_NULL
3770    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
3771 
3772    Level: intermediate
3773 
3774    Concepts: matrices^zeroing
3775 
3776 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3777 @*/
3778 int MatZeroRowsLocal(Mat mat,IS is,const PetscScalar *diag)
3779 {
3780   int ierr;
3781   IS  newis;
3782 
3783   PetscFunctionBegin;
3784   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3785   PetscValidType(mat);
3786   MatPreallocated(mat);
3787   PetscValidHeaderSpecific(is,IS_COOKIE);
3788   if (diag) PetscValidScalarPointer(diag);
3789   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3790   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3791 
3792   if (mat->ops->zerorowslocal) {
3793     ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr);
3794   } else {
3795     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3796     ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
3797     ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
3798     ierr = ISDestroy(newis);CHKERRQ(ierr);
3799   }
3800   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
3801   PetscFunctionReturn(0);
3802 }
3803 
3804 #undef __FUNCT__
3805 #define __FUNCT__ "MatGetSize"
3806 /*@
3807    MatGetSize - Returns the numbers of rows and columns in a matrix.
3808 
3809    Not Collective
3810 
3811    Input Parameter:
3812 .  mat - the matrix
3813 
3814    Output Parameters:
3815 +  m - the number of global rows
3816 -  n - the number of global columns
3817 
3818    Level: beginner
3819 
3820    Concepts: matrices^size
3821 
3822 .seealso: MatGetLocalSize()
3823 @*/
3824 int MatGetSize(Mat mat,int *m,int* n)
3825 {
3826   PetscFunctionBegin;
3827   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3828   if (m) *m = mat->M;
3829   if (n) *n = mat->N;
3830   PetscFunctionReturn(0);
3831 }
3832 
3833 #undef __FUNCT__
3834 #define __FUNCT__ "MatGetLocalSize"
3835 /*@
3836    MatGetLocalSize - Returns the number of rows and columns in a matrix
3837    stored locally.  This information may be implementation dependent, so
3838    use with care.
3839 
3840    Not Collective
3841 
3842    Input Parameters:
3843 .  mat - the matrix
3844 
3845    Output Parameters:
3846 +  m - the number of local rows
3847 -  n - the number of local columns
3848 
3849    Level: beginner
3850 
3851    Concepts: matrices^local size
3852 
3853 .seealso: MatGetSize()
3854 @*/
3855 int MatGetLocalSize(Mat mat,int *m,int* n)
3856 {
3857   PetscFunctionBegin;
3858   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3859   if (m) *m = mat->m;
3860   if (n) *n = mat->n;
3861   PetscFunctionReturn(0);
3862 }
3863 
3864 #undef __FUNCT__
3865 #define __FUNCT__ "MatGetOwnershipRange"
3866 /*@
3867    MatGetOwnershipRange - Returns the range of matrix rows owned by
3868    this processor, assuming that the matrix is laid out with the first
3869    n1 rows on the first processor, the next n2 rows on the second, etc.
3870    For certain parallel layouts this range may not be well defined.
3871 
3872    Not Collective
3873 
3874    Input Parameters:
3875 .  mat - the matrix
3876 
3877    Output Parameters:
3878 +  m - the global index of the first local row
3879 -  n - one more than the global index of the last local row
3880 
3881    Level: beginner
3882 
3883    Concepts: matrices^row ownership
3884 @*/
3885 int MatGetOwnershipRange(Mat mat,int *m,int* n)
3886 {
3887   int ierr;
3888 
3889   PetscFunctionBegin;
3890   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3891   PetscValidType(mat);
3892   MatPreallocated(mat);
3893   if (m) PetscValidIntPointer(m);
3894   if (n) PetscValidIntPointer(n);
3895   ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr);
3896   PetscFunctionReturn(0);
3897 }
3898 
3899 #undef __FUNCT__
3900 #define __FUNCT__ "MatILUFactorSymbolic"
3901 /*@
3902    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3903    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
3904    to complete the factorization.
3905 
3906    Collective on Mat
3907 
3908    Input Parameters:
3909 +  mat - the matrix
3910 .  row - row permutation
3911 .  column - column permutation
3912 -  info - structure containing
3913 $      levels - number of levels of fill.
3914 $      expected fill - as ratio of original fill.
3915 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3916                 missing diagonal entries)
3917 
3918    Output Parameters:
3919 .  fact - new matrix that has been symbolically factored
3920 
3921    Notes:
3922    See the users manual for additional information about
3923    choosing the fill factor for better efficiency.
3924 
3925    Most users should employ the simplified KSP interface for linear solvers
3926    instead of working directly with matrix algebra routines such as this.
3927    See, e.g., KSPCreate().
3928 
3929    Level: developer
3930 
3931   Concepts: matrices^symbolic LU factorization
3932   Concepts: matrices^factorization
3933   Concepts: LU^symbolic factorization
3934 
3935 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3936           MatGetOrdering(), MatFactorInfo
3937 
3938 @*/
3939 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
3940 {
3941   int ierr;
3942 
3943   PetscFunctionBegin;
3944   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3945   PetscValidType(mat);
3946   MatPreallocated(mat);
3947   PetscValidPointer(fact);
3948   PetscValidHeaderSpecific(row,IS_COOKIE);
3949   PetscValidHeaderSpecific(col,IS_COOKIE);
3950   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels);
3951   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3952   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3953   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3954   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3955 
3956   ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3957   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3958   ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);
3959   PetscFunctionReturn(0);
3960 }
3961 
3962 #undef __FUNCT__
3963 #define __FUNCT__ "MatICCFactorSymbolic"
3964 /*@
3965    MatICCFactorSymbolic - Performs symbolic incomplete
3966    Cholesky factorization for a symmetric matrix.  Use
3967    MatCholeskyFactorNumeric() to complete the factorization.
3968 
3969    Collective on Mat
3970 
3971    Input Parameters:
3972 +  mat - the matrix
3973 .  perm - row and column permutation
3974 -  info - structure containing
3975 $      levels - number of levels of fill.
3976 $      expected fill - as ratio of original fill.
3977 
3978    Output Parameter:
3979 .  fact - the factored matrix
3980 
3981    Notes:
3982    Currently only no-fill factorization is supported.
3983 
3984    Most users should employ the simplified KSP interface for linear solvers
3985    instead of working directly with matrix algebra routines such as this.
3986    See, e.g., KSPCreate().
3987 
3988    Level: developer
3989 
3990   Concepts: matrices^symbolic incomplete Cholesky factorization
3991   Concepts: matrices^factorization
3992   Concepts: Cholsky^symbolic factorization
3993 
3994 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
3995 @*/
3996 int MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
3997 {
3998   int ierr;
3999 
4000   PetscFunctionBegin;
4001   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4002   PetscValidType(mat);
4003   MatPreallocated(mat);
4004   PetscValidPointer(fact);
4005   PetscValidHeaderSpecific(perm,IS_COOKIE);
4006   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4007   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %d",(int) info->levels);
4008   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
4009   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
4010   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4011 
4012   ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4013   ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);CHKERRQ(ierr);
4014   ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);
4015   PetscFunctionReturn(0);
4016 }
4017 
4018 #undef __FUNCT__
4019 #define __FUNCT__ "MatGetArray"
4020 /*@C
4021    MatGetArray - Returns a pointer to the element values in the matrix.
4022    The result of this routine is dependent on the underlying matrix data
4023    structure, and may not even work for certain matrix types.  You MUST
4024    call MatRestoreArray() when you no longer need to access the array.
4025 
4026    Not Collective
4027 
4028    Input Parameter:
4029 .  mat - the matrix
4030 
4031    Output Parameter:
4032 .  v - the location of the values
4033 
4034 
4035    Fortran Note:
4036    This routine is used differently from Fortran, e.g.,
4037 .vb
4038         Mat         mat
4039         PetscScalar mat_array(1)
4040         PetscOffset i_mat
4041         int         ierr
4042         call MatGetArray(mat,mat_array,i_mat,ierr)
4043 
4044   C  Access first local entry in matrix; note that array is
4045   C  treated as one dimensional
4046         value = mat_array(i_mat + 1)
4047 
4048         [... other code ...]
4049         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4050 .ve
4051 
4052    See the Fortran chapter of the users manual and
4053    petsc/src/mat/examples/tests for details.
4054 
4055    Level: advanced
4056 
4057    Concepts: matrices^access array
4058 
4059 .seealso: MatRestoreArray(), MatGetArrayF90()
4060 @*/
4061 int MatGetArray(Mat mat,PetscScalar *v[])
4062 {
4063   int ierr;
4064 
4065   PetscFunctionBegin;
4066   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4067   PetscValidType(mat);
4068   MatPreallocated(mat);
4069   PetscValidPointer(v);
4070   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4071   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
4072   PetscFunctionReturn(0);
4073 }
4074 
4075 #undef __FUNCT__
4076 #define __FUNCT__ "MatRestoreArray"
4077 /*@C
4078    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
4079 
4080    Not Collective
4081 
4082    Input Parameter:
4083 +  mat - the matrix
4084 -  v - the location of the values
4085 
4086    Fortran Note:
4087    This routine is used differently from Fortran, e.g.,
4088 .vb
4089         Mat         mat
4090         PetscScalar mat_array(1)
4091         PetscOffset i_mat
4092         int         ierr
4093         call MatGetArray(mat,mat_array,i_mat,ierr)
4094 
4095   C  Access first local entry in matrix; note that array is
4096   C  treated as one dimensional
4097         value = mat_array(i_mat + 1)
4098 
4099         [... other code ...]
4100         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4101 .ve
4102 
4103    See the Fortran chapter of the users manual and
4104    petsc/src/mat/examples/tests for details
4105 
4106    Level: advanced
4107 
4108 .seealso: MatGetArray(), MatRestoreArrayF90()
4109 @*/
4110 int MatRestoreArray(Mat mat,PetscScalar *v[])
4111 {
4112   int ierr;
4113 
4114   PetscFunctionBegin;
4115   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4116   PetscValidType(mat);
4117   MatPreallocated(mat);
4118   PetscValidPointer(v);
4119 #if defined(PETSC_USE_BOPT_g)
4120   CHKMEMQ;
4121 #endif
4122   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4123   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
4124   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
4125   PetscFunctionReturn(0);
4126 }
4127 
4128 #undef __FUNCT__
4129 #define __FUNCT__ "MatGetSubMatrices"
4130 /*@C
4131    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4132    points to an array of valid matrices, they may be reused to store the new
4133    submatrices.
4134 
4135    Collective on Mat
4136 
4137    Input Parameters:
4138 +  mat - the matrix
4139 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4140 .  irow, icol - index sets of rows and columns to extract
4141 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4142 
4143    Output Parameter:
4144 .  submat - the array of submatrices
4145 
4146    Notes:
4147    MatGetSubMatrices() can extract only sequential submatrices
4148    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4149    to extract a parallel submatrix.
4150 
4151    When extracting submatrices from a parallel matrix, each processor can
4152    form a different submatrix by setting the rows and columns of its
4153    individual index sets according to the local submatrix desired.
4154 
4155    When finished using the submatrices, the user should destroy
4156    them with MatDestroyMatrices().
4157 
4158    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
4159    original matrix has not changed from that last call to MatGetSubMatrices().
4160 
4161    This routine creates the matrices in submat; you should NOT create them before
4162    calling it. It also allocates the array of matrix pointers submat.
4163 
4164    Fortran Note:
4165    The Fortran interface is slightly different from that given below; it
4166    requires one to pass in  as submat a Mat (integer) array of size at least m.
4167 
4168    Level: advanced
4169 
4170    Concepts: matrices^accessing submatrices
4171    Concepts: submatrices
4172 
4173 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4174 @*/
4175 int MatGetSubMatrices(Mat mat,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4176 {
4177   int        ierr;
4178 
4179   PetscFunctionBegin;
4180   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4181   PetscValidType(mat);
4182   MatPreallocated(mat);
4183   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4184   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4185   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4186 
4187   ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4188   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
4189   ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr);
4190   PetscFunctionReturn(0);
4191 }
4192 
4193 #undef __FUNCT__
4194 #define __FUNCT__ "MatDestroyMatrices"
4195 /*@C
4196    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
4197 
4198    Collective on Mat
4199 
4200    Input Parameters:
4201 +  n - the number of local matrices
4202 -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4203                        sequence of MatGetSubMatrices())
4204 
4205    Level: advanced
4206 
4207     Notes: Frees not only the matrices, but also the array that contains the matrices
4208 
4209 .seealso: MatGetSubMatrices()
4210 @*/
4211 int MatDestroyMatrices(int n,Mat *mat[])
4212 {
4213   int ierr,i;
4214 
4215   PetscFunctionBegin;
4216   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
4217   PetscValidPointer(mat);
4218   for (i=0; i<n; i++) {
4219     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
4220   }
4221   /* memory is allocated even if n = 0 */
4222   ierr = PetscFree(*mat);CHKERRQ(ierr);
4223   PetscFunctionReturn(0);
4224 }
4225 
4226 #undef __FUNCT__
4227 #define __FUNCT__ "MatIncreaseOverlap"
4228 /*@
4229    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4230    replaces the index sets by larger ones that represent submatrices with
4231    additional overlap.
4232 
4233    Collective on Mat
4234 
4235    Input Parameters:
4236 +  mat - the matrix
4237 .  n   - the number of index sets
4238 .  is  - the array of index sets (these index sets will changed during the call)
4239 -  ov  - the additional overlap requested
4240 
4241    Level: developer
4242 
4243    Concepts: overlap
4244    Concepts: ASM^computing overlap
4245 
4246 .seealso: MatGetSubMatrices()
4247 @*/
4248 int MatIncreaseOverlap(Mat mat,int n,IS is[],int ov)
4249 {
4250   int ierr;
4251 
4252   PetscFunctionBegin;
4253   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4254   PetscValidType(mat);
4255   MatPreallocated(mat);
4256   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4257   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4258 
4259   if (!ov) PetscFunctionReturn(0);
4260   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4261   ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4262   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
4263   ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr);
4264   PetscFunctionReturn(0);
4265 }
4266 
4267 #undef __FUNCT__
4268 #define __FUNCT__ "MatPrintHelp"
4269 /*@
4270    MatPrintHelp - Prints all the options for the matrix.
4271 
4272    Collective on Mat
4273 
4274    Input Parameter:
4275 .  mat - the matrix
4276 
4277    Options Database Keys:
4278 +  -help - Prints matrix options
4279 -  -h - Prints matrix options
4280 
4281    Level: developer
4282 
4283 .seealso: MatCreate(), MatCreateXXX()
4284 @*/
4285 int MatPrintHelp(Mat mat)
4286 {
4287   static PetscTruth called = PETSC_FALSE;
4288   int               ierr;
4289 
4290   PetscFunctionBegin;
4291   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4292   PetscValidType(mat);
4293   MatPreallocated(mat);
4294 
4295   if (!called) {
4296     if (mat->ops->printhelp) {
4297       ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
4298     }
4299     called = PETSC_TRUE;
4300   }
4301   PetscFunctionReturn(0);
4302 }
4303 
4304 #undef __FUNCT__
4305 #define __FUNCT__ "MatGetBlockSize"
4306 /*@
4307    MatGetBlockSize - Returns the matrix block size; useful especially for the
4308    block row and block diagonal formats.
4309 
4310    Not Collective
4311 
4312    Input Parameter:
4313 .  mat - the matrix
4314 
4315    Output Parameter:
4316 .  bs - block size
4317 
4318    Notes:
4319    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4320    Block row formats are MATSEQBAIJ, MATMPIBAIJ
4321 
4322    Level: intermediate
4323 
4324    Concepts: matrices^block size
4325 
4326 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4327 @*/
4328 int MatGetBlockSize(Mat mat,int *bs)
4329 {
4330   int ierr;
4331 
4332   PetscFunctionBegin;
4333   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4334   PetscValidType(mat);
4335   MatPreallocated(mat);
4336   PetscValidIntPointer(bs);
4337   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4338   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
4339   PetscFunctionReturn(0);
4340 }
4341 
4342 #undef __FUNCT__
4343 #define __FUNCT__ "MatGetRowIJ"
4344 /*@C
4345     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
4346 
4347    Collective on Mat
4348 
4349     Input Parameters:
4350 +   mat - the matrix
4351 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4352 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4353                 symmetrized
4354 
4355     Output Parameters:
4356 +   n - number of rows in the (possibly compressed) matrix
4357 .   ia - the row pointers
4358 .   ja - the column indices
4359 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4360 
4361     Level: developer
4362 
4363 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4364 @*/
4365 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4366 {
4367   int ierr;
4368 
4369   PetscFunctionBegin;
4370   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4371   PetscValidType(mat);
4372   MatPreallocated(mat);
4373   if (ia) PetscValidIntPointer(ia);
4374   if (ja) PetscValidIntPointer(ja);
4375   PetscValidIntPointer(done);
4376   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4377   else {
4378     *done = PETSC_TRUE;
4379     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4380   }
4381   PetscFunctionReturn(0);
4382 }
4383 
4384 #undef __FUNCT__
4385 #define __FUNCT__ "MatGetColumnIJ"
4386 /*@C
4387     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
4388 
4389     Collective on Mat
4390 
4391     Input Parameters:
4392 +   mat - the matrix
4393 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4394 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4395                 symmetrized
4396 
4397     Output Parameters:
4398 +   n - number of columns in the (possibly compressed) matrix
4399 .   ia - the column pointers
4400 .   ja - the row indices
4401 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
4402 
4403     Level: developer
4404 
4405 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4406 @*/
4407 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4408 {
4409   int ierr;
4410 
4411   PetscFunctionBegin;
4412   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4413   PetscValidType(mat);
4414   MatPreallocated(mat);
4415   if (ia) PetscValidIntPointer(ia);
4416   if (ja) PetscValidIntPointer(ja);
4417   PetscValidIntPointer(done);
4418 
4419   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4420   else {
4421     *done = PETSC_TRUE;
4422     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4423   }
4424   PetscFunctionReturn(0);
4425 }
4426 
4427 #undef __FUNCT__
4428 #define __FUNCT__ "MatRestoreRowIJ"
4429 /*@C
4430     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4431     MatGetRowIJ().
4432 
4433     Collective on Mat
4434 
4435     Input Parameters:
4436 +   mat - the matrix
4437 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4438 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4439                 symmetrized
4440 
4441     Output Parameters:
4442 +   n - size of (possibly compressed) matrix
4443 .   ia - the row pointers
4444 .   ja - the column indices
4445 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4446 
4447     Level: developer
4448 
4449 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4450 @*/
4451 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4452 {
4453   int ierr;
4454 
4455   PetscFunctionBegin;
4456   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4457   PetscValidType(mat);
4458   MatPreallocated(mat);
4459   if (ia) PetscValidIntPointer(ia);
4460   if (ja) PetscValidIntPointer(ja);
4461   PetscValidIntPointer(done);
4462 
4463   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4464   else {
4465     *done = PETSC_TRUE;
4466     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4467   }
4468   PetscFunctionReturn(0);
4469 }
4470 
4471 #undef __FUNCT__
4472 #define __FUNCT__ "MatRestoreColumnIJ"
4473 /*@C
4474     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4475     MatGetColumnIJ().
4476 
4477     Collective on Mat
4478 
4479     Input Parameters:
4480 +   mat - the matrix
4481 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4482 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4483                 symmetrized
4484 
4485     Output Parameters:
4486 +   n - size of (possibly compressed) matrix
4487 .   ia - the column pointers
4488 .   ja - the row indices
4489 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
4490 
4491     Level: developer
4492 
4493 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4494 @*/
4495 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4496 {
4497   int ierr;
4498 
4499   PetscFunctionBegin;
4500   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4501   PetscValidType(mat);
4502   MatPreallocated(mat);
4503   if (ia) PetscValidIntPointer(ia);
4504   if (ja) PetscValidIntPointer(ja);
4505   PetscValidIntPointer(done);
4506 
4507   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4508   else {
4509     *done = PETSC_TRUE;
4510     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
4511   }
4512   PetscFunctionReturn(0);
4513 }
4514 
4515 #undef __FUNCT__
4516 #define __FUNCT__ "MatColoringPatch"
4517 /*@C
4518     MatColoringPatch -Used inside matrix coloring routines that
4519     use MatGetRowIJ() and/or MatGetColumnIJ().
4520 
4521     Collective on Mat
4522 
4523     Input Parameters:
4524 +   mat - the matrix
4525 .   n   - number of colors
4526 -   colorarray - array indicating color for each column
4527 
4528     Output Parameters:
4529 .   iscoloring - coloring generated using colorarray information
4530 
4531     Level: developer
4532 
4533 .seealso: MatGetRowIJ(), MatGetColumnIJ()
4534 
4535 @*/
4536 int MatColoringPatch(Mat mat,int n,int ncolors,const ISColoringValue colorarray[],ISColoring *iscoloring)
4537 {
4538   int ierr;
4539 
4540   PetscFunctionBegin;
4541   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4542   PetscValidType(mat);
4543   MatPreallocated(mat);
4544   PetscValidIntPointer(colorarray);
4545 
4546   if (!mat->ops->coloringpatch){
4547     ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr);
4548   } else {
4549     ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr);
4550   }
4551   PetscFunctionReturn(0);
4552 }
4553 
4554 
4555 #undef __FUNCT__
4556 #define __FUNCT__ "MatSetUnfactored"
4557 /*@
4558    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
4559 
4560    Collective on Mat
4561 
4562    Input Parameter:
4563 .  mat - the factored matrix to be reset
4564 
4565    Notes:
4566    This routine should be used only with factored matrices formed by in-place
4567    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4568    format).  This option can save memory, for example, when solving nonlinear
4569    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4570    ILU(0) preconditioner.
4571 
4572    Note that one can specify in-place ILU(0) factorization by calling
4573 .vb
4574      PCType(pc,PCILU);
4575      PCILUSeUseInPlace(pc);
4576 .ve
4577    or by using the options -pc_type ilu -pc_ilu_in_place
4578 
4579    In-place factorization ILU(0) can also be used as a local
4580    solver for the blocks within the block Jacobi or additive Schwarz
4581    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
4582    of these preconditioners in the users manual for details on setting
4583    local solver options.
4584 
4585    Most users should employ the simplified KSP interface for linear solvers
4586    instead of working directly with matrix algebra routines such as this.
4587    See, e.g., KSPCreate().
4588 
4589    Level: developer
4590 
4591 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
4592 
4593    Concepts: matrices^unfactored
4594 
4595 @*/
4596 int MatSetUnfactored(Mat mat)
4597 {
4598   int ierr;
4599 
4600   PetscFunctionBegin;
4601   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4602   PetscValidType(mat);
4603   MatPreallocated(mat);
4604   mat->factor = 0;
4605   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
4606   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
4607   PetscFunctionReturn(0);
4608 }
4609 
4610 /*MC
4611     MatGetArrayF90 - Accesses a matrix array from Fortran90.
4612 
4613     Synopsis:
4614     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4615 
4616     Not collective
4617 
4618     Input Parameter:
4619 .   x - matrix
4620 
4621     Output Parameters:
4622 +   xx_v - the Fortran90 pointer to the array
4623 -   ierr - error code
4624 
4625     Example of Usage:
4626 .vb
4627       PetscScalar, pointer xx_v(:)
4628       ....
4629       call MatGetArrayF90(x,xx_v,ierr)
4630       a = xx_v(3)
4631       call MatRestoreArrayF90(x,xx_v,ierr)
4632 .ve
4633 
4634     Notes:
4635     Not yet supported for all F90 compilers
4636 
4637     Level: advanced
4638 
4639 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
4640 
4641     Concepts: matrices^accessing array
4642 
4643 M*/
4644 
4645 /*MC
4646     MatRestoreArrayF90 - Restores a matrix array that has been
4647     accessed with MatGetArrayF90().
4648 
4649     Synopsis:
4650     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
4651 
4652     Not collective
4653 
4654     Input Parameters:
4655 +   x - matrix
4656 -   xx_v - the Fortran90 pointer to the array
4657 
4658     Output Parameter:
4659 .   ierr - error code
4660 
4661     Example of Usage:
4662 .vb
4663        PetscScalar, pointer xx_v(:)
4664        ....
4665        call MatGetArrayF90(x,xx_v,ierr)
4666        a = xx_v(3)
4667        call MatRestoreArrayF90(x,xx_v,ierr)
4668 .ve
4669 
4670     Notes:
4671     Not yet supported for all F90 compilers
4672 
4673     Level: advanced
4674 
4675 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
4676 
4677 M*/
4678 
4679 
4680 #undef __FUNCT__
4681 #define __FUNCT__ "MatGetSubMatrix"
4682 /*@
4683     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4684                       as the original matrix.
4685 
4686     Collective on Mat
4687 
4688     Input Parameters:
4689 +   mat - the original matrix
4690 .   isrow - rows this processor should obtain
4691 .   iscol - columns for all processors you wish to keep
4692 .   csize - number of columns "local" to this processor (does nothing for sequential
4693             matrices). This should match the result from VecGetLocalSize(x,...) if you
4694             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4695 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4696 
4697     Output Parameter:
4698 .   newmat - the new submatrix, of the same type as the old
4699 
4700     Level: advanced
4701 
4702     Notes: the iscol argument MUST be the same on each processor. You might be
4703     able to create the iscol argument with ISAllGather().
4704 
4705       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4706    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4707    to this routine with a mat of the same nonzero structure will reuse the matrix
4708    generated the first time.
4709 
4710     Concepts: matrices^submatrices
4711 
4712 .seealso: MatGetSubMatrices(), ISAllGather()
4713 @*/
4714 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4715 {
4716   int     ierr, size;
4717   Mat     *local;
4718 
4719   PetscFunctionBegin;
4720   PetscValidType(mat);
4721   MatPreallocated(mat);
4722   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4723   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
4724 
4725   /* if original matrix is on just one processor then use submatrix generated */
4726   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4727     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
4728     PetscFunctionReturn(0);
4729   } else if (!mat->ops->getsubmatrix && size == 1) {
4730     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
4731     *newmat = *local;
4732     ierr    = PetscFree(local);CHKERRQ(ierr);
4733     PetscFunctionReturn(0);
4734   }
4735 
4736   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4737   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
4738   ierr = PetscObjectIncreaseState((PetscObject)*newmat); CHKERRQ(ierr);
4739   PetscFunctionReturn(0);
4740 }
4741 
4742 #undef __FUNCT__
4743 #define __FUNCT__ "MatGetPetscMaps"
4744 /*@C
4745    MatGetPetscMaps - Returns the maps associated with the matrix.
4746 
4747    Not Collective
4748 
4749    Input Parameter:
4750 .  mat - the matrix
4751 
4752    Output Parameters:
4753 +  rmap - the row (right) map
4754 -  cmap - the column (left) map
4755 
4756    Level: developer
4757 
4758    Concepts: maps^getting from matrix
4759 
4760 @*/
4761 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4762 {
4763   int ierr;
4764 
4765   PetscFunctionBegin;
4766   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4767   PetscValidType(mat);
4768   MatPreallocated(mat);
4769   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
4770   PetscFunctionReturn(0);
4771 }
4772 
4773 /*
4774       Version that works for all PETSc matrices
4775 */
4776 #undef __FUNCT__
4777 #define __FUNCT__ "MatGetPetscMaps_Petsc"
4778 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4779 {
4780   PetscFunctionBegin;
4781   if (rmap) *rmap = mat->rmap;
4782   if (cmap) *cmap = mat->cmap;
4783   PetscFunctionReturn(0);
4784 }
4785 
4786 #undef __FUNCT__
4787 #define __FUNCT__ "MatSetStashInitialSize"
4788 /*@
4789    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4790    used during the assembly process to store values that belong to
4791    other processors.
4792 
4793    Not Collective
4794 
4795    Input Parameters:
4796 +  mat   - the matrix
4797 .  size  - the initial size of the stash.
4798 -  bsize - the initial size of the block-stash(if used).
4799 
4800    Options Database Keys:
4801 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4802 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
4803 
4804    Level: intermediate
4805 
4806    Notes:
4807      The block-stash is used for values set with VecSetValuesBlocked() while
4808      the stash is used for values set with VecSetValues()
4809 
4810      Run with the option -log_info and look for output of the form
4811      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4812      to determine the appropriate value, MM, to use for size and
4813      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4814      to determine the value, BMM to use for bsize
4815 
4816    Concepts: stash^setting matrix size
4817    Concepts: matrices^stash
4818 
4819 @*/
4820 int MatSetStashInitialSize(Mat mat,int size, int bsize)
4821 {
4822   int ierr;
4823 
4824   PetscFunctionBegin;
4825   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4826   PetscValidType(mat);
4827   MatPreallocated(mat);
4828   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
4829   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
4830   PetscFunctionReturn(0);
4831 }
4832 
4833 #undef __FUNCT__
4834 #define __FUNCT__ "MatInterpolateAdd"
4835 /*@
4836    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
4837      the matrix
4838 
4839    Collective on Mat
4840 
4841    Input Parameters:
4842 +  mat   - the matrix
4843 .  x,y - the vectors
4844 -  w - where the result is stored
4845 
4846    Level: intermediate
4847 
4848    Notes:
4849     w may be the same vector as y.
4850 
4851     This allows one to use either the restriction or interpolation (its transpose)
4852     matrix to do the interpolation
4853 
4854     Concepts: interpolation
4855 
4856 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4857 
4858 @*/
4859 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4860 {
4861   int M,N,ierr;
4862 
4863   PetscFunctionBegin;
4864   PetscValidType(A);
4865   MatPreallocated(A);
4866   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4867   if (N > M) {
4868     ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr);
4869   } else {
4870     ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr);
4871   }
4872   PetscFunctionReturn(0);
4873 }
4874 
4875 #undef __FUNCT__
4876 #define __FUNCT__ "MatInterpolate"
4877 /*@
4878    MatInterpolate - y = A*x or A'*x depending on the shape of
4879      the matrix
4880 
4881    Collective on Mat
4882 
4883    Input Parameters:
4884 +  mat   - the matrix
4885 -  x,y - the vectors
4886 
4887    Level: intermediate
4888 
4889    Notes:
4890     This allows one to use either the restriction or interpolation (its transpose)
4891     matrix to do the interpolation
4892 
4893    Concepts: matrices^interpolation
4894 
4895 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
4896 
4897 @*/
4898 int MatInterpolate(Mat A,Vec x,Vec y)
4899 {
4900   int M,N,ierr;
4901 
4902   PetscFunctionBegin;
4903   PetscValidType(A);
4904   MatPreallocated(A);
4905   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4906   if (N > M) {
4907     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4908   } else {
4909     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4910   }
4911   PetscFunctionReturn(0);
4912 }
4913 
4914 #undef __FUNCT__
4915 #define __FUNCT__ "MatRestrict"
4916 /*@
4917    MatRestrict - y = A*x or A'*x
4918 
4919    Collective on Mat
4920 
4921    Input Parameters:
4922 +  mat   - the matrix
4923 -  x,y - the vectors
4924 
4925    Level: intermediate
4926 
4927    Notes:
4928     This allows one to use either the restriction or interpolation (its transpose)
4929     matrix to do the restriction
4930 
4931    Concepts: matrices^restriction
4932 
4933 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
4934 
4935 @*/
4936 int MatRestrict(Mat A,Vec x,Vec y)
4937 {
4938   int M,N,ierr;
4939 
4940   PetscFunctionBegin;
4941   PetscValidType(A);
4942   MatPreallocated(A);
4943   ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
4944   if (N > M) {
4945     ierr = MatMult(A,x,y);CHKERRQ(ierr);
4946   } else {
4947     ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr);
4948   }
4949   PetscFunctionReturn(0);
4950 }
4951 
4952 #undef __FUNCT__
4953 #define __FUNCT__ "MatNullSpaceAttach"
4954 /*@C
4955    MatNullSpaceAttach - attaches a null space to a matrix.
4956         This null space will be removed from the resulting vector whenever
4957         MatMult() is called
4958 
4959    Collective on Mat
4960 
4961    Input Parameters:
4962 +  mat - the matrix
4963 -  nullsp - the null space object
4964 
4965    Level: developer
4966 
4967    Notes:
4968       Overwrites any previous null space that may have been attached
4969 
4970    Concepts: null space^attaching to matrix
4971 
4972 .seealso: MatCreate(), MatNullSpaceCreate()
4973 @*/
4974 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
4975 {
4976   int ierr;
4977 
4978   PetscFunctionBegin;
4979   PetscValidHeaderSpecific(mat,MAT_COOKIE);
4980   PetscValidType(mat);
4981   MatPreallocated(mat);
4982   PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE);
4983 
4984   if (mat->nullsp) {
4985     ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr);
4986   }
4987   mat->nullsp = nullsp;
4988   ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);
4989   PetscFunctionReturn(0);
4990 }
4991 
4992 #undef __FUNCT__
4993 #define __FUNCT__ "MatICCFactor"
4994 /*@
4995    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
4996 
4997    Collective on Mat
4998 
4999    Input Parameters:
5000 +  mat - the matrix
5001 .  row - row/column permutation
5002 .  fill - expected fill factor >= 1.0
5003 -  level - level of fill, for ICC(k)
5004 
5005    Notes:
5006    Probably really in-place only when level of fill is zero, otherwise allocates
5007    new space to store factored matrix and deletes previous memory.
5008 
5009    Most users should employ the simplified KSP interface for linear solvers
5010    instead of working directly with matrix algebra routines such as this.
5011    See, e.g., KSPCreate().
5012 
5013    Level: developer
5014 
5015    Concepts: matrices^incomplete Cholesky factorization
5016    Concepts: Cholesky factorization
5017 
5018 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5019 @*/
5020 int MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5021 {
5022   int ierr;
5023 
5024   PetscFunctionBegin;
5025   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5026   PetscValidType(mat);
5027   MatPreallocated(mat);
5028   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5029   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5030   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5031   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5032   ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr);
5033   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5034   PetscFunctionReturn(0);
5035 }
5036 
5037 #undef __FUNCT__
5038 #define __FUNCT__ "MatSetValuesAdic"
5039 /*@
5040    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.
5041 
5042    Not Collective
5043 
5044    Input Parameters:
5045 +  mat - the matrix
5046 -  v - the values compute with ADIC
5047 
5048    Level: developer
5049 
5050    Notes:
5051      Must call MatSetColoring() before using this routine. Also this matrix must already
5052      have its nonzero pattern determined.
5053 
5054 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5055           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5056 @*/
5057 int MatSetValuesAdic(Mat mat,void *v)
5058 {
5059   int ierr;
5060 
5061   PetscFunctionBegin;
5062   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5063   PetscValidType(mat);
5064 
5065   if (!mat->assembled) {
5066     SETERRQ(1,"Matrix must be already assembled");
5067   }
5068   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5069   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5070   ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr);
5071   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5072   ierr = MatView_Private(mat);CHKERRQ(ierr);
5073   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5074   PetscFunctionReturn(0);
5075 }
5076 
5077 
5078 #undef __FUNCT__
5079 #define __FUNCT__ "MatSetColoring"
5080 /*@
5081    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()
5082 
5083    Not Collective
5084 
5085    Input Parameters:
5086 +  mat - the matrix
5087 -  coloring - the coloring
5088 
5089    Level: developer
5090 
5091 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5092           MatSetValues(), MatSetValuesAdic()
5093 @*/
5094 int MatSetColoring(Mat mat,ISColoring coloring)
5095 {
5096   int ierr;
5097 
5098   PetscFunctionBegin;
5099   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5100   PetscValidType(mat);
5101 
5102   if (!mat->assembled) {
5103     SETERRQ(1,"Matrix must be already assembled");
5104   }
5105   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5106   ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr);
5107   PetscFunctionReturn(0);
5108 }
5109 
5110 #undef __FUNCT__
5111 #define __FUNCT__ "MatSetValuesAdifor"
5112 /*@
5113    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
5114 
5115    Not Collective
5116 
5117    Input Parameters:
5118 +  mat - the matrix
5119 .  nl - leading dimension of v
5120 -  v - the values compute with ADIFOR
5121 
5122    Level: developer
5123 
5124    Notes:
5125      Must call MatSetColoring() before using this routine. Also this matrix must already
5126      have its nonzero pattern determined.
5127 
5128 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5129           MatSetValues(), MatSetColoring()
5130 @*/
5131 int MatSetValuesAdifor(Mat mat,int nl,void *v)
5132 {
5133   int ierr;
5134 
5135   PetscFunctionBegin;
5136   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5137   PetscValidType(mat);
5138 
5139   if (!mat->assembled) {
5140     SETERRQ(1,"Matrix must be already assembled");
5141   }
5142   ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5143   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5144   ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr);
5145   ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr);
5146   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5147   PetscFunctionReturn(0);
5148 }
5149 
5150 EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec);
5151 EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec);
5152 
5153 #undef __FUNCT__
5154 #define __FUNCT__ "MatDiagonalScaleLocal"
5155 /*@
5156    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
5157          ghosted ones.
5158 
5159    Not Collective
5160 
5161    Input Parameters:
5162 +  mat - the matrix
5163 -  diag = the diagonal values, including ghost ones
5164 
5165    Level: developer
5166 
5167    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5168 
5169 .seealso: MatDiagonalScale()
5170 @*/
5171 int MatDiagonalScaleLocal(Mat mat,Vec diag)
5172 {
5173   int        ierr,size;
5174 
5175   PetscFunctionBegin;
5176   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5177   PetscValidHeaderSpecific(diag,VEC_COOKIE);
5178   PetscValidType(mat);
5179 
5180   if (!mat->assembled) {
5181     SETERRQ(1,"Matrix must be already assembled");
5182   }
5183   ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5184   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
5185   if (size == 1) {
5186     int n,m;
5187     ierr = VecGetSize(diag,&n);CHKERRQ(ierr);
5188     ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr);
5189     if (m == n) {
5190       ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr);
5191     } else {
5192       SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions");
5193     }
5194   } else {
5195     int (*f)(Mat,Vec);
5196     ierr = PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);CHKERRQ(ierr);
5197     if (f) {
5198       ierr = (*f)(mat,diag);CHKERRQ(ierr);
5199     } else {
5200       SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5201     }
5202   }
5203   ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr);
5204   ierr = PetscObjectIncreaseState((PetscObject)mat); CHKERRQ(ierr);
5205   PetscFunctionReturn(0);
5206 }
5207 
5208 #undef __FUNCT__
5209 #define __FUNCT__ "MatGetInertia"
5210 /*@
5211    MatGetInertia - Gets the inertia from a factored matrix
5212 
5213    Collective on Mat
5214 
5215    Input Parameter:
5216 .  mat - the matrix
5217 
5218    Output Parameters:
5219 +   nneg - number of negative eigenvalues
5220 .   nzero - number of zero eigenvalues
5221 -   npos - number of positive eigenvalues
5222 
5223    Level: advanced
5224 
5225    Notes: Matrix must have been factored by MatCholeskyFactor()
5226 
5227 
5228 @*/
5229 int MatGetInertia(Mat mat,int *nneg,int *nzero,int *npos)
5230 {
5231   int        ierr;
5232 
5233   PetscFunctionBegin;
5234   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5235   PetscValidType(mat);
5236   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5237   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5238   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5239   ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr);
5240   PetscFunctionReturn(0);
5241 }
5242 
5243 /* ----------------------------------------------------------------*/
5244 #undef __FUNCT__
5245 #define __FUNCT__ "MatSolves"
5246 /*@
5247    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
5248 
5249    Collective on Mat and Vecs
5250 
5251    Input Parameters:
5252 +  mat - the factored matrix
5253 -  b - the right-hand-side vectors
5254 
5255    Output Parameter:
5256 .  x - the result vectors
5257 
5258    Notes:
5259    The vectors b and x cannot be the same.  I.e., one cannot
5260    call MatSolves(A,x,x).
5261 
5262    Notes:
5263    Most users should employ the simplified KSP interface for linear solvers
5264    instead of working directly with matrix algebra routines such as this.
5265    See, e.g., KSPCreate().
5266 
5267    Level: developer
5268 
5269    Concepts: matrices^triangular solves
5270 
5271 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
5272 @*/
5273 int MatSolves(Mat mat,Vecs b,Vecs x)
5274 {
5275   int ierr;
5276 
5277   PetscFunctionBegin;
5278   PetscValidHeaderSpecific(mat,MAT_COOKIE);
5279   PetscValidType(mat);
5280   MatPreallocated(mat);
5281   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
5282   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5283   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
5284 
5285   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5286   ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5287   ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr);
5288   ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr);
5289   PetscFunctionReturn(0);
5290 }
5291 
5292 #undef __FUNCT__
5293 #define __FUNCT__ "MatIsSymmetric"
5294 /*@C
5295    MatIsSymmetric - Test whether a matrix is symmetric
5296 
5297    Collective on Mat
5298 
5299    Input Parameter:
5300 .  A - the matrix to test
5301 
5302    Output Parameters:
5303 .  flg - the result
5304 
5305    Level: intermediate
5306 
5307    Concepts: matrix^symmetry
5308 
5309 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption()
5310 @*/
5311 int MatIsSymmetric(Mat A,PetscTruth *flg)
5312 {
5313   int ierr;
5314 
5315   PetscFunctionBegin;
5316   PetscValidHeaderSpecific(A,MAT_COOKIE);
5317   if (!A->symmetric_set) {
5318     if (!A->ops->issymmetric) {
5319       MatType mattype;
5320       ierr = MatGetType(A,&mattype); CHKERRQ(ierr);
5321       SETERRQ1(1,"Matrix of type <%s> does not support checking for symmetric",
5322 	       mattype);
5323     }
5324     ierr = (*A->ops->issymmetric)(A,&A->symmetric); CHKERRQ(ierr);
5325     A->symmetric_set = PETSC_TRUE;
5326     if (A->symmetric) {
5327       A->structurally_symmetric_set = PETSC_TRUE;
5328       A->structurally_symmetric     = PETSC_TRUE;
5329     }
5330   }
5331   *flg = A->symmetric;
5332   PetscFunctionReturn(0);
5333 }
5334 
5335 #undef __FUNCT__
5336 #define __FUNCT__ "MatIsStructurallySymmetric"
5337 /*@C
5338    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
5339 
5340    Collective on Mat
5341 
5342    Input Parameter:
5343 .  A - the matrix to test
5344 
5345    Output Parameters:
5346 .  flg - the result
5347 
5348    Level: intermediate
5349 
5350    Concepts: matrix^symmetry
5351 
5352 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
5353 @*/
5354 int MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
5355 {
5356   int ierr;
5357 
5358   PetscFunctionBegin;
5359   PetscValidHeaderSpecific(A,MAT_COOKIE);
5360   if (!A->structurally_symmetric_set) {
5361     if (!A->ops->isstructurallysymmetric) SETERRQ(1,"Matrix does not support checking for structural symmetric");
5362     ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr);
5363     A->structurally_symmetric_set = PETSC_TRUE;
5364   }
5365   *flg = A->structurally_symmetric;
5366   PetscFunctionReturn(0);
5367 }
5368 
5369 #undef __FUNCT__
5370 #define __FUNCT__ "MatIsHermitian"
5371 /*@C
5372    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.
5373 
5374    Collective on Mat
5375 
5376    Input Parameter:
5377 .  A - the matrix to test
5378 
5379    Output Parameters:
5380 .  flg - the result
5381 
5382    Level: intermediate
5383 
5384    Concepts: matrix^symmetry
5385 
5386 .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
5387 @*/
5388 int MatIsHermitian(Mat A,PetscTruth *flg)
5389 {
5390   int ierr;
5391 
5392   PetscFunctionBegin;
5393   PetscValidHeaderSpecific(A,MAT_COOKIE);
5394   if (!A->hermitian_set) {
5395     if (!A->ops->ishermitian) SETERRQ(1,"Matrix does not support checking for being Hermitian");
5396     ierr = (*A->ops->ishermitian)(A,&A->hermitian);CHKERRQ(ierr);
5397     A->hermitian_set = PETSC_TRUE;
5398     if (A->hermitian) {
5399       A->structurally_symmetric_set = PETSC_TRUE;
5400       A->structurally_symmetric     = PETSC_TRUE;
5401     }
5402   }
5403   *flg = A->hermitian;
5404   PetscFunctionReturn(0);
5405 }
5406