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