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