xref: /petsc/src/mat/interface/matrix.c (revision 0f5bd95cca42d693ada6d048329ab39533680180)
1 #ifdef PETSC_RCS_HEADER
2 static char vcid[] = "$Id: matrix.c,v 1.348 1999/10/01 21:21:09 bsmith Exp bsmith $";
3 #endif
4 
5 /*
6    This is where the abstract matrix operations are defined
7 */
8 
9 #include "src/mat/matimpl.h"        /*I "mat.h" I*/
10 #include "src/vec/vecimpl.h"
11 
12 #undef __FUNC__
13 #define __FUNC__ "MatGetRow"
14 /*@C
15    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
16    for each row that you get to ensure that your application does
17    not bleed memory.
18 
19    Not Collective
20 
21    Input Parameters:
22 +  mat - the matrix
23 -  row - the row to get
24 
25    Output Parameters:
26 +  ncols -  the number of nonzeros in the row
27 .  cols - if nonzero, the column numbers
28 -  vals - if nonzero, the values
29 
30    Notes:
31    This routine is provided for people who need to have direct access
32    to the structure of a matrix.  We hope that we provide enough
33    high-level matrix routines that few users will need it.
34 
35    MatGetRow() always returns 0-based column indices, regardless of
36    whether the internal representation is 0-based (default) or 1-based.
37 
38    For better efficiency, set cols and/or vals to PETSC_NULL if you do
39    not wish to extract these quantities.
40 
41    The user can only examine the values extracted with MatGetRow();
42    the values cannot be altered.  To change the matrix entries, one
43    must use MatSetValues().
44 
45    You can only have one call to MatGetRow() outstanding for a particular
46    matrix at a time.
47 
48    Fortran Notes:
49    The calling sequence from Fortran is
50 .vb
51    MatGetRow(matrix,row,ncols,cols,values,ierr)
52          Mat     matrix (input)
53          integer row    (input)
54          integer ncols  (output)
55          integer cols(maxcols) (output)
56          double precision (or double complex) values(maxcols) output
57 .ve
58    where maxcols >= maximum nonzeros in any row of the matrix.
59 
60    Caution:
61    Do not try to change the contents of the output arrays (cols and vals).
62    In some cases, this may corrupt the matrix.
63 
64    Level: advanced
65 
66 .keywords: matrix, row, get, extract
67 
68 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubmatrices(), MatGetDiagonal()
69 @*/
70 int MatGetRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
71 {
72   int   ierr;
73 
74   PetscFunctionBegin;
75   PetscValidHeaderSpecific(mat,MAT_COOKIE);
76   PetscValidIntPointer(ncols);
77   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
78   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
79   if (!mat->ops->getrow) SETERRQ(PETSC_ERR_SUP,0,"");
80   PLogEventBegin(MAT_GetRow,mat,0,0,0);
81   ierr = (*mat->ops->getrow)(mat,row,ncols,cols,vals);CHKERRQ(ierr);
82   PLogEventEnd(MAT_GetRow,mat,0,0,0);
83   PetscFunctionReturn(0);
84 }
85 
86 #undef __FUNC__
87 #define __FUNC__ "MatRestoreRow"
88 /*@C
89    MatRestoreRow - Frees any temporary space allocated by MatGetRow().
90 
91    Not Collective
92 
93    Input Parameters:
94 +  mat - the matrix
95 .  row - the row to get
96 .  ncols, cols - the number of nonzeros and their columns
97 -  vals - if nonzero the column values
98 
99    Notes:
100    This routine should be called after you have finished examining the entries.
101 
102    Fortran Notes:
103    The calling sequence from Fortran is
104 .vb
105    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
106       Mat     matrix (input)
107       integer row    (input)
108       integer ncols  (output)
109       integer cols(maxcols) (output)
110       double precision (or double complex) values(maxcols) output
111 .ve
112    Where maxcols >= maximum nonzeros in any row of the matrix.
113 
114    In Fortran MatRestoreRow() MUST be called after MatGetRow()
115    before another call to MatGetRow() can be made.
116 
117    Level: advanced
118 
119 .keywords: matrix, row, restore
120 
121 .seealso:  MatGetRow()
122 @*/
123 int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,Scalar **vals)
124 {
125   int ierr;
126 
127   PetscFunctionBegin;
128   PetscValidHeaderSpecific(mat,MAT_COOKIE);
129   PetscValidIntPointer(ncols);
130   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
131   if (!mat->ops->restorerow) PetscFunctionReturn(0);
132   ierr = (*mat->ops->restorerow)(mat,row,ncols,cols,vals);CHKERRQ(ierr);
133   PetscFunctionReturn(0);
134 }
135 
136 #undef __FUNC__
137 #define __FUNC__ "MatView"
138 /*@C
139    MatView - Visualizes a matrix object.
140 
141    Collective on Mat unless Viewer is VIEWER_STDOUT_SELF
142 
143    Input Parameters:
144 +  mat - the matrix
145 -  ptr - visualization context
146 
147   Notes:
148   The available visualization contexts include
149 +    VIEWER_STDOUT_SELF - standard output (default)
150 .    VIEWER_STDOUT_WORLD - synchronized standard
151         output where only the first processor opens
152         the file.  All other processors send their
153         data to the first processor to print.
154 -     VIEWER_DRAW_WORLD - graphical display of nonzero structure
155 
156    The user can open alternative visualization contexts with
157 +    ViewerASCIIOpen() - Outputs matrix to a specified file
158 .    ViewerBinaryOpen() - Outputs matrix in binary to a
159          specified file; corresponding input uses MatLoad()
160 .    ViewerDrawOpen() - Outputs nonzero matrix structure to
161          an X window display
162 -    ViewerSocketOpen() - Outputs matrix to Socket viewer.
163          Currently only the sequential dense and AIJ
164          matrix types support the Socket viewer.
165 
166    The user can call ViewerSetFormat() to specify the output
167    format of ASCII printed objects (when using VIEWER_STDOUT_SELF,
168    VIEWER_STDOUT_WORLD and ViewerASCIIOpen).  Available formats include
169 +    VIEWER_FORMAT_ASCII_DEFAULT - default, prints matrix contents
170 .    VIEWER_FORMAT_ASCII_MATLAB - prints matrix contents in Matlab format
171 .    VIEWER_FORMAT_ASCII_DENSE - prints entire matrix including zeros
172 .    VIEWER_FORMAT_ASCII_COMMON - prints matrix contents, using a sparse
173          format common among all matrix types
174 .    VIEWER_FORMAT_ASCII_IMPL - prints matrix contents, using an implementation-specific
175          format (which is in many cases the same as the default)
176 .    VIEWER_FORMAT_ASCII_INFO - prints basic information about the matrix
177          size and structure (not the matrix entries)
178 -    VIEWER_FORMAT_ASCII_INFO_LONG - prints more detailed information about
179          the matrix structure
180 
181    Level: beginner
182 
183 .keywords: matrix, view, visualize, output, print, write, draw
184 
185 .seealso: ViewerSetFormat(), ViewerASCIIOpen(), ViewerDrawOpen(),
186           ViewerSocketOpen(), ViewerBinaryOpen(), MatLoad()
187 @*/
188 int MatView(Mat mat,Viewer viewer)
189 {
190   int          format, ierr, rows, cols;
191   int          isascii;
192   char         *cstr;
193 
194   PetscFunctionBegin;
195   PetscValidHeaderSpecific(mat,MAT_COOKIE);
196   if (!viewer) {
197     viewer = VIEWER_STDOUT_SELF;
198   }
199   PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
200 
201   isascii = PetscTypeCompare(viewer,ASCII_VIEWER);
202   if (isascii) {
203     ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr);
204     if (format == VIEWER_FORMAT_ASCII_INFO || format == VIEWER_FORMAT_ASCII_INFO_LONG) {
205       ierr = ViewerASCIIPrintf(viewer,"Matrix Object:\n");CHKERRQ(ierr);
206       ierr = MatGetType(mat,PETSC_NULL,&cstr);CHKERRQ(ierr);
207       ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
208       ierr = ViewerASCIIPrintf(viewer,"  type=%s, rows=%d, cols=%d\n",cstr,rows,cols);CHKERRQ(ierr);
209       if (mat->ops->getinfo) {
210         MatInfo info;
211         ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
212         ierr = ViewerASCIIPrintf(viewer,"  total: nonzeros=%d, allocated nonzeros=%d\n",
213                           (int)info.nz_used,(int)info.nz_allocated);CHKERRQ(ierr);
214       }
215     }
216   }
217   if (mat->ops->view) {
218     ierr = ViewerASCIIPushTab(viewer);CHKERRQ(ierr);
219     ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);
220     ierr = ViewerASCIIPopTab(viewer);CHKERRQ(ierr);
221   } else if (!isascii) {
222     SETERRQ1(1,1,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
223   }
224   PetscFunctionReturn(0);
225 }
226 
227 #undef __FUNC__
228 #define __FUNC__ "MatScaleSystem"
229 /*@C
230    MatScaleSystem - Scale a vector solution and right hand side to
231    match the scaling of a scaled matrix.
232 
233    Collective on Mat
234 
235    Input Parameter:
236 +  mat - the matrix
237 .  x - solution vector (or PETSC_NULL)
238 +  b - right hand side vector (or PETSC_NULL)
239 
240 
241    Notes:
242    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not
243    internally scaled, so this does nothing. For MPIROWBS it
244    permutes and diagonally scales.
245 
246    The SLES methods automatically call this routine when required
247    (via PCPreSolve()) so it is rarely used directly.
248 
249    Level: Developer
250 
251 .keywords: matrix, scale
252 
253 .seealso: MatUseScaledForm(), MatUnScaleSystem()
254 @*/
255 int MatScaleSystem(Mat mat,Vec x,Vec b)
256 {
257   int ierr;
258 
259   PetscFunctionBegin;
260   PetscValidHeaderSpecific(mat,MAT_COOKIE);
261   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
262   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);}
263 
264   if (mat->ops->scalesystem) {
265     ierr = (*mat->ops->scalesystem)(mat,x,b);CHKERRQ(ierr);
266   }
267   PetscFunctionReturn(0);
268 }
269 
270 #undef __FUNC__
271 #define __FUNC__ "MatUnScaleSystem"
272 /*@C
273    MatUnScaleSystem - Unscales a vector solution and right hand side to
274    match the original 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 .keywords: matrix, scale
295 
296 .seealso: MatUseScaledForm(), MatScaleSystem()
297 @*/
298 int MatUnScaleSystem(Mat mat,Vec x,Vec b)
299 {
300   int ierr;
301 
302   PetscFunctionBegin;
303   PetscValidHeaderSpecific(mat,MAT_COOKIE);
304   if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);}
305   if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,x);}
306   if (mat->ops->unscalesystem) {
307     ierr = (*mat->ops->unscalesystem)(mat,x,b);CHKERRQ(ierr);
308   }
309   PetscFunctionReturn(0);
310 }
311 
312 #undef __FUNC__
313 #define __FUNC__ "MatUseScaledForm"
314 /*@C
315    MatUseScaledForm - For matrix storage formats that scale the
316    matrix (for example MPIRowBS matrices are diagonally scaled on
317    assembly) indicates matrix operations (MatMult() etc) are
318    applied using the scaled matrix.
319 
320    Collective on Mat
321 
322    Input Parameter:
323 +  mat - the matrix
324 -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for
325             applying the original matrix
326 
327    Notes:
328    For scaled matrix formats, applying the original, unscaled matrix
329    will be slightly more expensive
330 
331    Level: Developer
332 
333 .keywords: matrix, scale
334 
335 .seealso: MatScaleSystem(), MatUnScaleSystem()
336 @*/
337 int MatUseScaledForm(Mat mat,PetscTruth scaled)
338 {
339   int ierr;
340 
341   PetscFunctionBegin;
342   PetscValidHeaderSpecific(mat,MAT_COOKIE);
343   if (mat->ops->usescaledform) {
344     ierr = (*mat->ops->usescaledform)(mat,scaled);CHKERRQ(ierr);
345   }
346   PetscFunctionReturn(0);
347 }
348 
349 #undef __FUNC__
350 #define __FUNC__ "MatDestroy"
351 /*@C
352    MatDestroy - Frees space taken by a matrix.
353 
354    Collective on Mat
355 
356    Input Parameter:
357 .  mat - the matrix
358 
359    Level: beginner
360 
361 .keywords: matrix, destroy
362 @*/
363 int MatDestroy(Mat mat)
364 {
365   int ierr;
366 
367   PetscFunctionBegin;
368   PetscValidHeaderSpecific(mat,MAT_COOKIE);
369   if (--mat->refct > 0) PetscFunctionReturn(0);
370 
371   /* if memory was published with AMS then destroy it */
372   ierr = PetscObjectDepublish(mat);CHKERRQ(ierr);
373 
374   ierr = (*mat->ops->destroy)(mat);CHKERRQ(ierr);
375   PetscFunctionReturn(0);
376 }
377 
378 #undef __FUNC__
379 #define __FUNC__ "MatValid"
380 /*@
381    MatValid - Checks whether a matrix object is valid.
382 
383    Collective on Mat
384 
385    Input Parameter:
386 .  m - the matrix to check
387 
388    Output Parameter:
389    flg - flag indicating matrix status, either
390    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.
391 
392    Level: developer
393 
394 .keywords: matrix, valid
395 @*/
396 int MatValid(Mat m,PetscTruth *flg)
397 {
398   PetscFunctionBegin;
399   PetscValidIntPointer(flg);
400   if (!m)                           *flg = PETSC_FALSE;
401   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
402   else                              *flg = PETSC_TRUE;
403   PetscFunctionReturn(0);
404 }
405 
406 #undef __FUNC__
407 #define __FUNC__ "MatSetValues"
408 /*@
409    MatSetValues - Inserts or adds a block of values into a matrix.
410    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
411    MUST be called after all calls to MatSetValues() have been completed.
412 
413    Not Collective
414 
415    Input Parameters:
416 +  mat - the matrix
417 .  v - a logically two-dimensional array of values
418 .  m, idxm - the number of rows and their global indices
419 .  n, idxn - the number of columns and their global indices
420 -  addv - either ADD_VALUES or INSERT_VALUES, where
421    ADD_VALUES adds values to any existing entries, and
422    INSERT_VALUES replaces existing entries with new values
423 
424    Notes:
425    By default the values, v, are row-oriented and unsorted.
426    See MatSetOption() for other options.
427 
428    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
429    options cannot be mixed without intervening calls to the assembly
430    routines.
431 
432    MatSetValues() uses 0-based row and column numbers in Fortran
433    as well as in C.
434 
435    Negative indices may be passed in idxm and idxn, these rows and columns are
436    simply ignored. This allows easily inserting element stiffness matrices
437    with homogeneous Dirchlet boundary conditions that you don't want represented
438    in the matrix.
439 
440    Efficiency Alert:
441    The routine MatSetValuesBlocked() may offer much better efficiency
442    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
443 
444    Level: beginner
445 
446 .keywords: matrix, insert, add, set, values
447 
448 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
449 @*/
450 int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,InsertMode addv)
451 {
452   int ierr;
453 
454   PetscFunctionBegin;
455   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
456   PetscValidHeaderSpecific(mat,MAT_COOKIE);
457   PetscValidIntPointer(idxm);
458   PetscValidIntPointer(idxn);
459   PetscValidScalarPointer(v);
460   if (mat->insertmode == NOT_SET_VALUES) {
461     mat->insertmode = addv;
462   }
463 #if defined(PETSC_USE_BOPT_g)
464   else if (mat->insertmode != addv) {
465     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
466   }
467   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
468 #endif
469 
470   if (mat->assembled) {
471     mat->was_assembled = PETSC_TRUE;
472     mat->assembled     = PETSC_FALSE;
473   }
474   PLogEventBegin(MAT_SetValues,mat,0,0,0);
475   if (!mat->ops->setvalues) SETERRQ(PETSC_ERR_SUP,1,"Not supported for this matrix type");
476   ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
477   PLogEventEnd(MAT_SetValues,mat,0,0,0);
478   PetscFunctionReturn(0);
479 }
480 
481 #undef __FUNC__
482 #define __FUNC__ "MatSetValuesBlocked"
483 /*@
484    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
485 
486    Not Collective
487 
488    Input Parameters:
489 +  mat - the matrix
490 .  v - a logically two-dimensional array of values
491 .  m, idxm - the number of block rows and their global block indices
492 .  n, idxn - the number of block columns and their global block indices
493 -  addv - either ADD_VALUES or INSERT_VALUES, where
494    ADD_VALUES adds values to any existing entries, and
495    INSERT_VALUES replaces existing entries with new values
496 
497    Notes:
498    By default the values, v, are row-oriented and unsorted. So the layout of
499    v is the same as for MatSetValues(). See MatSetOption() for other options.
500 
501    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
502    options cannot be mixed without intervening calls to the assembly
503    routines.
504 
505    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
506    as well as in C.
507 
508    Negative indices may be passed in idxm and idxn, these rows and columns are
509    simply ignored. This allows easily inserting element stiffness matrices
510    with homogeneous Dirchlet boundary conditions that you don't want represented
511    in the matrix.
512 
513    Each time an entry is set within a sparse matrix via MatSetValues(),
514    internal searching must be done to determine where to place the the
515    data in the matrix storage space.  By instead inserting blocks of
516    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
517    reduced.
518 
519    Restrictions:
520    MatSetValuesBlocked() is currently supported only for the block AIJ
521    matrix format (MATSEQBAIJ and MATMPIBAIJ, which are created via
522    MatCreateSeqBAIJ() and MatCreateMPIBAIJ()).
523 
524    Level: intermediate
525 
526 .keywords: matrix, insert, add, set, values
527 
528 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
529 @*/
530 int MatSetValuesBlocked(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,InsertMode addv)
531 {
532   int ierr;
533 
534   PetscFunctionBegin;
535   if (!m || !n) PetscFunctionReturn(0); /* no values to insert */
536   PetscValidHeaderSpecific(mat,MAT_COOKIE);
537   PetscValidIntPointer(idxm);
538   PetscValidIntPointer(idxn);
539   PetscValidScalarPointer(v);
540   if (mat->insertmode == NOT_SET_VALUES) {
541     mat->insertmode = addv;
542   }
543 #if defined(PETSC_USE_BOPT_g)
544   else if (mat->insertmode != addv) {
545     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
546   }
547   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
548 #endif
549 
550   if (mat->assembled) {
551     mat->was_assembled = PETSC_TRUE;
552     mat->assembled     = PETSC_FALSE;
553   }
554   PLogEventBegin(MAT_SetValues,mat,0,0,0);
555   if (!mat->ops->setvaluesblocked) SETERRQ(PETSC_ERR_SUP,1,"Not supported for this matrix type");
556   ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr);
557   PLogEventEnd(MAT_SetValues,mat,0,0,0);
558   PetscFunctionReturn(0);
559 }
560 
561 /*MC
562    MatSetValue - Set a single entry into a matrix.
563 
564    Synopsis:
565    void MatSetValue(Mat m,int row,int col,Scalar value,InsertMode mode);
566 
567    Not collective
568 
569    Input Parameters:
570 +  m - the matrix
571 .  row - the row location of the entry
572 .  col - the column location of the entry
573 .  value - the value to insert
574 -  mode - either INSERT_VALUES or ADD_VALUES
575 
576    Notes:
577    For efficiency one should use MatSetValues() and set several or many
578    values simultaneously if possible.
579 
580    Note that VecSetValue() does NOT return an error code (since this
581    is checked internally).
582 
583    Level: beginner
584 
585 .seealso: MatSetValues()
586 M*/
587 
588 #undef __FUNC__
589 #define __FUNC__ "MatGetValues"
590 /*@
591    MatGetValues - Gets a block of values from a matrix.
592 
593    Not Collective; currently only returns a local block
594 
595    Input Parameters:
596 +  mat - the matrix
597 .  v - a logically two-dimensional array for storing the values
598 .  m, idxm - the number of rows and their global indices
599 -  n, idxn - the number of columns and their global indices
600 
601    Notes:
602    The user must allocate space (m*n Scalars) for the values, v.
603    The values, v, are then returned in a row-oriented format,
604    analogous to that used by default in MatSetValues().
605 
606    MatGetValues() uses 0-based row and column numbers in
607    Fortran as well as in C.
608 
609    MatGetValues() requires that the matrix has been assembled
610    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
611    MatSetValues() and MatGetValues() CANNOT be made in succession
612    without intermediate matrix assembly.
613 
614    Level: advanced
615 
616 .keywords: matrix, get, values
617 
618 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
619 @*/
620 int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v)
621 {
622   int ierr;
623 
624   PetscFunctionBegin;
625   PetscValidHeaderSpecific(mat,MAT_COOKIE);
626   PetscValidIntPointer(idxm);
627   PetscValidIntPointer(idxn);
628   PetscValidScalarPointer(v);
629   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
630   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
631   if (!mat->ops->getvalues) SETERRQ(PETSC_ERR_SUP,0,"");
632 
633   PLogEventBegin(MAT_GetValues,mat,0,0,0);
634   ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr);
635   PLogEventEnd(MAT_GetValues,mat,0,0,0);
636   PetscFunctionReturn(0);
637 }
638 
639 #undef __FUNC__
640 #define __FUNC__ "MatSetLocalToGlobalMapping"
641 /*@
642    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
643    the routine MatSetValuesLocal() to allow users to insert matrix entries
644    using a local (per-processor) numbering.
645 
646    Not Collective
647 
648    Input Parameters:
649 +  x - the matrix
650 -  mapping - mapping created with ISLocalToGlobalMappingCreate()
651              or ISLocalToGlobalMappingCreateIS()
652 
653    Level: intermediate
654 
655 .keywords: matrix, set, values, local, global, mapping
656 
657 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
658 @*/
659 int MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
660 {
661   PetscFunctionBegin;
662   PetscValidHeaderSpecific(x,MAT_COOKIE);
663   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
664   if (x->mapping) {
665     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Mapping already set for matrix");
666   }
667 
668   x->mapping = mapping;
669   PetscObjectReference((PetscObject)mapping);
670   PetscFunctionReturn(0);
671 }
672 
673 #undef __FUNC__
674 #define __FUNC__ "MatSetLocalToGlobalMappingBlock"
675 /*@
676    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
677    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
678    entries using a local (per-processor) numbering.
679 
680    Not Collective
681 
682    Input Parameters:
683 +  x - the matrix
684 -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
685              ISLocalToGlobalMappingCreateIS()
686 
687    Level: intermediate
688 
689 .keywords: matrix, set, values, local ordering
690 
691 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
692            MatSetValuesBlocked(), MatSetValuesLocal()
693 @*/
694 int MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
695 {
696   PetscFunctionBegin;
697   PetscValidHeaderSpecific(x,MAT_COOKIE);
698   PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE);
699   if (x->bmapping) {
700     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Mapping already set for matrix");
701   }
702 
703   x->bmapping = mapping;
704   PetscObjectReference((PetscObject)mapping);
705   PetscFunctionReturn(0);
706 }
707 
708 #undef __FUNC__
709 #define __FUNC__ "MatSetValuesLocal"
710 /*@
711    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
712    using a local ordering of the nodes.
713 
714    Not Collective
715 
716    Input Parameters:
717 +  x - the matrix
718 .  nrow, irow - number of rows and their local indices
719 .  ncol, icol - number of columns and their local indices
720 .  y -  a logically two-dimensional array of values
721 -  addv - either INSERT_VALUES or ADD_VALUES, where
722    ADD_VALUES adds values to any existing entries, and
723    INSERT_VALUES replaces existing entries with new values
724 
725    Notes:
726    Before calling MatSetValuesLocal(), the user must first set the
727    local-to-global mapping by calling MatSetLocalToGlobalMapping().
728 
729    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
730    options cannot be mixed without intervening calls to the assembly
731    routines.
732 
733    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
734    MUST be called after all calls to MatSetValuesLocal() have been completed.
735 
736    Level: intermediate
737 
738 .keywords: matrix, set, values, local ordering
739 
740 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping()
741 @*/
742 int MatSetValuesLocal(Mat mat,int nrow,int *irow,int ncol, int *icol,Scalar *y,InsertMode addv)
743 {
744   int ierr,irowm[2048],icolm[2048];
745 
746   PetscFunctionBegin;
747   PetscValidHeaderSpecific(mat,MAT_COOKIE);
748   PetscValidIntPointer(irow);
749   PetscValidIntPointer(icol);
750   PetscValidScalarPointer(y);
751 
752   if (mat->insertmode == NOT_SET_VALUES) {
753     mat->insertmode = addv;
754   }
755 #if defined(PETSC_USE_BOPT_g)
756   else if (mat->insertmode != addv) {
757     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
758   }
759   if (!mat->mapping) {
760     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Local to global never set with MatSetLocalToGlobalMapping()");
761   }
762   if (nrow > 2048 || ncol > 2048) {
763     SETERRQ2(PETSC_ERR_SUP,0,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
764   }
765   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
766 #endif
767 
768   if (mat->assembled) {
769     mat->was_assembled = PETSC_TRUE;
770     mat->assembled     = PETSC_FALSE;
771   }
772   PLogEventBegin(MAT_SetValues,mat,0,0,0);
773   ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr);
774   ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr);
775   ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
776   PLogEventEnd(MAT_SetValues,mat,0,0,0);
777   PetscFunctionReturn(0);
778 }
779 
780 #undef __FUNC__
781 #define __FUNC__ "MatSetValuesBlockedLocal"
782 /*@
783    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
784    using a local ordering of the nodes a block at a time.
785 
786    Not Collective
787 
788    Input Parameters:
789 +  x - the matrix
790 .  nrow, irow - number of rows and their local indices
791 .  ncol, icol - number of columns and their local indices
792 .  y -  a logically two-dimensional array of values
793 -  addv - either INSERT_VALUES or ADD_VALUES, where
794    ADD_VALUES adds values to any existing entries, and
795    INSERT_VALUES replaces existing entries with new values
796 
797    Notes:
798    Before calling MatSetValuesBlockedLocal(), the user must first set the
799    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
800    where the mapping MUST be set for matrix blocks, not for matrix elements.
801 
802    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
803    options cannot be mixed without intervening calls to the assembly
804    routines.
805 
806    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
807    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
808 
809    Level: intermediate
810 
811 .keywords: matrix, set, values, blocked, local
812 
813 .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
814 @*/
815 int MatSetValuesBlockedLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,Scalar *y,InsertMode addv)
816 {
817   int ierr,irowm[2048],icolm[2048];
818 
819   PetscFunctionBegin;
820   PetscValidHeaderSpecific(mat,MAT_COOKIE);
821   PetscValidIntPointer(irow);
822   PetscValidIntPointer(icol);
823   PetscValidScalarPointer(y);
824   if (mat->insertmode == NOT_SET_VALUES) {
825     mat->insertmode = addv;
826   }
827 #if defined(PETSC_USE_BOPT_g)
828   else if (mat->insertmode != addv) {
829     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Cannot mix add values and insert values");
830   }
831   if (!mat->bmapping) {
832     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
833   }
834   if (nrow > 2048 || ncol > 2048) {
835     SETERRQ2(PETSC_ERR_SUP,0,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
836   }
837   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
838 #endif
839 
840   if (mat->assembled) {
841     mat->was_assembled = PETSC_TRUE;
842     mat->assembled     = PETSC_FALSE;
843   }
844   PLogEventBegin(MAT_SetValues,mat,0,0,0);
845   ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr);
846   ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr);
847   ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr);
848   PLogEventEnd(MAT_SetValues,mat,0,0,0);
849   PetscFunctionReturn(0);
850 }
851 
852 /* --------------------------------------------------------*/
853 #undef __FUNC__
854 #define __FUNC__ "MatMult"
855 /*@
856    MatMult - Computes the matrix-vector product, y = Ax.
857 
858    Collective on Mat and Vec
859 
860    Input Parameters:
861 +  mat - the matrix
862 -  x   - the vector to be multilplied
863 
864    Output Parameters:
865 .  y - the result
866 
867    Notes:
868    The vectors x and y cannot be the same.  I.e., one cannot
869    call MatMult(A,y,y).
870 
871    Level: beginner
872 
873 .keywords: matrix, multiply, matrix-vector product
874 
875 .seealso: MatMultTrans(), MatMultAdd(), MatMultTransAdd()
876 @*/
877 int MatMult(Mat mat,Vec x,Vec y)
878 {
879   int ierr;
880 
881   PetscFunctionBegin;
882   PetscValidHeaderSpecific(mat,MAT_COOKIE);
883   PetscValidHeaderSpecific(x,VEC_COOKIE);
884   PetscValidHeaderSpecific(y,VEC_COOKIE);
885   PetscCheckSameComm(mat,x);
886   PetscCheckSameComm(mat,y);
887   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
888   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
889   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"x and y must be different vectors");
890   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
891   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
892   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
893 
894   PLogEventBegin(MAT_Mult,mat,x,y,0);
895   ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr);
896   PLogEventEnd(MAT_Mult,mat,x,y,0);
897 
898   PetscFunctionReturn(0);
899 }
900 
901 #undef __FUNC__
902 #define __FUNC__ "MatMultTrans"
903 /*@
904    MatMultTrans - Computes matrix transpose times a vector.
905 
906    Collective on Mat and Vec
907 
908    Input Parameters:
909 +  mat - the matrix
910 -  x   - the vector to be multilplied
911 
912    Output Parameters:
913 .  y - the result
914 
915    Notes:
916    The vectors x and y cannot be the same.  I.e., one cannot
917    call MatMultTrans(A,y,y).
918 
919    Level: beginner
920 
921 .keywords: matrix, multiply, matrix-vector product, transpose
922 
923 .seealso: MatMult(), MatMultAdd(), MatMultTransAdd()
924 @*/
925 int MatMultTrans(Mat mat,Vec x,Vec y)
926 {
927   int ierr;
928 
929   PetscFunctionBegin;
930   PetscValidHeaderSpecific(mat,MAT_COOKIE);
931   PetscValidHeaderSpecific(x,VEC_COOKIE);
932   PetscValidHeaderSpecific(y,VEC_COOKIE);
933   PetscCheckSameComm(mat,x);
934   PetscCheckSameComm(mat,y);
935   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
936   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
937   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"x and y must be different vectors");
938   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
939   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
940 
941   PLogEventBegin(MAT_MultTrans,mat,x,y,0);
942   ierr = (*mat->ops->multtrans)(mat,x,y);CHKERRQ(ierr);
943   PLogEventEnd(MAT_MultTrans,mat,x,y,0);
944   PetscFunctionReturn(0);
945 }
946 
947 #undef __FUNC__
948 #define __FUNC__ "MatMultAdd"
949 /*@
950     MatMultAdd -  Computes v3 = v2 + A * v1.
951 
952     Collective on Mat and Vec
953 
954     Input Parameters:
955 +   mat - the matrix
956 -   v1, v2 - the vectors
957 
958     Output Parameters:
959 .   v3 - the result
960 
961     Notes:
962     The vectors v1 and v3 cannot be the same.  I.e., one cannot
963     call MatMultAdd(A,v1,v2,v1).
964 
965     Level: beginner
966 
967 .keywords: matrix, multiply, matrix-vector product, add
968 
969 .seealso: MatMultTrans(), MatMult(), MatMultTransAdd()
970 @*/
971 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
972 {
973   int ierr;
974 
975   PetscFunctionBegin;
976   PetscValidHeaderSpecific(mat,MAT_COOKIE);
977   PetscValidHeaderSpecific(v1,VEC_COOKIE);
978   PetscValidHeaderSpecific(v2,VEC_COOKIE);
979   PetscValidHeaderSpecific(v3,VEC_COOKIE);
980   PetscCheckSameComm(mat,v1);
981   PetscCheckSameComm(mat,v2);
982   PetscCheckSameComm(mat,v3);
983   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
984   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
985   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N);
986   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N);
987   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N);
988   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n);
989   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n);
990   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,0,"v1 and v3 must be different vectors");
991 
992   PLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
993   ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr);
994   PLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
995   PetscFunctionReturn(0);
996 }
997 
998 #undef __FUNC__
999 #define __FUNC__ "MatMultTransAdd"
1000 /*@
1001    MatMultTransAdd - Computes v3 = v2 + A' * v1.
1002 
1003    Collective on Mat and Vec
1004 
1005    Input Parameters:
1006 +  mat - the matrix
1007 -  v1, v2 - the vectors
1008 
1009    Output Parameters:
1010 .  v3 - the result
1011 
1012    Notes:
1013    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1014    call MatMultTransAdd(A,v1,v2,v1).
1015 
1016    Level: beginner
1017 
1018 .keywords: matrix, multiply, matrix-vector product, transpose, add
1019 
1020 .seealso: MatMultTrans(), MatMultAdd(), MatMult()
1021 @*/
1022 int MatMultTransAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1023 {
1024   int ierr;
1025 
1026   PetscFunctionBegin;
1027   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1028   PetscValidHeaderSpecific(v1,VEC_COOKIE);
1029   PetscValidHeaderSpecific(v2,VEC_COOKIE);
1030   PetscValidHeaderSpecific(v3,VEC_COOKIE);
1031   PetscCheckSameComm(mat,v1);
1032   PetscCheckSameComm(mat,v2);
1033   PetscCheckSameComm(mat,v3);
1034   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1035   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1036   if (!mat->ops->multtransadd) SETERRQ(PETSC_ERR_SUP,0,"");
1037   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,0,"v1 and v3 must be different vectors");
1038   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N);
1039   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N);
1040   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N);
1041 
1042   PLogEventBegin(MAT_MultTransAdd,mat,v1,v2,v3);
1043   ierr = (*mat->ops->multtransadd)(mat,v1,v2,v3);CHKERRQ(ierr);
1044   PLogEventEnd(MAT_MultTransAdd,mat,v1,v2,v3);
1045   PetscFunctionReturn(0);
1046 }
1047 /* ------------------------------------------------------------*/
1048 #undef __FUNC__
1049 #define __FUNC__ "MatGetInfo"
1050 /*@C
1051    MatGetInfo - Returns information about matrix storage (number of
1052    nonzeros, memory, etc.).
1053 
1054    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1055    as the flag
1056 
1057    Input Parameters:
1058 .  mat - the matrix
1059 
1060    Output Parameters:
1061 +  flag - flag indicating the type of parameters to be returned
1062    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1063    MAT_GLOBAL_SUM - sum over all processors)
1064 -  info - matrix information context
1065 
1066    Notes:
1067    The MatInfo context contains a variety of matrix data, including
1068    number of nonzeros allocated and used, number of mallocs during
1069    matrix assembly, etc.  Additional information for factored matrices
1070    is provided (such as the fill ratio, number of mallocs during
1071    factorization, etc.).  Much of this info is printed to STDOUT
1072    when using the runtime options
1073 $       -log_info -mat_view_info
1074 
1075    Example for C/C++ Users:
1076    See the file ${PETSC_DIR}/include/mat.h for a complete list of
1077    data within the MatInfo context.  For example,
1078 .vb
1079       MatInfo info;
1080       Mat     A;
1081       double  mal, nz_a, nz_u;
1082 
1083       MatGetInfo(A,MAT_LOCAL,&info);
1084       mal  = info.mallocs;
1085       nz_a = info.nz_allocated;
1086 .ve
1087 
1088    Example for Fortran Users:
1089    Fortran users should declare info as a double precision
1090    array of dimension MAT_INFO_SIZE, and then extract the parameters
1091    of interest.  See the file ${PETSC_DIR}/include/finclude/mat.h
1092    a complete list of parameter names.
1093 .vb
1094       double  precision info(MAT_INFO_SIZE)
1095       double  precision mal, nz_a
1096       Mat     A
1097       integer ierr
1098 
1099       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1100       mal = info(MAT_INFO_MALLOCS)
1101       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1102 .ve
1103 
1104     Level: intermediate
1105 
1106 .keywords: matrix, get, info, storage, nonzeros, memory, fill
1107 @*/
1108 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1109 {
1110   int ierr;
1111 
1112   PetscFunctionBegin;
1113   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1114   PetscValidPointer(info);
1115   if (!mat->ops->getinfo) SETERRQ(PETSC_ERR_SUP,0,"");
1116   ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr);
1117   PetscFunctionReturn(0);
1118 }
1119 
1120 /* ----------------------------------------------------------*/
1121 #undef __FUNC__
1122 #define __FUNC__ "MatILUDTFactor"
1123 /*@
1124    MatILUDTFactor - Performs a drop tolerance ILU factorization.
1125 
1126    Collective on Mat
1127 
1128    Input Parameters:
1129 +  mat - the matrix
1130 .  dt  - the drop tolerance
1131 .  maxnz - the maximum number of nonzeros per row allowed
1132 .  row - row permutation
1133 -  col - column permutation
1134 
1135    Output Parameters:
1136 .  fact - the factored matrix
1137 
1138    Notes:
1139    Most users should employ the simplified SLES interface for linear solvers
1140    instead of working directly with matrix algebra routines such as this.
1141    See, e.g., SLESCreate().
1142 
1143    Level: developer
1144 
1145 .keywords: matrix, factor, LU, in-place
1146 
1147 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
1148 @*/
1149 int MatILUDTFactor(Mat mat,double dt,int maxnz,IS row,IS col,Mat *fact)
1150 {
1151   int ierr;
1152 
1153   PetscFunctionBegin;
1154   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1155   PetscValidPointer(fact);
1156   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1157   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1158   if (!mat->ops->iludtfactor) SETERRQ(PETSC_ERR_SUP,0,"");
1159 
1160   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1161   ierr = (*mat->ops->iludtfactor)(mat,dt,maxnz,row,col,fact);CHKERRQ(ierr);
1162   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
1163 
1164   PetscFunctionReturn(0);
1165 }
1166 
1167 #undef __FUNC__
1168 #define __FUNC__ "MatLUFactor"
1169 /*@
1170    MatLUFactor - Performs in-place LU factorization of matrix.
1171 
1172    Collective on Mat
1173 
1174    Input Parameters:
1175 +  mat - the matrix
1176 .  row - row permutation
1177 .  col - column permutation
1178 -  f - expected fill as ratio of original fill.
1179 
1180    Notes:
1181    Most users should employ the simplified SLES interface for linear solvers
1182    instead of working directly with matrix algebra routines such as this.
1183    See, e.g., SLESCreate().
1184 
1185    Level: developer
1186 
1187 .keywords: matrix, factor, LU, in-place
1188 
1189 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1190           MatGetOrdering()
1191 
1192 @*/
1193 int MatLUFactor(Mat mat,IS row,IS col,double f)
1194 {
1195   int ierr;
1196 
1197   PetscFunctionBegin;
1198   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1199   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"matrix must be square");
1200   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1201   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1202   if (!mat->ops->lufactor) SETERRQ(PETSC_ERR_SUP,0,"");
1203 
1204   PLogEventBegin(MAT_LUFactor,mat,row,col,0);
1205   ierr = (*mat->ops->lufactor)(mat,row,col,f);CHKERRQ(ierr);
1206   PLogEventEnd(MAT_LUFactor,mat,row,col,0);
1207   PetscFunctionReturn(0);
1208 }
1209 
1210 #undef __FUNC__
1211 #define __FUNC__ "MatILUFactor"
1212 /*@
1213    MatILUFactor - Performs in-place ILU factorization of matrix.
1214 
1215    Collective on Mat
1216 
1217    Input Parameters:
1218 +  mat - the matrix
1219 .  row - row permutation
1220 .  col - column permutation
1221 -  info - structure containing
1222 $      levels - number of levels of fill.
1223 $      expected fill - as ratio of original fill.
1224 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1225                 missing diagonal entries)
1226 
1227    Notes:
1228    Probably really in-place only when level of fill is zero, otherwise allocates
1229    new space to store factored matrix and deletes previous memory.
1230 
1231    Most users should employ the simplified SLES interface for linear solvers
1232    instead of working directly with matrix algebra routines such as this.
1233    See, e.g., SLESCreate().
1234 
1235    Level: developer
1236 
1237 .keywords: matrix, factor, ILU, in-place
1238 
1239 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
1240 @*/
1241 int MatILUFactor(Mat mat,IS row,IS col,MatILUInfo *info)
1242 {
1243   int ierr;
1244 
1245   PetscFunctionBegin;
1246   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1247   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"matrix must be square");
1248   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1249   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1250   if (!mat->ops->ilufactor) SETERRQ(PETSC_ERR_SUP,0,"");
1251 
1252   PLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1253   ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr);
1254   PLogEventEnd(MAT_ILUFactor,mat,row,col,0);
1255   PetscFunctionReturn(0);
1256 }
1257 
1258 #undef __FUNC__
1259 #define __FUNC__ "MatLUFactorSymbolic"
1260 /*@
1261    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1262    Call this routine before calling MatLUFactorNumeric().
1263 
1264    Collective on Mat
1265 
1266    Input Parameters:
1267 +  mat - the matrix
1268 .  row, col - row and column permutations
1269 -  f - expected fill as ratio of the original number of nonzeros,
1270        for example 3.0; choosing this parameter well can result in
1271        more efficient use of time and space. Run with the option -log_info
1272        to determine an optimal value to use
1273 
1274    Output Parameter:
1275 .  fact - new matrix that has been symbolically factored
1276 
1277    Notes:
1278    See the users manual for additional information about
1279    choosing the fill factor for better efficiency.
1280 
1281    Most users should employ the simplified SLES interface for linear solvers
1282    instead of working directly with matrix algebra routines such as this.
1283    See, e.g., SLESCreate().
1284 
1285    Level: developer
1286 
1287 .keywords: matrix, factor, LU, symbolic, fill
1288 
1289 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor()
1290 @*/
1291 int MatLUFactorSymbolic(Mat mat,IS row,IS col,double f,Mat *fact)
1292 {
1293   int ierr;
1294 
1295   PetscFunctionBegin;
1296   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1297   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"matrix must be square");
1298   PetscValidPointer(fact);
1299   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1300   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1301   if (!mat->ops->lufactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"");
1302 
1303   PLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
1304   ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,f,fact);CHKERRQ(ierr);
1305   PLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
1306   PetscFunctionReturn(0);
1307 }
1308 
1309 #undef __FUNC__
1310 #define __FUNC__ "MatLUFactorNumeric"
1311 /*@
1312    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1313    Call this routine after first calling MatLUFactorSymbolic().
1314 
1315    Collective on Mat
1316 
1317    Input Parameters:
1318 +  mat - the matrix
1319 -  row, col - row and  column permutations
1320 
1321    Output Parameters:
1322 .  fact - symbolically factored matrix that must have been generated
1323           by MatLUFactorSymbolic()
1324 
1325    Notes:
1326    See MatLUFactor() for in-place factorization.  See
1327    MatCholeskyFactorNumeric() for the symmetric, positive definite case.
1328 
1329    Most users should employ the simplified SLES interface for linear solvers
1330    instead of working directly with matrix algebra routines such as this.
1331    See, e.g., SLESCreate().
1332 
1333    Level: developer
1334 
1335 .keywords: matrix, factor, LU, numeric
1336 
1337 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1338 @*/
1339 int MatLUFactorNumeric(Mat mat,Mat *fact)
1340 {
1341   int ierr,flg;
1342 
1343   PetscFunctionBegin;
1344   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1345   PetscValidPointer(fact);
1346   PetscValidHeaderSpecific(*fact,MAT_COOKIE);
1347   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1348   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1349     SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1350             mat->M,(*fact)->M,mat->N,(*fact)->N);
1351   }
1352   if (!(*fact)->ops->lufactornumeric) SETERRQ(PETSC_ERR_SUP,0,"");
1353 
1354   PLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);
1355   ierr = (*(*fact)->ops->lufactornumeric)(mat,fact);CHKERRQ(ierr);
1356   PLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);
1357   ierr = OptionsHasName(PETSC_NULL,"-mat_view_draw",&flg);CHKERRQ(ierr);
1358   if (flg) {
1359     ierr = OptionsHasName(PETSC_NULL,"-mat_view_contour",&flg);CHKERRQ(ierr);
1360     if (flg) {
1361       ViewerPushFormat(VIEWER_DRAW_(mat->comm),VIEWER_FORMAT_DRAW_CONTOUR,0);CHKERRQ(ierr);
1362     }
1363     ierr = MatView(*fact,VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1364     ierr = ViewerFlush(VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1365     if (flg) {
1366       ViewerPopFormat(VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
1367     }
1368   }
1369   PetscFunctionReturn(0);
1370 }
1371 
1372 #undef __FUNC__
1373 #define __FUNC__ "MatCholeskyFactor"
1374 /*@
1375    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1376    symmetric matrix.
1377 
1378    Collective on Mat
1379 
1380    Input Parameters:
1381 +  mat - the matrix
1382 .  perm - row and column permutations
1383 -  f - expected fill as ratio of original fill
1384 
1385    Notes:
1386    See MatLUFactor() for the nonsymmetric case.  See also
1387    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
1388 
1389    Most users should employ the simplified SLES interface for linear solvers
1390    instead of working directly with matrix algebra routines such as this.
1391    See, e.g., SLESCreate().
1392 
1393    Level: developer
1394 
1395 .keywords: matrix, factor, in-place, Cholesky
1396 
1397 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1398           MatGetOrdering()
1399 
1400 @*/
1401 int MatCholeskyFactor(Mat mat,IS perm,double f)
1402 {
1403   int ierr;
1404 
1405   PetscFunctionBegin;
1406   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1407   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Matrix must be square");
1408   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1409   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1410   if (!mat->ops->choleskyfactor) SETERRQ(PETSC_ERR_SUP,0,"");
1411 
1412   PLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
1413   ierr = (*mat->ops->choleskyfactor)(mat,perm,f);CHKERRQ(ierr);
1414   PLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
1415   PetscFunctionReturn(0);
1416 }
1417 
1418 #undef __FUNC__
1419 #define __FUNC__ "MatCholeskyFactorSymbolic"
1420 /*@
1421    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1422    of a symmetric matrix.
1423 
1424    Collective on Mat
1425 
1426    Input Parameters:
1427 +  mat - the matrix
1428 .  perm - row and column permutations
1429 -  f - expected fill as ratio of original
1430 
1431    Output Parameter:
1432 .  fact - the factored matrix
1433 
1434    Notes:
1435    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1436    MatCholeskyFactor() and MatCholeskyFactorNumeric().
1437 
1438    Most users should employ the simplified SLES interface for linear solvers
1439    instead of working directly with matrix algebra routines such as this.
1440    See, e.g., SLESCreate().
1441 
1442    Level: developer
1443 
1444 .keywords: matrix, factor, factorization, symbolic, Cholesky
1445 
1446 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1447           MatGetOrdering()
1448 
1449 @*/
1450 int MatCholeskyFactorSymbolic(Mat mat,IS perm,double f,Mat *fact)
1451 {
1452   int ierr;
1453 
1454   PetscFunctionBegin;
1455   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1456   PetscValidPointer(fact);
1457   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,0,"Matrix must be square");
1458   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1459   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1460   if (!mat->ops->choleskyfactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"");
1461 
1462   PLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1463   ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,f,fact);CHKERRQ(ierr);
1464   PLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1465   PetscFunctionReturn(0);
1466 }
1467 
1468 #undef __FUNC__
1469 #define __FUNC__ "MatCholeskyFactorNumeric"
1470 /*@
1471    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1472    of a symmetric matrix. Call this routine after first calling
1473    MatCholeskyFactorSymbolic().
1474 
1475    Collective on Mat
1476 
1477    Input Parameter:
1478 .  mat - the initial matrix
1479 
1480    Output Parameter:
1481 .  fact - the factored matrix
1482 
1483    Notes:
1484    Most users should employ the simplified SLES interface for linear solvers
1485    instead of working directly with matrix algebra routines such as this.
1486    See, e.g., SLESCreate().
1487 
1488    Level: developer
1489 
1490 .keywords: matrix, factor, numeric, Cholesky
1491 
1492 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1493 @*/
1494 int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1495 {
1496   int ierr;
1497 
1498   PetscFunctionBegin;
1499   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1500   PetscValidPointer(fact);
1501   if (!mat->ops->choleskyfactornumeric) SETERRQ(PETSC_ERR_SUP,0,"");
1502   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1503   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1504     SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1505             mat->M,(*fact)->M,mat->N,(*fact)->N);
1506   }
1507 
1508   PLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1509   ierr = (*mat->ops->choleskyfactornumeric)(mat,fact);CHKERRQ(ierr);
1510   PLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1511   PetscFunctionReturn(0);
1512 }
1513 
1514 /* ----------------------------------------------------------------*/
1515 #undef __FUNC__
1516 #define __FUNC__ "MatSolve"
1517 /*@
1518    MatSolve - Solves A x = b, given a factored matrix.
1519 
1520    Collective on Mat and Vec
1521 
1522    Input Parameters:
1523 +  mat - the factored matrix
1524 -  b - the right-hand-side vector
1525 
1526    Output Parameter:
1527 .  x - the result vector
1528 
1529    Notes:
1530    The vectors b and x cannot be the same.  I.e., one cannot
1531    call MatSolve(A,x,x).
1532 
1533    Notes:
1534    Most users should employ the simplified SLES interface for linear solvers
1535    instead of working directly with matrix algebra routines such as this.
1536    See, e.g., SLESCreate().
1537 
1538    Level: developer
1539 
1540 .keywords: matrix, linear system, solve, LU, Cholesky, triangular solve
1541 
1542 .seealso: MatSolveAdd(), MatSolveTrans(), MatSolveTransAdd()
1543 @*/
1544 int MatSolve(Mat mat,Vec b,Vec x)
1545 {
1546   int ierr;
1547 
1548   PetscFunctionBegin;
1549   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1550   PetscValidHeaderSpecific(b,VEC_COOKIE);
1551   PetscValidHeaderSpecific(x,VEC_COOKIE);
1552   PetscCheckSameComm(mat,b);
1553   PetscCheckSameComm(mat,x);
1554   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1555   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1556   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1557   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1558   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1559   if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0);
1560 
1561   if (!mat->ops->solve) SETERRQ(PETSC_ERR_SUP,0,"");
1562   PLogEventBegin(MAT_Solve,mat,b,x,0);
1563   ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr);
1564   PLogEventEnd(MAT_Solve,mat,b,x,0);
1565   PetscFunctionReturn(0);
1566 }
1567 
1568 #undef __FUNC__
1569 #define __FUNC__ "MatForwardSolve"
1570 /* @
1571    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.
1572 
1573    Collective on Mat and Vec
1574 
1575    Input Parameters:
1576 +  mat - the factored matrix
1577 -  b - the right-hand-side vector
1578 
1579    Output Parameter:
1580 .  x - the result vector
1581 
1582    Notes:
1583    MatSolve() should be used for most applications, as it performs
1584    a forward solve followed by a backward solve.
1585 
1586    The vectors b and x cannot be the same.  I.e., one cannot
1587    call MatForwardSolve(A,x,x).
1588 
1589    Most users should employ the simplified SLES interface for linear solvers
1590    instead of working directly with matrix algebra routines such as this.
1591    See, e.g., SLESCreate().
1592 
1593    Level: developer
1594 
1595 .keywords: matrix, forward, LU, Cholesky, triangular solve
1596 
1597 .seealso: MatSolve(), MatBackwardSolve()
1598 @ */
1599 int MatForwardSolve(Mat mat,Vec b,Vec x)
1600 {
1601   int ierr;
1602 
1603   PetscFunctionBegin;
1604   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1605   PetscValidHeaderSpecific(b,VEC_COOKIE);
1606   PetscValidHeaderSpecific(x,VEC_COOKIE);
1607   PetscCheckSameComm(mat,b);
1608   PetscCheckSameComm(mat,x);
1609   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1610   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1611   if (!mat->ops->forwardsolve) SETERRQ(PETSC_ERR_SUP,0,"");
1612   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1613   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1614   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1615 
1616   PLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
1617   ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr);
1618   PLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
1619   PetscFunctionReturn(0);
1620 }
1621 
1622 #undef __FUNC__
1623 #define __FUNC__ "MatBackwardSolve"
1624 /* @
1625    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
1626 
1627    Collective on Mat and Vec
1628 
1629    Input Parameters:
1630 +  mat - the factored matrix
1631 -  b - the right-hand-side vector
1632 
1633    Output Parameter:
1634 .  x - the result vector
1635 
1636    Notes:
1637    MatSolve() should be used for most applications, as it performs
1638    a forward solve followed by a backward solve.
1639 
1640    The vectors b and x cannot be the same.  I.e., one cannot
1641    call MatBackwardSolve(A,x,x).
1642 
1643    Most users should employ the simplified SLES interface for linear solvers
1644    instead of working directly with matrix algebra routines such as this.
1645    See, e.g., SLESCreate().
1646 
1647    Level: developer
1648 
1649 .keywords: matrix, backward, LU, Cholesky, triangular solve
1650 
1651 .seealso: MatSolve(), MatForwardSolve()
1652 @ */
1653 int MatBackwardSolve(Mat mat,Vec b,Vec x)
1654 {
1655   int ierr;
1656 
1657   PetscFunctionBegin;
1658   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1659   PetscValidHeaderSpecific(b,VEC_COOKIE);
1660   PetscValidHeaderSpecific(x,VEC_COOKIE);
1661   PetscCheckSameComm(mat,b);
1662   PetscCheckSameComm(mat,x);
1663   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1664   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1665   if (!mat->ops->backwardsolve) SETERRQ(PETSC_ERR_SUP,0,"");
1666   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1667   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1668   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1669 
1670   PLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
1671   ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr);
1672   PLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
1673   PetscFunctionReturn(0);
1674 }
1675 
1676 #undef __FUNC__
1677 #define __FUNC__ "MatSolveAdd"
1678 /*@
1679    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
1680 
1681    Collective on Mat and Vec
1682 
1683    Input Parameters:
1684 +  mat - the factored matrix
1685 .  b - the right-hand-side vector
1686 -  y - the vector to be added to
1687 
1688    Output Parameter:
1689 .  x - the result vector
1690 
1691    Notes:
1692    The vectors b and x cannot be the same.  I.e., one cannot
1693    call MatSolveAdd(A,x,y,x).
1694 
1695    Most users should employ the simplified SLES interface for linear solvers
1696    instead of working directly with matrix algebra routines such as this.
1697    See, e.g., SLESCreate().
1698 
1699    Level: developer
1700 
1701 .keywords: matrix, linear system, solve, LU, Cholesky, add
1702 
1703 .seealso: MatSolve(), MatSolveTrans(), MatSolveTransAdd()
1704 @*/
1705 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
1706 {
1707   Scalar one = 1.0;
1708   Vec    tmp;
1709   int    ierr;
1710 
1711   PetscFunctionBegin;
1712   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1713   PetscValidHeaderSpecific(y,VEC_COOKIE);
1714   PetscValidHeaderSpecific(b,VEC_COOKIE);
1715   PetscValidHeaderSpecific(x,VEC_COOKIE);
1716   PetscCheckSameComm(mat,b);
1717   PetscCheckSameComm(mat,y);
1718   PetscCheckSameComm(mat,x);
1719   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1720   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1721   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1722   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1723   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1724   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1725   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Vec x,Vec y: local dim %d %d",x->n,y->n);
1726 
1727   PLogEventBegin(MAT_SolveAdd,mat,b,x,y);
1728   if (mat->ops->solveadd)  {
1729     ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr);
1730   } else {
1731     /* do the solve then the add manually */
1732     if (x != y) {
1733       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
1734       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
1735     } else {
1736       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
1737       PLogObjectParent(mat,tmp);
1738       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
1739       ierr = MatSolve(mat,b,x);CHKERRQ(ierr);
1740       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
1741       ierr = VecDestroy(tmp);CHKERRQ(ierr);
1742     }
1743   }
1744   PLogEventEnd(MAT_SolveAdd,mat,b,x,y);
1745   PetscFunctionReturn(0);
1746 }
1747 
1748 #undef __FUNC__
1749 #define __FUNC__ "MatSolveTrans"
1750 /*@
1751    MatSolveTrans - Solves A' x = b, given a factored matrix.
1752 
1753    Collective on Mat and Vec
1754 
1755    Input Parameters:
1756 +  mat - the factored matrix
1757 -  b - the right-hand-side vector
1758 
1759    Output Parameter:
1760 .  x - the result vector
1761 
1762    Notes:
1763    The vectors b and x cannot be the same.  I.e., one cannot
1764    call MatSolveTrans(A,x,x).
1765 
1766    Most users should employ the simplified SLES interface for linear solvers
1767    instead of working directly with matrix algebra routines such as this.
1768    See, e.g., SLESCreate().
1769 
1770    Level: developer
1771 
1772 .keywords: matrix, linear system, solve, LU, Cholesky, transpose
1773 
1774 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransAdd()
1775 @*/
1776 int MatSolveTrans(Mat mat,Vec b,Vec x)
1777 {
1778   int ierr;
1779 
1780   PetscFunctionBegin;
1781   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1782   PetscValidHeaderSpecific(b,VEC_COOKIE);
1783   PetscValidHeaderSpecific(x,VEC_COOKIE);
1784   PetscCheckSameComm(mat,b);
1785   PetscCheckSameComm(mat,x);
1786   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1787   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1788   if (!mat->ops->solvetrans) SETERRQ(PETSC_ERR_SUP,0,"");
1789   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1790   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
1791 
1792   PLogEventBegin(MAT_SolveTrans,mat,b,x,0);
1793   ierr = (*mat->ops->solvetrans)(mat,b,x);CHKERRQ(ierr);
1794   PLogEventEnd(MAT_SolveTrans,mat,b,x,0);
1795   PetscFunctionReturn(0);
1796 }
1797 
1798 #undef __FUNC__
1799 #define __FUNC__ "MatSolveTransAdd"
1800 /*@
1801    MatSolveTransAdd - Computes x = y + inv(trans(A)) b, given a
1802                       factored matrix.
1803 
1804    Collective on Mat and Vec
1805 
1806    Input Parameters:
1807 +  mat - the factored matrix
1808 .  b - the right-hand-side vector
1809 -  y - the vector to be added to
1810 
1811    Output Parameter:
1812 .  x - the result vector
1813 
1814    Notes:
1815    The vectors b and x cannot be the same.  I.e., one cannot
1816    call MatSolveTransAdd(A,x,y,x).
1817 
1818    Most users should employ the simplified SLES interface for linear solvers
1819    instead of working directly with matrix algebra routines such as this.
1820    See, e.g., SLESCreate().
1821 
1822    Level: developer
1823 
1824 .keywords: matrix, linear system, solve, LU, Cholesky, transpose, add
1825 
1826 .seealso: MatSolve(), MatSolveAdd(), MatSolveTrans()
1827 @*/
1828 int MatSolveTransAdd(Mat mat,Vec b,Vec y,Vec x)
1829 {
1830   Scalar one = 1.0;
1831   int    ierr;
1832   Vec    tmp;
1833 
1834   PetscFunctionBegin;
1835   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1836   PetscValidHeaderSpecific(y,VEC_COOKIE);
1837   PetscValidHeaderSpecific(b,VEC_COOKIE);
1838   PetscValidHeaderSpecific(x,VEC_COOKIE);
1839   PetscCheckSameComm(mat,b);
1840   PetscCheckSameComm(mat,y);
1841   PetscCheckSameComm(mat,x);
1842   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,0,"x and b must be different vectors");
1843   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Unfactored matrix");
1844   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1845   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
1846   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
1847   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Vec x,Vec y: local dim %d %d",x->n,y->n);
1848 
1849   PLogEventBegin(MAT_SolveTransAdd,mat,b,x,y);
1850   if (mat->ops->solvetransadd) {
1851     ierr = (*mat->ops->solvetransadd)(mat,b,y,x);CHKERRQ(ierr);
1852   } else {
1853     /* do the solve then the add manually */
1854     if (x != y) {
1855       ierr = MatSolveTrans(mat,b,x);CHKERRQ(ierr);
1856       ierr = VecAXPY(&one,y,x);CHKERRQ(ierr);
1857     } else {
1858       ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr);
1859       PLogObjectParent(mat,tmp);
1860       ierr = VecCopy(x,tmp);CHKERRQ(ierr);
1861       ierr = MatSolveTrans(mat,b,x);CHKERRQ(ierr);
1862       ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr);
1863       ierr = VecDestroy(tmp);CHKERRQ(ierr);
1864     }
1865   }
1866   PLogEventEnd(MAT_SolveTransAdd,mat,b,x,y);
1867   PetscFunctionReturn(0);
1868 }
1869 /* ----------------------------------------------------------------*/
1870 
1871 #undef __FUNC__
1872 #define __FUNC__ "MatRelax"
1873 /*@
1874    MatRelax - Computes one relaxation sweep.
1875 
1876    Collective on Mat and Vec
1877 
1878    Input Parameters:
1879 +  mat - the matrix
1880 .  b - the right hand side
1881 .  omega - the relaxation factor
1882 .  flag - flag indicating the type of SOR (see below)
1883 .  shift -  diagonal shift
1884 -  its - the number of iterations
1885 
1886    Output Parameters:
1887 .  x - the solution (can contain an initial guess)
1888 
1889    SOR Flags:
1890 .     SOR_FORWARD_SWEEP - forward SOR
1891 .     SOR_BACKWARD_SWEEP - backward SOR
1892 .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
1893 .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
1894 .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
1895 .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
1896 .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
1897          upper/lower triangular part of matrix to
1898          vector (with omega)
1899 .     SOR_ZERO_INITIAL_GUESS - zero initial guess
1900 
1901    Notes:
1902    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
1903    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
1904    on each processor.
1905 
1906    Application programmers will not generally use MatRelax() directly,
1907    but instead will employ the SLES/PC interface.
1908 
1909    Notes for Advanced Users:
1910    The flags are implemented as bitwise inclusive or operations.
1911    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
1912    to specify a zero initial guess for SSOR.
1913 
1914    Most users should employ the simplified SLES interface for linear solvers
1915    instead of working directly with matrix algebra routines such as this.
1916    See, e.g., SLESCreate().
1917 
1918    Level: developer
1919 
1920 .keywords: matrix, relax, relaxation, sweep
1921 @*/
1922 int MatRelax(Mat mat,Vec b,double omega,MatSORType flag,double shift,int its,Vec x)
1923 {
1924   int ierr;
1925 
1926   PetscFunctionBegin;
1927   PetscValidHeaderSpecific(mat,MAT_COOKIE);
1928   PetscValidHeaderSpecific(b,VEC_COOKIE);
1929   PetscValidHeaderSpecific(x,VEC_COOKIE);
1930   PetscCheckSameComm(mat,b);
1931   PetscCheckSameComm(mat,x);
1932   if (!mat->ops->relax) SETERRQ(PETSC_ERR_SUP,0,"");
1933   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
1934   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
1935   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1936   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1937   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,0,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1938 
1939   PLogEventBegin(MAT_Relax,mat,b,x,0);
1940   ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,x);CHKERRQ(ierr);
1941   PLogEventEnd(MAT_Relax,mat,b,x,0);
1942   PetscFunctionReturn(0);
1943 }
1944 
1945 #undef __FUNC__
1946 #define __FUNC__ "MatCopy_Basic"
1947 /*
1948       Default matrix copy routine.
1949 */
1950 int MatCopy_Basic(Mat A,Mat B,MatStructure str)
1951 {
1952   int    ierr,i,rstart,rend,nz,*cwork;
1953   Scalar *vwork;
1954 
1955   PetscFunctionBegin;
1956   ierr = MatZeroEntries(B);CHKERRQ(ierr);
1957   ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr);
1958   for (i=rstart; i<rend; i++) {
1959     ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
1960     ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);
1961     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
1962   }
1963   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1964   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1965   PetscFunctionReturn(0);
1966 }
1967 
1968 #undef __FUNC__
1969 #define __FUNC__ "MatCopy"
1970 /*@C
1971    MatCopy - Copys a matrix to another matrix.
1972 
1973    Collective on Mat
1974 
1975    Input Parameters:
1976 +  A - the matrix
1977 -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
1978 
1979    Output Parameter:
1980 .  B - where the copy is put
1981 
1982    Notes:
1983    If you use SAME_NONZERO_PATTERN then the zero matrices had better have the
1984    same nonzero pattern or the routine will crash.
1985 
1986    MatCopy() copies the matrix entries of a matrix to another existing
1987    matrix (after first zeroing the second matrix).  A related routine is
1988    MatConvert(), which first creates a new matrix and then copies the data.
1989 
1990    Level: intermediate
1991 
1992 .keywords: matrix, copy, convert
1993 
1994 .seealso: MatConvert()
1995 @*/
1996 int MatCopy(Mat A,Mat B,MatStructure str)
1997 {
1998   int ierr;
1999 
2000   PetscFunctionBegin;
2001   PetscValidHeaderSpecific(A,MAT_COOKIE);
2002   PetscValidHeaderSpecific(B,MAT_COOKIE);
2003   PetscCheckSameComm(A,B);
2004   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2005   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2006   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat A,Mat B: global dim %d %d",A->M,B->M,
2007                                              A->N,B->N);
2008 
2009   PLogEventBegin(MAT_Copy,A,B,0,0);
2010   if (A->ops->copy) {
2011     ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr);
2012   } else { /* generic conversion */
2013     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
2014   }
2015   PLogEventEnd(MAT_Copy,A,B,0,0);
2016   PetscFunctionReturn(0);
2017 }
2018 
2019 static int MatConvertersSet = 0;
2020 static int (*MatConverters[MAX_MATRIX_TYPES][MAX_MATRIX_TYPES])(Mat,MatType,Mat*) =
2021            {{0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
2022             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
2023             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
2024             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
2025             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0},
2026             {0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0}};
2027 
2028 #undef __FUNC__
2029 #define __FUNC__ "MatConvertRegister"
2030 /*@C
2031     MatConvertRegister - Allows one to register a routine that converts between
2032     two matrix types.
2033 
2034     Not Collective
2035 
2036     Input Parameters:
2037 +   intype - the type of matrix (defined in include/mat.h), for example, MATSEQAIJ.
2038 -   outtype - new matrix type, or MATSAME
2039 
2040     Level: advanced
2041 
2042 .seealso: MatConvertRegisterAll()
2043 @*/
2044 int MatConvertRegister(MatType intype,MatType outtype,int (*converter)(Mat,MatType,Mat*))
2045 {
2046   PetscFunctionBegin;
2047   MatConverters[intype][outtype] = converter;
2048   MatConvertersSet               = 1;
2049   PetscFunctionReturn(0);
2050 }
2051 
2052 #undef __FUNC__
2053 #define __FUNC__ "MatConvert"
2054 /*@C
2055    MatConvert - Converts a matrix to another matrix, either of the same
2056    or different type.
2057 
2058    Collective on Mat
2059 
2060    Input Parameters:
2061 +  mat - the matrix
2062 -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2063    same type as the original matrix.
2064 
2065    Output Parameter:
2066 .  M - pointer to place new matrix
2067 
2068    Notes:
2069    MatConvert() first creates a new matrix and then copies the data from
2070    the first matrix.  A related routine is MatCopy(), which copies the matrix
2071    entries of one matrix to another already existing matrix context.
2072 
2073    Level: intermediate
2074 
2075 .keywords: matrix, copy, convert
2076 
2077 .seealso: MatCopy(), MatDuplicate()
2078 @*/
2079 int MatConvert(Mat mat,MatType newtype,Mat *M)
2080 {
2081   int ierr;
2082 
2083   PetscFunctionBegin;
2084   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2085   PetscValidPointer(M);
2086   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2087   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2088 
2089   if (newtype > MAX_MATRIX_TYPES || newtype < -1) {
2090     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
2091   }
2092   *M  = 0;
2093 
2094   if (!MatConvertersSet) {
2095     ierr = MatLoadRegisterAll();CHKERRQ(ierr);
2096   }
2097 
2098   PLogEventBegin(MAT_Convert,mat,0,0,0);
2099   if ((newtype == mat->type || newtype == MATSAME) && mat->ops->duplicate) {
2100     ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr);
2101   } else {
2102     if (!MatConvertersSet) {
2103       ierr = MatConvertRegisterAll();CHKERRQ(ierr);
2104     }
2105     if (!MatConverters[mat->type][newtype]) {
2106       SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix converter not registered");
2107     }
2108     ierr = (*MatConverters[mat->type][newtype])(mat,newtype,M);CHKERRQ(ierr);
2109   }
2110   PLogEventEnd(MAT_Convert,mat,0,0,0);
2111   PetscFunctionReturn(0);
2112 }
2113 
2114 #undef __FUNC__
2115 #define __FUNC__ "MatDuplicate"
2116 /*@C
2117    MatDuplicate - Duplicates a matrix including the non-zero structure.
2118 
2119    Collective on Mat
2120 
2121    Input Parameters:
2122 +  mat - the matrix
2123 -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2124         values as well or not
2125 
2126    Output Parameter:
2127 .  M - pointer to place new matrix
2128 
2129    Level: intermediate
2130 
2131 .keywords: matrix, copy, convert, duplicate
2132 
2133 .seealso: MatCopy(), MatConvert()
2134 @*/
2135 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2136 {
2137   int ierr;
2138 
2139   PetscFunctionBegin;
2140   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2141   PetscValidPointer(M);
2142   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2143   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2144 
2145   *M  = 0;
2146   PLogEventBegin(MAT_Convert,mat,0,0,0);
2147   if (!mat->ops->duplicate) {
2148     SETERRQ(PETSC_ERR_SUP,1,"Not written for this matrix type");
2149   }
2150   ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr);
2151   PLogEventEnd(MAT_Convert,mat,0,0,0);
2152   PetscFunctionReturn(0);
2153 }
2154 
2155 #undef __FUNC__
2156 #define __FUNC__ "MatGetDiagonal"
2157 /*@
2158    MatGetDiagonal - Gets the diagonal of a matrix.
2159 
2160    Collective on Mat and Vec
2161 
2162    Input Parameters:
2163 +  mat - the matrix
2164 -  v - the vector for storing the diagonal
2165 
2166    Output Parameter:
2167 .  v - the diagonal of the matrix
2168 
2169    Notes:
2170    For the SeqAIJ matrix format, this routine may also be called
2171    on a LU factored matrix; in that case it routines the reciprocal of
2172    the diagonal entries in U. It returns the entries permuted by the
2173    row and column permutation used during the symbolic factorization.
2174 
2175    Level: intermediate
2176 
2177 .keywords: matrix, get, diagonal
2178 
2179 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix()
2180 @*/
2181 int MatGetDiagonal(Mat mat,Vec v)
2182 {
2183   int ierr;
2184 
2185   PetscFunctionBegin;
2186   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2187   PetscValidHeaderSpecific(v,VEC_COOKIE);
2188   /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */
2189   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2190   if (!mat->ops->getdiagonal) SETERRQ(PETSC_ERR_SUP,0,"");
2191 
2192   ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr);
2193   PetscFunctionReturn(0);
2194 }
2195 
2196 #undef __FUNC__
2197 #define __FUNC__ "MatTranspose"
2198 /*@C
2199    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
2200 
2201    Collective on Mat
2202 
2203    Input Parameter:
2204 .  mat - the matrix to transpose
2205 
2206    Output Parameters:
2207 .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)
2208 
2209    Level: intermediate
2210 
2211 .keywords: matrix, transpose
2212 
2213 .seealso: MatMultTrans(), MatMultTransAdd()
2214 @*/
2215 int MatTranspose(Mat mat,Mat *B)
2216 {
2217   int ierr;
2218 
2219   PetscFunctionBegin;
2220   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2221   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2222   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2223   if (!mat->ops->transpose) SETERRQ(PETSC_ERR_SUP,0,"");
2224   ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr);
2225   PetscFunctionReturn(0);
2226 }
2227 
2228 #undef __FUNC__
2229 #define __FUNC__ "MatPermute"
2230 /*@C
2231    MatPermute - Creates a new matrix with rows and columns permuted from the
2232    original.
2233 
2234    Collective on Mat
2235 
2236    Input Parameters:
2237 +  mat - the matrix to permute
2238 .  row - row permutation
2239 -  col - column permutation
2240 
2241    Output Parameters:
2242 .  B - the permuted matrix
2243 
2244    Level: advanced
2245 
2246 .keywords: matrix, transpose
2247 
2248 .seealso: MatGetOrdering()
2249 @*/
2250 int MatPermute(Mat mat,IS row,IS col,Mat *B)
2251 {
2252   int ierr;
2253 
2254   PetscFunctionBegin;
2255   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2256   PetscValidHeaderSpecific(row,IS_COOKIE);
2257   PetscValidHeaderSpecific(col,IS_COOKIE);
2258   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2259   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2260   if (!mat->ops->permute) SETERRQ(PETSC_ERR_SUP,0,"");
2261   ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr);
2262   PetscFunctionReturn(0);
2263 }
2264 
2265 #undef __FUNC__
2266 #define __FUNC__ "MatEqual"
2267 /*@
2268    MatEqual - Compares two matrices.
2269 
2270    Collective on Mat
2271 
2272    Input Parameters:
2273 +  A - the first matrix
2274 -  B - the second matrix
2275 
2276    Output Parameter:
2277 .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
2278 
2279    Level: intermediate
2280 
2281 .keywords: matrix, equal, equivalent
2282 @*/
2283 int MatEqual(Mat A,Mat B,PetscTruth *flg)
2284 {
2285   int ierr;
2286 
2287   PetscFunctionBegin;
2288   PetscValidHeaderSpecific(A,MAT_COOKIE);
2289   PetscValidHeaderSpecific(B,MAT_COOKIE);
2290   PetscValidIntPointer(flg);
2291   PetscCheckSameComm(A,B);
2292   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2293   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2294   if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,0,"Mat A,Mat B: global dim %d %d %d %d",
2295                                              A->M,B->M,A->N,B->N);
2296   if (!A->ops->equal) SETERRQ(PETSC_ERR_SUP,0,"");
2297   ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr);
2298   PetscFunctionReturn(0);
2299 }
2300 
2301 #undef __FUNC__
2302 #define __FUNC__ "MatDiagonalScale"
2303 /*@
2304    MatDiagonalScale - Scales a matrix on the left and right by diagonal
2305    matrices that are stored as vectors.  Either of the two scaling
2306    matrices can be PETSC_NULL.
2307 
2308    Collective on Mat
2309 
2310    Input Parameters:
2311 +  mat - the matrix to be scaled
2312 .  l - the left scaling vector (or PETSC_NULL)
2313 -  r - the right scaling vector (or PETSC_NULL)
2314 
2315    Notes:
2316    MatDiagonalScale() computes A = LAR, where
2317    L = a diagonal matrix, R = a diagonal matrix
2318 
2319    Level: intermediate
2320 
2321 .keywords: matrix, diagonal, scale
2322 
2323 .seealso: MatScale()
2324 @*/
2325 int MatDiagonalScale(Mat mat,Vec l,Vec r)
2326 {
2327   int ierr;
2328 
2329   PetscFunctionBegin;
2330   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2331   if (!mat->ops->diagonalscale) SETERRQ(PETSC_ERR_SUP,0,"");
2332   if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE);PetscCheckSameComm(mat,l);}
2333   if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE);PetscCheckSameComm(mat,r);}
2334   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2335   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2336 
2337   PLogEventBegin(MAT_Scale,mat,0,0,0);
2338   ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr);
2339   PLogEventEnd(MAT_Scale,mat,0,0,0);
2340   PetscFunctionReturn(0);
2341 }
2342 
2343 #undef __FUNC__
2344 #define __FUNC__ "MatScale"
2345 /*@
2346     MatScale - Scales all elements of a matrix by a given number.
2347 
2348     Collective on Mat
2349 
2350     Input Parameters:
2351 +   mat - the matrix to be scaled
2352 -   a  - the scaling value
2353 
2354     Output Parameter:
2355 .   mat - the scaled matrix
2356 
2357     Level: intermediate
2358 
2359 .keywords: matrix, scale
2360 
2361 .seealso: MatDiagonalScale()
2362 @*/
2363 int MatScale(Scalar *a,Mat mat)
2364 {
2365   int ierr;
2366 
2367   PetscFunctionBegin;
2368   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2369   PetscValidScalarPointer(a);
2370   if (!mat->ops->scale) SETERRQ(PETSC_ERR_SUP,0,"");
2371   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2372   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2373 
2374   PLogEventBegin(MAT_Scale,mat,0,0,0);
2375   ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr);
2376   PLogEventEnd(MAT_Scale,mat,0,0,0);
2377   PetscFunctionReturn(0);
2378 }
2379 
2380 #undef __FUNC__
2381 #define __FUNC__ "MatNorm"
2382 /*@
2383    MatNorm - Calculates various norms of a matrix.
2384 
2385    Collective on Mat
2386 
2387    Input Parameters:
2388 +  mat - the matrix
2389 -  type - the type of norm, NORM_1, NORM_2, NORM_FROBENIUS, NORM_INFINITY
2390 
2391    Output Parameters:
2392 .  norm - the resulting norm
2393 
2394    Level: intermediate
2395 
2396 .keywords: matrix, norm, Frobenius
2397 @*/
2398 int MatNorm(Mat mat,NormType type,double *norm)
2399 {
2400   int ierr;
2401 
2402   PetscFunctionBegin;
2403   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2404   PetscValidScalarPointer(norm);
2405 
2406   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2407   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2408   if (!mat->ops->norm) SETERRQ(PETSC_ERR_SUP,0,"Not for this matrix type");
2409   ierr = (*mat->ops->norm)(mat,type,norm);CHKERRQ(ierr);
2410   PetscFunctionReturn(0);
2411 }
2412 
2413 /*
2414      This variable is used to prevent counting of MatAssemblyBegin() that
2415    are called from within a MatAssemblyEnd().
2416 */
2417 static int MatAssemblyEnd_InUse = 0;
2418 #undef __FUNC__
2419 #define __FUNC__ "MatAssemblyBegin"
2420 /*@
2421    MatAssemblyBegin - Begins assembling the matrix.  This routine should
2422    be called after completing all calls to MatSetValues().
2423 
2424    Collective on Mat
2425 
2426    Input Parameters:
2427 +  mat - the matrix
2428 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
2429 
2430    Notes:
2431    MatSetValues() generally caches the values.  The matrix is ready to
2432    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
2433    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
2434    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
2435    using the matrix.
2436 
2437    Level: beginner
2438 
2439 .keywords: matrix, assembly, assemble, begin
2440 
2441 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
2442 @*/
2443 int MatAssemblyBegin(Mat mat,MatAssemblyType type)
2444 {
2445   int ierr;
2446 
2447   PetscFunctionBegin;
2448   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2449   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix.\n did you forget to call MatSetUnfactored()?");
2450   if (mat->assembled) {
2451     mat->was_assembled = PETSC_TRUE;
2452     mat->assembled     = PETSC_FALSE;
2453   }
2454   if (!MatAssemblyEnd_InUse) {
2455     PLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
2456     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2457     PLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
2458   } else {
2459     if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);}
2460   }
2461   PetscFunctionReturn(0);
2462 }
2463 
2464 #undef __FUNC__
2465 #define __FUNC__ "MatAssembed"
2466 /*@
2467    MatAssembled - Indicates if a matrix has been assembled and is ready for
2468      use; for example, in matrix-vector product.
2469 
2470    Collective on Mat
2471 
2472    Input Parameter:
2473 .  mat - the matrix
2474 
2475    Output Parameter:
2476 .  assembled - PETSC_TRUE or PETSC_FALSE
2477 
2478    Level: advanced
2479 
2480 .keywords: matrix, assembly, assemble, begin
2481 
2482 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
2483 @*/
2484 int MatAssembled(Mat mat,PetscTruth *assembled)
2485 {
2486   PetscFunctionBegin;
2487   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2488   *assembled = mat->assembled;
2489   PetscFunctionReturn(0);
2490 }
2491 
2492 #undef __FUNC__
2493 #define __FUNC__ "MatView_Private"
2494 /*
2495     Processes command line options to determine if/how a matrix
2496   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
2497 */
2498 int MatView_Private(Mat mat)
2499 {
2500   int ierr,flg;
2501 
2502   PetscFunctionBegin;
2503   ierr = OptionsHasName(mat->prefix,"-mat_view_info",&flg);CHKERRQ(ierr);
2504   if (flg) {
2505     ierr = ViewerPushFormat(VIEWER_STDOUT_(mat->comm),VIEWER_FORMAT_ASCII_INFO,0);CHKERRQ(ierr);
2506     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2507     ierr = ViewerPopFormat(VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2508   }
2509   ierr = OptionsHasName(mat->prefix,"-mat_view_info_detailed",&flg);CHKERRQ(ierr);
2510   if (flg) {
2511     ierr = ViewerPushFormat(VIEWER_STDOUT_(mat->comm),VIEWER_FORMAT_ASCII_INFO_LONG,0);CHKERRQ(ierr);
2512     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2513     ierr = ViewerPopFormat(VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2514   }
2515   ierr = OptionsHasName(mat->prefix,"-mat_view",&flg);CHKERRQ(ierr);
2516   if (flg) {
2517     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2518   }
2519   ierr = OptionsHasName(mat->prefix,"-mat_view_matlab",&flg);CHKERRQ(ierr);
2520   if (flg) {
2521     ierr = ViewerPushFormat(VIEWER_STDOUT_(mat->comm),VIEWER_FORMAT_ASCII_MATLAB,"M");CHKERRQ(ierr);
2522     ierr = MatView(mat,VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2523     ierr = ViewerPopFormat(VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr);
2524   }
2525   ierr = OptionsHasName(mat->prefix,"-mat_view_draw",&flg);CHKERRQ(ierr);
2526   if (flg) {
2527     ierr = OptionsHasName(mat->prefix,"-mat_view_contour",&flg);CHKERRQ(ierr);
2528     if (flg) {
2529       ViewerPushFormat(VIEWER_DRAW_(mat->comm),VIEWER_FORMAT_DRAW_CONTOUR,0);CHKERRQ(ierr);
2530     }
2531     ierr = MatView(mat,VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
2532     ierr = ViewerFlush(VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
2533     if (flg) {
2534       ViewerPopFormat(VIEWER_DRAW_(mat->comm));CHKERRQ(ierr);
2535     }
2536   }
2537   ierr = OptionsHasName(mat->prefix,"-mat_view_socket",&flg);CHKERRQ(ierr);
2538   if (flg) {
2539     ierr = MatView(mat,VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
2540     ierr = ViewerFlush(VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr);
2541   }
2542   PetscFunctionReturn(0);
2543 }
2544 
2545 #undef __FUNC__
2546 #define __FUNC__ "MatAssemblyEnd"
2547 /*@
2548    MatAssemblyEnd - Completes assembling the matrix.  This routine should
2549    be called after MatAssemblyBegin().
2550 
2551    Collective on Mat
2552 
2553    Input Parameters:
2554 +  mat - the matrix
2555 -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
2556 
2557    Options Database Keys:
2558 +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
2559 .  -mat_view_info_detailed - Prints more detailed info
2560 .  -mat_view - Prints matrix in ASCII format
2561 .  -mat_view_matlab - Prints matrix in Matlab format
2562 .  -mat_view_draw - Draws nonzero structure of matrix, using MatView() and DrawOpenX().
2563 .  -display <name> - Sets display name (default is host)
2564 -  -draw_pause <sec> - Sets number of seconds to pause after display
2565 
2566    Notes:
2567    MatSetValues() generally caches the values.  The matrix is ready to
2568    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
2569    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
2570    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
2571    using the matrix.
2572 
2573    Level: beginner
2574 
2575 .keywords: matrix, assembly, assemble, end
2576 
2577 .seealso: MatAssemblyBegin(), MatSetValues(), DrawOpenX(), MatView(), MatAssembled()
2578 @*/
2579 int MatAssemblyEnd(Mat mat,MatAssemblyType type)
2580 {
2581   int        ierr;
2582   static int inassm = 0;
2583 
2584   PetscFunctionBegin;
2585   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2586 
2587   inassm++;
2588   MatAssemblyEnd_InUse++;
2589   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
2590     PLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
2591     if (mat->ops->assemblyend) {
2592       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
2593     }
2594     PLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
2595   } else {
2596     if (mat->ops->assemblyend) {
2597       ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr);
2598     }
2599   }
2600 
2601   /* Flush assembly is not a true assembly */
2602   if (type != MAT_FLUSH_ASSEMBLY) {
2603     mat->assembled  = PETSC_TRUE; mat->num_ass++;
2604   }
2605   mat->insertmode = NOT_SET_VALUES;
2606   MatAssemblyEnd_InUse--;
2607 
2608   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
2609     ierr = MatView_Private(mat);CHKERRQ(ierr);
2610   }
2611   inassm--;
2612   PetscFunctionReturn(0);
2613 }
2614 
2615 
2616 #undef __FUNC__
2617 #define __FUNC__ "MatCompress"
2618 /*@
2619    MatCompress - Tries to store the matrix in as little space as
2620    possible.  May fail if memory is already fully used, since it
2621    tries to allocate new space.
2622 
2623    Collective on Mat
2624 
2625    Input Parameters:
2626 .  mat - the matrix
2627 
2628    Level: advanced
2629 
2630 .keywords: matrix, compress
2631 @*/
2632 int MatCompress(Mat mat)
2633 {
2634   int ierr;
2635 
2636   PetscFunctionBegin;
2637   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2638   if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);}
2639   PetscFunctionReturn(0);
2640 }
2641 
2642 #undef __FUNC__
2643 #define __FUNC__ "MatSetOption"
2644 /*@
2645    MatSetOption - Sets a parameter option for a matrix. Some options
2646    may be specific to certain storage formats.  Some options
2647    determine how values will be inserted (or added). Sorted,
2648    row-oriented input will generally assemble the fastest. The default
2649    is row-oriented, nonsorted input.
2650 
2651    Collective on Mat
2652 
2653    Input Parameters:
2654 +  mat - the matrix
2655 -  option - the option, one of those listed below (and possibly others),
2656              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR
2657 
2658    Options Describing Matrix Structure:
2659 +    MAT_SYMMETRIC - symmetric in terms of both structure and value
2660 -    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
2661 
2662    Options For Use with MatSetValues():
2663    Insert a logically dense subblock, which can be
2664 +    MAT_ROW_ORIENTED - row-oriented
2665 .    MAT_COLUMN_ORIENTED - column-oriented
2666 .    MAT_ROWS_SORTED - sorted by row
2667 .    MAT_ROWS_UNSORTED - not sorted by row
2668 .    MAT_COLUMNS_SORTED - sorted by column
2669 -    MAT_COLUMNS_UNSORTED - not sorted by column
2670 
2671    Not these options reflect the data you pass in with MatSetValues(); it has
2672    nothing to do with how the data is stored internally in the matrix
2673    data structure.
2674 
2675    When (re)assembling a matrix, we can restrict the input for
2676    efficiency/debugging purposes.  These options include
2677 +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
2678         allowed if they generate a new nonzero
2679 .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
2680 .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
2681          they generate a nonzero in a new diagonal (for block diagonal format only)
2682 .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
2683 .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
2684 .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
2685 -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
2686 
2687    Notes:
2688    Some options are relevant only for particular matrix types and
2689    are thus ignored by others.  Other options are not supported by
2690    certain matrix types and will generate an error message if set.
2691 
2692    If using a Fortran 77 module to compute a matrix, one may need to
2693    use the column-oriented option (or convert to the row-oriented
2694    format).
2695 
2696    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion
2697    that would generate a new entry in the nonzero structure is instead
2698    ignored.  Thus, if memory has not alredy been allocated for this particular
2699    data, then the insertion is ignored. For dense matrices, in which
2700    the entire array is allocated, no entries are ever ignored.
2701 
2702    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
2703    that would generate a new entry in the nonzero structure instead produces
2704    an error. (Currently supported for AIJ and BAIJ formats only.)
2705    This is a useful flag when using SAME_NONZERO_PATTERN in calling
2706    SLESSetOperators() to ensure that the nonzero pattern truely does
2707    remain unchanged.
2708 
2709    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
2710    that would generate a new entry that has not been preallocated will
2711    instead produce an error. (Currently supported for AIJ and BAIJ formats
2712    only.) This is a useful flag when debugging matrix memory preallocation.
2713 
2714    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
2715    other processors should be dropped, rather than stashed.
2716    This is useful if you know that the "owning" processor is also
2717    always generating the correct matrix entries, so that PETSc need
2718    not transfer duplicate entries generated on another processor.
2719 
2720    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
2721    searches during matrix assembly. When this flag is set, the hash table
2722    is created during the first Matrix Assembly. This hash table is
2723    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
2724    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag
2725    should be used with MAT_USE_HASH_TABLE flag. This option is currently
2726    supported by MATMPIBAIJ format only.
2727 
2728    Level: intermediate
2729 
2730 .keywords: matrix, option, row-oriented, column-oriented, sorted, nonzero
2731 @*/
2732 int MatSetOption(Mat mat,MatOption op)
2733 {
2734   int ierr;
2735 
2736   PetscFunctionBegin;
2737   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2738   if (mat->ops->setoption) {ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);}
2739   PetscFunctionReturn(0);
2740 }
2741 
2742 #undef __FUNC__
2743 #define __FUNC__ "MatZeroEntries"
2744 /*@
2745    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
2746    this routine retains the old nonzero structure.
2747 
2748    Collective on Mat
2749 
2750    Input Parameters:
2751 .  mat - the matrix
2752 
2753    Level: intermediate
2754 
2755 .keywords: matrix, zero, entries
2756 
2757 .seealso: MatZeroRows()
2758 @*/
2759 int MatZeroEntries(Mat mat)
2760 {
2761   int ierr;
2762 
2763   PetscFunctionBegin;
2764   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2765   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2766   if (!mat->ops->zeroentries) SETERRQ(PETSC_ERR_SUP,0,"");
2767 
2768   PLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
2769   ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr);
2770   PLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
2771   PetscFunctionReturn(0);
2772 }
2773 
2774 #undef __FUNC__
2775 #define __FUNC__ "MatZeroRows"
2776 /*@C
2777    MatZeroRows - Zeros all entries (except possibly the main diagonal)
2778    of a set of rows of a matrix.
2779 
2780    Collective on Mat
2781 
2782    Input Parameters:
2783 +  mat - the matrix
2784 .  is - index set of rows to remove
2785 -  diag - pointer to value put in all diagonals of eliminated rows.
2786           Note that diag is not a pointer to an array, but merely a
2787           pointer to a single value.
2788 
2789    Notes:
2790    For the AIJ matrix formats this removes the old nonzero structure,
2791    but does not release memory.  For the dense and block diagonal
2792    formats this does not alter the nonzero structure.
2793 
2794    The user can set a value in the diagonal entry (or for the AIJ and
2795    row formats can optionally remove the main diagonal entry from the
2796    nonzero structure as well, by passing a null pointer (PETSC_NULL
2797    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
2798 
2799    For the parallel case, all processes that share the matrix (i.e.,
2800    those in the communicator used for matrix creation) MUST call this
2801    routine, regardless of whether any rows being zeroed are owned by
2802    them.
2803 
2804    Level: intermediate
2805 
2806 .keywords: matrix, zero, rows, boundary conditions
2807 
2808 .seealso: MatZeroEntries(), MatZeroRowsLocal()
2809 @*/
2810 int MatZeroRows(Mat mat,IS is, Scalar *diag)
2811 {
2812   int ierr;
2813 
2814   PetscFunctionBegin;
2815   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2816   PetscValidHeaderSpecific(is,IS_COOKIE);
2817   if (diag) PetscValidScalarPointer(diag);
2818   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2819   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2820   if (!mat->ops->zerorows) SETERRQ(PETSC_ERR_SUP,0,"");
2821 
2822   ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr);
2823   ierr = MatView_Private(mat);CHKERRQ(ierr);
2824   PetscFunctionReturn(0);
2825 }
2826 
2827 #undef __FUNC__
2828 #define __FUNC__ "MatZeroRowsLocal"
2829 /*@C
2830    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
2831    of a set of rows of a matrix; using local numbering of rows.
2832 
2833    Collective on Mat
2834 
2835    Input Parameters:
2836 +  mat - the matrix
2837 .  is - index set of rows to remove
2838 -  diag - pointer to value put in all diagonals of eliminated rows.
2839           Note that diag is not a pointer to an array, but merely a
2840           pointer to a single value.
2841 
2842    Notes:
2843    For the AIJ matrix formats this removes the old nonzero structure,
2844    but does not release memory.  For the dense and block diagonal
2845    formats this does not alter the nonzero structure.
2846 
2847    The user can set a value in the diagonal entry (or for the AIJ and
2848    row formats can optionally remove the main diagonal entry from the
2849    nonzero structure as well, by passing a null pointer (PETSC_NULL
2850    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).
2851 
2852    Level: intermediate
2853 
2854 .keywords: matrix, zero, rows, boundary conditions
2855 
2856 .seealso: MatZeroEntries(), MatZeroRows()
2857 @*/
2858 int MatZeroRowsLocal(Mat mat,IS is, Scalar *diag)
2859 {
2860   int ierr;
2861   IS  newis;
2862 
2863   PetscFunctionBegin;
2864   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2865   PetscValidHeaderSpecific(is,IS_COOKIE);
2866   if (diag) PetscValidScalarPointer(diag);
2867   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
2868   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
2869   if (!mat->ops->zerorows) SETERRQ(PETSC_ERR_SUP,0,"");
2870 
2871   ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr);
2872   ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr);
2873   ierr = ISDestroy(newis);CHKERRQ(ierr);
2874   PetscFunctionReturn(0);
2875 }
2876 
2877 #undef __FUNC__
2878 #define __FUNC__ "MatGetSize"
2879 /*@
2880    MatGetSize - Returns the numbers of rows and columns in a matrix.
2881 
2882    Not Collective
2883 
2884    Input Parameter:
2885 .  mat - the matrix
2886 
2887    Output Parameters:
2888 +  m - the number of global rows
2889 -  n - the number of global columns
2890 
2891    Level: beginner
2892 
2893 .keywords: matrix, dimension, size, rows, columns, global, get
2894 
2895 .seealso: MatGetLocalSize()
2896 @*/
2897 int MatGetSize(Mat mat,int *m,int* n)
2898 {
2899   int ierr;
2900 
2901   PetscFunctionBegin;
2902   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2903   ierr = (*mat->ops->getsize)(mat,m,n);CHKERRQ(ierr);
2904   PetscFunctionReturn(0);
2905 }
2906 
2907 #undef __FUNC__
2908 #define __FUNC__ "MatGetLocalSize"
2909 /*@
2910    MatGetLocalSize - Returns the number of rows and columns in a matrix
2911    stored locally.  This information may be implementation dependent, so
2912    use with care.
2913 
2914    Not Collective
2915 
2916    Input Parameters:
2917 .  mat - the matrix
2918 
2919    Output Parameters:
2920 +  m - the number of local rows
2921 -  n - the number of local columns
2922 
2923    Level: beginner
2924 
2925 .keywords: matrix, dimension, size, local, rows, columns, get
2926 
2927 .seealso: MatGetSize()
2928 @*/
2929 int MatGetLocalSize(Mat mat,int *m,int* n)
2930 {
2931   int ierr;
2932 
2933   PetscFunctionBegin;
2934   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2935   ierr = (*mat->ops->getlocalsize)(mat,m,n);CHKERRQ(ierr);
2936   PetscFunctionReturn(0);
2937 }
2938 
2939 #undef __FUNC__
2940 #define __FUNC__ "MatGetOwnershipRange"
2941 /*@
2942    MatGetOwnershipRange - Returns the range of matrix rows owned by
2943    this processor, assuming that the matrix is laid out with the first
2944    n1 rows on the first processor, the next n2 rows on the second, etc.
2945    For certain parallel layouts this range may not be well defined.
2946 
2947    Not Collective
2948 
2949    Input Parameters:
2950 .  mat - the matrix
2951 
2952    Output Parameters:
2953 +  m - the global index of the first local row
2954 -  n - one more than the global index of the last local row
2955 
2956    Level: beginner
2957 
2958 .keywords: matrix, get, range, ownership
2959 @*/
2960 int MatGetOwnershipRange(Mat mat,int *m,int* n)
2961 {
2962   int ierr;
2963 
2964   PetscFunctionBegin;
2965   PetscValidHeaderSpecific(mat,MAT_COOKIE);
2966   PetscValidIntPointer(m);
2967   PetscValidIntPointer(n);
2968   if (!mat->ops->getownershiprange) SETERRQ(PETSC_ERR_SUP,0,"");
2969   ierr = (*mat->ops->getownershiprange)(mat,m,n);CHKERRQ(ierr);
2970   PetscFunctionReturn(0);
2971 }
2972 
2973 #undef __FUNC__
2974 #define __FUNC__ "MatILUFactorSymbolic"
2975 /*@
2976    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
2977    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
2978    to complete the factorization.
2979 
2980    Collective on Mat
2981 
2982    Input Parameters:
2983 +  mat - the matrix
2984 .  row - row permutation
2985 .  column - column permutation
2986 -  info - structure containing
2987 $      levels - number of levels of fill.
2988 $      expected fill - as ratio of original fill.
2989 $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2990                 missing diagonal entries)
2991 
2992    Output Parameters:
2993 .  fact - new matrix that has been symbolically factored
2994 
2995    Notes:
2996    See the users manual for additional information about
2997    choosing the fill factor for better efficiency.
2998 
2999    Most users should employ the simplified SLES interface for linear solvers
3000    instead of working directly with matrix algebra routines such as this.
3001    See, e.g., SLESCreate().
3002 
3003    Level: developer
3004 
3005 .keywords: matrix, factor, incomplete, ILU, symbolic, fill
3006 
3007 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3008           MatGetOrdering()
3009 
3010 @*/
3011 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatILUInfo *info,Mat *fact)
3012 {
3013   int ierr;
3014 
3015   PetscFunctionBegin;
3016   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3017   PetscValidPointer(fact);
3018   if (info && info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Levels of fill negative %d",info->levels);
3019   if (info && info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Expected fill less than 1.0 %g",info->fill);
3020   if (!mat->ops->ilufactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"Only MatCreateMPIRowbs() matrices support parallel ILU");
3021   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
3022   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
3023 
3024   PLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
3025   ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr);
3026   PLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
3027   PetscFunctionReturn(0);
3028 }
3029 
3030 #undef __FUNC__
3031 #define __FUNC__ "MatIncompleteCholeskyFactorSymbolic"
3032 /*@
3033    MatIncompleteCholeskyFactorSymbolic - Performs symbolic incomplete
3034    Cholesky factorization for a symmetric matrix.  Use
3035    MatCholeskyFactorNumeric() to complete the factorization.
3036 
3037    Collective on Mat
3038 
3039    Input Parameters:
3040 +  mat - the matrix
3041 .  perm - row and column permutation
3042 .  fill - levels of fill
3043 -  f - expected fill as ratio of original fill
3044 
3045    Output Parameter:
3046 .  fact - the factored matrix
3047 
3048    Notes:
3049    Currently only no-fill factorization is supported.
3050 
3051    Most users should employ the simplified SLES interface for linear solvers
3052    instead of working directly with matrix algebra routines such as this.
3053    See, e.g., SLESCreate().
3054 
3055    Level: developer
3056 
3057 .keywords: matrix, factor, incomplete, ICC, Cholesky, symbolic, fill
3058 
3059 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
3060 @*/
3061 int MatIncompleteCholeskyFactorSymbolic(Mat mat,IS perm,double f,int fill,Mat *fact)
3062 {
3063   int ierr;
3064 
3065   PetscFunctionBegin;
3066   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3067   PetscValidPointer(fact);
3068   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
3069   if (fill < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Fill negative %d",fill);
3070   if (f < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Expected fill less than 1.0 %g",f);
3071   if (!mat->ops->incompletecholeskyfactorsymbolic) SETERRQ(PETSC_ERR_SUP,0,"Currently only MatCreateMPIRowbs() matrices support ICC in parallel");
3072   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
3073 
3074   PLogEventBegin(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
3075   ierr = (*mat->ops->incompletecholeskyfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr);
3076   PLogEventEnd(MAT_IncompleteCholeskyFactorSymbolic,mat,perm,0,0);
3077   PetscFunctionReturn(0);
3078 }
3079 
3080 #undef __FUNC__
3081 #define __FUNC__ "MatGetArray"
3082 /*@C
3083    MatGetArray - Returns a pointer to the element values in the matrix.
3084    The result of this routine is dependent on the underlying matrix data
3085    structure, and may not even work for certain matrix types.  You MUST
3086    call MatRestoreArray() when you no longer need to access the array.
3087 
3088    Not Collective
3089 
3090    Input Parameter:
3091 .  mat - the matrix
3092 
3093    Output Parameter:
3094 .  v - the location of the values
3095 
3096    Currently returns an array only for the dense formats, giving access to
3097    the local portion of the matrix in the usual Fortran column-oriented format.
3098 
3099    Fortran Note:
3100    This routine is used differently from Fortran, e.g.,
3101 .vb
3102         Mat         mat
3103         Scalar      mat_array(1)
3104         PetscOffset i_mat
3105         int         ierr
3106         call MatGetArray(mat,mat_array,i_mat,ierr)
3107 
3108   C  Access first local entry in matrix; note that array is
3109   C  treated as one dimensional
3110         value = mat_array(i_mat + 1)
3111 
3112         [... other code ...]
3113         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3114 .ve
3115 
3116    See the Fortran chapter of the users manual and
3117    petsc/src/mat/examples/tests for details.
3118 
3119    Level: advanced
3120 
3121 .keywords: matrix, array, elements, values
3122 
3123 .seealso: MatRestoreArray(), MatGetArrayF90()
3124 @*/
3125 int MatGetArray(Mat mat,Scalar **v)
3126 {
3127   int ierr;
3128 
3129   PetscFunctionBegin;
3130   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3131   PetscValidPointer(v);
3132   if (!mat->ops->getarray) SETERRQ(PETSC_ERR_SUP,0,"");
3133   ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr);
3134   PetscFunctionReturn(0);
3135 }
3136 
3137 #undef __FUNC__
3138 #define __FUNC__ "MatRestoreArray"
3139 /*@C
3140    MatRestoreArray - Restores the matrix after MatGetArray() has been called.
3141 
3142    Not Collective
3143 
3144    Input Parameter:
3145 +  mat - the matrix
3146 -  v - the location of the values
3147 
3148    Fortran Note:
3149    This routine is used differently from Fortran, e.g.,
3150 .vb
3151         Mat         mat
3152         Scalar      mat_array(1)
3153         PetscOffset i_mat
3154         int         ierr
3155         call MatGetArray(mat,mat_array,i_mat,ierr)
3156 
3157   C  Access first local entry in matrix; note that array is
3158   C  treated as one dimensional
3159         value = mat_array(i_mat + 1)
3160 
3161         [... other code ...]
3162         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3163 .ve
3164 
3165    See the Fortran chapter of the users manual and
3166    petsc/src/mat/examples/tests for details
3167 
3168    Level: advanced
3169 
3170 .keywords: matrix, array, elements, values, restore
3171 
3172 .seealso: MatGetArray(), MatRestoreArrayF90()
3173 @*/
3174 int MatRestoreArray(Mat mat,Scalar **v)
3175 {
3176   int ierr;
3177 
3178   PetscFunctionBegin;
3179   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3180   PetscValidPointer(v);
3181   if (!mat->ops->restorearray) SETERRQ(PETSC_ERR_SUP,0,"");
3182   ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr);
3183   PetscFunctionReturn(0);
3184 }
3185 
3186 #undef __FUNC__
3187 #define __FUNC__ "MatGetSubMatrices"
3188 /*@C
3189    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
3190    points to an array of valid matrices, they may be reused to store the new
3191    submatrices.
3192 
3193    Collective on Mat
3194 
3195    Input Parameters:
3196 +  mat - the matrix
3197 .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
3198 .  irow, icol - index sets of rows and columns to extract
3199 -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
3200 
3201    Output Parameter:
3202 .  submat - the array of submatrices
3203 
3204    Notes:
3205    MatGetSubMatrices() can extract only sequential submatrices
3206    (from both sequential and parallel matrices). Use MatGetSubMatrix()
3207    to extract a parallel submatrix.
3208 
3209    When extracting submatrices from a parallel matrix, each processor can
3210    form a different submatrix by setting the rows and columns of its
3211    individual index sets according to the local submatrix desired.
3212 
3213    When finished using the submatrices, the user should destroy
3214    them with MatDestroySubMatrices().
3215 
3216    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
3217    original matrix has not changed from that last call to MatGetSubMatrices().
3218 
3219    Fortran Note:
3220    The Fortran interface is slightly different from that given below; it
3221    requires one to pass in  as submat a Mat (integer) array of size at least m.
3222 
3223    Level: advanced
3224 
3225 .keywords: matrix, get, submatrix, submatrices
3226 
3227 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
3228 @*/
3229 int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatReuse scall,Mat **submat)
3230 {
3231   int ierr;
3232 
3233   PetscFunctionBegin;
3234   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3235   if (!mat->ops->getsubmatrices) SETERRQ(PETSC_ERR_SUP,0,"");
3236   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
3237 
3238   PLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
3239   ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr);
3240   PLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
3241 
3242   PetscFunctionReturn(0);
3243 }
3244 
3245 #undef __FUNC__
3246 #define __FUNC__ "MatDestroyMatrices"
3247 /*@C
3248    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
3249 
3250    Collective on Mat
3251 
3252    Input Parameters:
3253 +  n - the number of local matrices
3254 -  mat - the matrices
3255 
3256    Level: advanced
3257 
3258 .keywords: matrix, destroy, submatrix, submatrices
3259 
3260 .seealso: MatGetSubMatrices()
3261 @*/
3262 int MatDestroyMatrices(int n,Mat **mat)
3263 {
3264   int ierr,i;
3265 
3266   PetscFunctionBegin;
3267   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,1,"Trying to destroy negative number of matrices %d",n);
3268   PetscValidPointer(mat);
3269   for ( i=0; i<n; i++ ) {
3270     ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr);
3271   }
3272   if (n) {ierr = PetscFree(*mat);CHKERRQ(ierr);}
3273   PetscFunctionReturn(0);
3274 }
3275 
3276 #undef __FUNC__
3277 #define __FUNC__ "MatIncreaseOverlap"
3278 /*@
3279    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
3280    replaces the index sets by larger ones that represent submatrices with
3281    additional overlap.
3282 
3283    Collective on Mat
3284 
3285    Input Parameters:
3286 +  mat - the matrix
3287 .  n   - the number of index sets
3288 .  is  - the array of pointers to index sets
3289 -  ov  - the additional overlap requested
3290 
3291    Level: developer
3292 
3293 .keywords: matrix, overlap, Schwarz
3294 
3295 .seealso: MatGetSubMatrices()
3296 @*/
3297 int MatIncreaseOverlap(Mat mat,int n, IS *is,int ov)
3298 {
3299   int ierr;
3300 
3301   PetscFunctionBegin;
3302   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3303   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix");
3304   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix");
3305 
3306   if (ov == 0) PetscFunctionReturn(0);
3307   if (!mat->ops->increaseoverlap) SETERRQ(PETSC_ERR_SUP,0,"");
3308   PLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
3309   ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr);
3310   PLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
3311   PetscFunctionReturn(0);
3312 }
3313 
3314 #undef __FUNC__
3315 #define __FUNC__ "MatPrintHelp"
3316 /*@
3317    MatPrintHelp - Prints all the options for the matrix.
3318 
3319    Collective on Mat
3320 
3321    Input Parameter:
3322 .  mat - the matrix
3323 
3324    Options Database Keys:
3325 +  -help - Prints matrix options
3326 -  -h - Prints matrix options
3327 
3328    Level: developer
3329 
3330 .keywords: mat, help
3331 
3332 .seealso: MatCreate(), MatCreateXXX()
3333 @*/
3334 int MatPrintHelp(Mat mat)
3335 {
3336   static int called = 0;
3337   int        ierr;
3338   MPI_Comm   comm;
3339 
3340   PetscFunctionBegin;
3341   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3342 
3343   comm = mat->comm;
3344   if (!called) {
3345     ierr = (*PetscHelpPrintf)(comm,"General matrix options:\n");CHKERRQ(ierr);
3346     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info: view basic matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3347     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_info_detailed: view detailed matrix info during MatAssemblyEnd()\n");CHKERRQ(ierr);
3348     ierr = (*PetscHelpPrintf)(comm,"  -mat_view_draw: draw nonzero matrix structure during MatAssemblyEnd()\n");CHKERRQ(ierr);
3349     ierr = (*PetscHelpPrintf)(comm,"      -draw_pause <sec>: set seconds of display pause\n");CHKERRQ(ierr);
3350     ierr = (*PetscHelpPrintf)(comm,"      -display <name>: set alternate display\n");CHKERRQ(ierr);
3351     called = 1;
3352   }
3353   if (mat->ops->printhelp) {
3354     ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr);
3355   }
3356   PetscFunctionReturn(0);
3357 }
3358 
3359 #undef __FUNC__
3360 #define __FUNC__ "MatGetBlockSize"
3361 /*@
3362    MatGetBlockSize - Returns the matrix block size; useful especially for the
3363    block row and block diagonal formats.
3364 
3365    Not Collective
3366 
3367    Input Parameter:
3368 .  mat - the matrix
3369 
3370    Output Parameter:
3371 .  bs - block size
3372 
3373    Notes:
3374    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
3375    Block row formats are MATSEQBAIJ, MATMPIBAIJ
3376 
3377    Level: intermediate
3378 
3379 .keywords: matrix, get, block, size
3380 
3381 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
3382 @*/
3383 int MatGetBlockSize(Mat mat,int *bs)
3384 {
3385   int ierr;
3386 
3387   PetscFunctionBegin;
3388   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3389   PetscValidIntPointer(bs);
3390   if (!mat->ops->getblocksize) SETERRQ(PETSC_ERR_SUP,0,"");
3391   ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr);
3392   PetscFunctionReturn(0);
3393 }
3394 
3395 #undef __FUNC__
3396 #define __FUNC__ "MatGetRowIJ"
3397 /*@C
3398     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
3399 
3400    Collective on Mat
3401 
3402     Input Parameters:
3403 +   mat - the matrix
3404 .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
3405 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3406                 symmetrized
3407 
3408     Output Parameters:
3409 +   n - number of rows in the (possibly compressed) matrix
3410 .   ia - the row pointers
3411 .   ja - the column indices
3412 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
3413 
3414     Level: developer
3415 
3416 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
3417 @*/
3418 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3419 {
3420   int ierr;
3421 
3422   PetscFunctionBegin;
3423   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3424   if (ia) PetscValidIntPointer(ia);
3425   if (ja) PetscValidIntPointer(ja);
3426   PetscValidIntPointer(done);
3427   if (!mat->ops->getrowij) *done = PETSC_FALSE;
3428   else {
3429     *done = PETSC_TRUE;
3430     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
3431   }
3432   PetscFunctionReturn(0);
3433 }
3434 
3435 #undef __FUNC__
3436 #define __FUNC__ "MatGetColumnIJ"
3437 /*@C
3438     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
3439 
3440     Collective on Mat
3441 
3442     Input Parameters:
3443 +   mat - the matrix
3444 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3445 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3446                 symmetrized
3447 
3448     Output Parameters:
3449 +   n - number of columns in the (possibly compressed) matrix
3450 .   ia - the column pointers
3451 .   ja - the row indices
3452 -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
3453 
3454     Level: developer
3455 
3456 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
3457 @*/
3458 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3459 {
3460   int ierr;
3461 
3462   PetscFunctionBegin;
3463   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3464   if (ia) PetscValidIntPointer(ia);
3465   if (ja) PetscValidIntPointer(ja);
3466   PetscValidIntPointer(done);
3467 
3468   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
3469   else {
3470     *done = PETSC_TRUE;
3471     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
3472   }
3473   PetscFunctionReturn(0);
3474 }
3475 
3476 #undef __FUNC__
3477 #define __FUNC__ "MatRestoreRowIJ"
3478 /*@C
3479     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
3480     MatGetRowIJ().
3481 
3482     Collective on Mat
3483 
3484     Input Parameters:
3485 +   mat - the matrix
3486 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3487 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3488                 symmetrized
3489 
3490     Output Parameters:
3491 +   n - size of (possibly compressed) matrix
3492 .   ia - the row pointers
3493 .   ja - the column indices
3494 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
3495 
3496     Level: developer
3497 
3498 .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
3499 @*/
3500 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3501 {
3502   int ierr;
3503 
3504   PetscFunctionBegin;
3505   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3506   if (ia) PetscValidIntPointer(ia);
3507   if (ja) PetscValidIntPointer(ja);
3508   PetscValidIntPointer(done);
3509 
3510   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
3511   else {
3512     *done = PETSC_TRUE;
3513     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
3514   }
3515   PetscFunctionReturn(0);
3516 }
3517 
3518 #undef __FUNC__
3519 #define __FUNC__ "MatRestoreColumnIJ"
3520 /*@C
3521     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
3522     MatGetColumnIJ().
3523 
3524     Collective on Mat
3525 
3526     Input Parameters:
3527 +   mat - the matrix
3528 .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3529 -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3530                 symmetrized
3531 
3532     Output Parameters:
3533 +   n - size of (possibly compressed) matrix
3534 .   ia - the column pointers
3535 .   ja - the row indices
3536 -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
3537 
3538     Level: developer
3539 
3540 .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
3541 @*/
3542 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3543 {
3544   int ierr;
3545 
3546   PetscFunctionBegin;
3547   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3548   if (ia) PetscValidIntPointer(ia);
3549   if (ja) PetscValidIntPointer(ja);
3550   PetscValidIntPointer(done);
3551 
3552   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
3553   else {
3554     *done = PETSC_TRUE;
3555     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr);
3556   }
3557   PetscFunctionReturn(0);
3558 }
3559 
3560 #undef __FUNC__
3561 #define __FUNC__ "MatColoringPatch"
3562 /*@C
3563     MatColoringPatch -Used inside matrix coloring routines that
3564     use MatGetRowIJ() and/or MatGetColumnIJ().
3565 
3566     Collective on Mat
3567 
3568     Input Parameters:
3569 +   mat - the matrix
3570 .   n   - number of colors
3571 -   colorarray - array indicating color for each column
3572 
3573     Output Parameters:
3574 .   iscoloring - coloring generated using colorarray information
3575 
3576     Level: developer
3577 
3578 .seealso: MatGetRowIJ(), MatGetColumnIJ()
3579 
3580 .keywords: mat, coloring, patch
3581 @*/
3582 int MatColoringPatch(Mat mat,int n,int *colorarray,ISColoring *iscoloring)
3583 {
3584   int ierr;
3585 
3586   PetscFunctionBegin;
3587   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3588   PetscValidIntPointer(colorarray);
3589 
3590   if (!mat->ops->coloringpatch) {SETERRQ(PETSC_ERR_SUP,0,"");}
3591   else {
3592     ierr  = (*mat->ops->coloringpatch)(mat,n,colorarray,iscoloring);CHKERRQ(ierr);
3593   }
3594   PetscFunctionReturn(0);
3595 }
3596 
3597 
3598 #undef __FUNC__
3599 #define __FUNC__ "MatSetUnfactored"
3600 /*@
3601    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
3602 
3603    Collective on Mat
3604 
3605    Input Parameter:
3606 .  mat - the factored matrix to be reset
3607 
3608    Notes:
3609    This routine should be used only with factored matrices formed by in-place
3610    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
3611    format).  This option can save memory, for example, when solving nonlinear
3612    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
3613    ILU(0) preconditioner.
3614 
3615    Note that one can specify in-place ILU(0) factorization by calling
3616 .vb
3617      PCType(pc,PCILU);
3618      PCILUSeUseInPlace(pc);
3619 .ve
3620    or by using the options -pc_type ilu -pc_ilu_in_place
3621 
3622    In-place factorization ILU(0) can also be used as a local
3623    solver for the blocks within the block Jacobi or additive Schwarz
3624    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion
3625    of these preconditioners in the users manual for details on setting
3626    local solver options.
3627 
3628    Most users should employ the simplified SLES interface for linear solvers
3629    instead of working directly with matrix algebra routines such as this.
3630    See, e.g., SLESCreate().
3631 
3632    Level: developer
3633 
3634 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()
3635 
3636 .keywords: matrix-free, in-place ILU, in-place LU
3637 @*/
3638 int MatSetUnfactored(Mat mat)
3639 {
3640   int ierr;
3641 
3642   PetscFunctionBegin;
3643   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3644   mat->factor = 0;
3645   if (!mat->ops->setunfactored) PetscFunctionReturn(0);
3646   ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr);
3647   PetscFunctionReturn(0);
3648 }
3649 
3650 #undef __FUNC__
3651 #define __FUNC__ "MatGetType"
3652 /*@C
3653    MatGetType - Gets the matrix type and name (as a string) from the matrix.
3654 
3655    Not Collective
3656 
3657    Input Parameter:
3658 .  mat - the matrix
3659 
3660    Output Parameter:
3661 +  type - the matrix type (or use PETSC_NULL)
3662 -  name - name of matrix type (or use PETSC_NULL)
3663 
3664    Level: intermediate
3665 
3666 .keywords: matrix, get, type, name
3667 @*/
3668 int MatGetType(Mat mat,MatType *type,char **name)
3669 {
3670   int  itype = (int)mat->type;
3671   char *matname[10];
3672 
3673   PetscFunctionBegin;
3674   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3675 
3676   if (type) *type = (MatType) mat->type;
3677   if (name) {
3678     /* Note:  Be sure that this list corresponds to the enum in mat.h */
3679     matname[0] = "MATSEQDENSE";
3680     matname[1] = "MATSEQAIJ";
3681     matname[2] = "MATMPIAIJ";
3682     matname[3] = "MATSHELL";
3683     matname[4] = "MATMPIROWBS";
3684     matname[5] = "MATSEQBDIAG";
3685     matname[6] = "MATMPIBDIAG";
3686     matname[7] = "MATMPIDENSE";
3687     matname[8] = "MATSEQBAIJ";
3688     matname[9] = "MATMPIBAIJ";
3689 
3690     if (itype < 0 || itype > 9) *name = "Unknown matrix type";
3691     else                        *name = matname[itype];
3692   }
3693   PetscFunctionReturn(0);
3694 }
3695 
3696 /*MC
3697     MatGetArrayF90 - Accesses a matrix array from Fortran90.
3698 
3699     Synopsis:
3700     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
3701 
3702     Not collective
3703 
3704     Input Parameter:
3705 .   x - matrix
3706 
3707     Output Parameters:
3708 +   xx_v - the Fortran90 pointer to the array
3709 -   ierr - error code
3710 
3711     Example of Usage:
3712 .vb
3713       Scalar, pointer xx_v(:)
3714       ....
3715       call MatGetArrayF90(x,xx_v,ierr)
3716       a = xx_v(3)
3717       call MatRestoreArrayF90(x,xx_v,ierr)
3718 .ve
3719 
3720     Notes:
3721     Not yet supported for all F90 compilers
3722 
3723     Level: advanced
3724 
3725 .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()
3726 
3727 .keywords:  matrix, array, f90
3728 M*/
3729 
3730 /*MC
3731     MatRestoreArrayF90 - Restores a matrix array that has been
3732     accessed with MatGetArrayF90().
3733 
3734     Synopsis:
3735     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
3736 
3737     Not collective
3738 
3739     Input Parameters:
3740 +   x - matrix
3741 -   xx_v - the Fortran90 pointer to the array
3742 
3743     Output Parameter:
3744 .   ierr - error code
3745 
3746     Example of Usage:
3747 .vb
3748        Scalar, pointer xx_v(:)
3749        ....
3750        call MatGetArrayF90(x,xx_v,ierr)
3751        a = xx_v(3)
3752        call MatRestoreArrayF90(x,xx_v,ierr)
3753 .ve
3754 
3755     Notes:
3756     Not yet supported for all F90 compilers
3757 
3758     Level: advanced
3759 
3760 .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()
3761 
3762 .keywords:  matrix, array, f90
3763 M*/
3764 
3765 
3766 #undef __FUNC__
3767 #define __FUNC__ "MatGetSubMatrix"
3768 /*@
3769     MatGetSubMatrix - Gets a single submatrix on the same number of processors
3770                       as the original matrix.
3771 
3772     Collective on Mat
3773 
3774     Input Parameters:
3775 +   mat - the original matrix
3776 .   isrow - rows this processor should obtain
3777 .   iscol - columns for all processors you wish to keep
3778 .   csize - number of columns "local" to this processor (does nothing for sequential
3779             matrices). This should match the result from VecGetLocalSize(x,...) if you
3780             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
3781 -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
3782 
3783     Output Parameter:
3784 .   newmat - the new submatrix, of the same type as the old
3785 
3786     Level: advanced
3787 
3788 .keywords: matrix, get, submatrix, submatrices
3789 
3790 .seealso: MatGetSubMatrices()
3791 @*/
3792 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
3793 {
3794   int     ierr, size;
3795   Mat     *local;
3796 
3797   PetscFunctionBegin;
3798   ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr);
3799 
3800   /* if original matrix is on just one processor then use submatrix generated */
3801   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
3802     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr);
3803     PetscFunctionReturn(0);
3804   } else if (!mat->ops->getsubmatrix && size == 1) {
3805     ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr);
3806     *newmat = *local;
3807     ierr = PetscFree(local);CHKERRQ(ierr);
3808     PetscFunctionReturn(0);
3809   }
3810 
3811   if (!mat->ops->getsubmatrix) SETERRQ(PETSC_ERR_SUP,0,"Not currently implemented");
3812   ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr);
3813   PetscFunctionReturn(0);
3814 }
3815 
3816 #undef __FUNC__
3817 #define __FUNC__ "MatGetMaps"
3818 /*@C
3819    MatGetMaps - Returns the maps associated with the matrix.
3820 
3821    Not Collective
3822 
3823    Input Parameter:
3824 .  mat - the matrix
3825 
3826    Output Parameters:
3827 +  rmap - the row (right) map
3828 -  cmap - the column (left) map
3829 
3830    Level: developer
3831 
3832 .keywords: matrix, get, map
3833 @*/
3834 int MatGetMaps(Mat mat,Map *rmap,Map *cmap)
3835 {
3836   int ierr;
3837 
3838   PetscFunctionBegin;
3839   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3840   ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr);
3841   PetscFunctionReturn(0);
3842 }
3843 
3844 /*
3845       Version that works for all PETSc matrices
3846 */
3847 #undef __FUNC__
3848 #define __FUNC__ "MatGetMaps_Petsc"
3849 int MatGetMaps_Petsc(Mat mat,Map *rmap,Map *cmap)
3850 {
3851   PetscFunctionBegin;
3852   if (rmap) *rmap = mat->rmap;
3853   if (cmap) *cmap = mat->cmap;
3854   PetscFunctionReturn(0);
3855 }
3856 
3857 #undef __FUNC__
3858 #define __FUNC__ "MatSetStashInitialSize"
3859 /*@
3860    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
3861    used during the assembly process to store values that belong to
3862    other processors.
3863 
3864    Not Collective
3865 
3866    Input Parameters:
3867 +  mat   - the matrix
3868 .  size  - the initial size of the stash.
3869 -  bsize - the initial size of the block-stash(if used).
3870 
3871    Options Database Keys:
3872 +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
3873 -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>
3874 
3875    Level: intermediate
3876 
3877    Notes:
3878      The block-stash is used for values set with VecSetValuesBlocked() while
3879      the stash is used for values set with VecSetValues()
3880 
3881      Run with the option -log_info and look for output of the form
3882      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
3883      to determine the appropriate value, MM, to use for size and
3884      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
3885      to determine the value, BMM to use for bsize
3886 
3887 .keywords: matrix, stash, assembly
3888 @*/
3889 int MatSetStashInitialSize(Mat mat,int size, int bsize)
3890 {
3891   int ierr;
3892 
3893   PetscFunctionBegin;
3894   PetscValidHeaderSpecific(mat,MAT_COOKIE);
3895   ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr);
3896   ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr);
3897   PetscFunctionReturn(0);
3898 }
3899