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