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