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