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