Actual source code: matrix.c

  1: /*$Id: matrix.c,v 1.414 2001/09/28 18:57:28 balay Exp $*/

  3: /*
  4:    This is where the abstract matrix operations are defined
  5: */

 7:  #include src/mat/matimpl.h
 8:  #include src/vec/vecimpl.h

 10: /* Logging support */
 11: int MAT_COOKIE;
 12: int MATSNESMFCTX_COOKIE;
 13: int MAT_Mult, MAT_MultMatrixFree, MAT_MultMultiple, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
 14: int MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_SolveMultiple, MAT_SolveAdd, MAT_SolveTranspose;
 15: int MAT_SolveTransposeAdd, MAT_Relax, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
 16: int MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
 17: int MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
 18: int MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering;
 19: int MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
 20: int MAT_FDColoringApply,MAT_Transpose;

 22: /*@C
 23:    MatGetRow - Gets a row of a matrix.  You MUST call MatRestoreRow()
 24:    for each row that you get to ensure that your application does
 25:    not bleed memory.

 27:    Not Collective

 29:    Input Parameters:
 30: +  mat - the matrix
 31: -  row - the row to get

 33:    Output Parameters:
 34: +  ncols -  the number of nonzeros in the row
 35: .  cols - if not NULL, the column numbers
 36: -  vals - if not NULL, the values

 38:    Notes:
 39:    This routine is provided for people who need to have direct access
 40:    to the structure of a matrix.  We hope that we provide enough
 41:    high-level matrix routines that few users will need it. 

 43:    MatGetRow() always returns 0-based column indices, regardless of
 44:    whether the internal representation is 0-based (default) or 1-based.

 46:    For better efficiency, set cols and/or vals to PETSC_NULL if you do
 47:    not wish to extract these quantities.

 49:    The user can only examine the values extracted with MatGetRow();
 50:    the values cannot be altered.  To change the matrix entries, one
 51:    must use MatSetValues().

 53:    You can only have one call to MatGetRow() outstanding for a particular
 54:    matrix at a time, per processor. MatGetRow() can only obtained rows
 55:    associated with the given processor, it cannot get rows from the 
 56:    other processors; for that we suggest using MatGetSubMatrices(), then
 57:    MatGetRow() on the submatrix. The row indix passed to MatGetRows() 
 58:    is in the global number of rows.

 60:    Fortran Notes:
 61:    The calling sequence from Fortran is 
 62: .vb
 63:    MatGetRow(matrix,row,ncols,cols,values,ierr)
 64:          Mat     matrix (input)
 65:          integer row    (input)
 66:          integer ncols  (output)
 67:          integer cols(maxcols) (output)
 68:          double precision (or double complex) values(maxcols) output
 69: .ve
 70:    where maxcols >= maximum nonzeros in any row of the matrix.

 72:    Caution:
 73:    Do not try to change the contents of the output arrays (cols and vals).
 74:    In some cases, this may corrupt the matrix.

 76:    Level: advanced

 78:    Concepts: matrices^row access

 80: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubmatrices(), MatGetDiagonal()
 81: @*/
 82: int MatGetRow(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals)
 83: {
 84:   int   ierr;

 90:   MatPreallocated(mat);
 91:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
 92:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
 93:   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
 94:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
 95:   (*mat->ops->getrow)(mat,row,ncols,cols,vals);
 96:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
 97:   return(0);
 98: }

100: /*@C  
101:    MatRestoreRow - Frees any temporary space allocated by MatGetRow().

103:    Not Collective

105:    Input Parameters:
106: +  mat - the matrix
107: .  row - the row to get
108: .  ncols, cols - the number of nonzeros and their columns
109: -  vals - if nonzero the column values

111:    Notes: 
112:    This routine should be called after you have finished examining the entries.

114:    Fortran Notes:
115:    The calling sequence from Fortran is 
116: .vb
117:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
118:       Mat     matrix (input)
119:       integer row    (input)
120:       integer ncols  (output)
121:       integer cols(maxcols) (output)
122:       double precision (or double complex) values(maxcols) output
123: .ve
124:    Where maxcols >= maximum nonzeros in any row of the matrix. 

126:    In Fortran MatRestoreRow() MUST be called after MatGetRow()
127:    before another call to MatGetRow() can be made.

129:    Level: advanced

131: .seealso:  MatGetRow()
132: @*/
133: int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals)
134: {

140:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
141:   if (!mat->ops->restorerow) return(0);
142:   (*mat->ops->restorerow)(mat,row,ncols,cols,vals);
143:   return(0);
144: }

146: /*@C
147:    MatView - Visualizes a matrix object.

149:    Collective on Mat

151:    Input Parameters:
152: +  mat - the matrix
153: -  ptr - visualization context

155:   Notes:
156:   The available visualization contexts include
157: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
158: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
159:         output where only the first processor opens
160:         the file.  All other processors send their 
161:         data to the first processor to print. 
162: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

164:    The user can open alternative visualization contexts with
165: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
166: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
167:          specified file; corresponding input uses MatLoad()
168: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to 
169:          an X window display
170: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
171:          Currently only the sequential dense and AIJ
172:          matrix types support the Socket viewer.

174:    The user can call PetscViewerSetFormat() to specify the output
175:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
176:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
177: +    PETSC_VIEWER_ASCII_DEFAULT - default, prints matrix contents
178: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
179: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
180: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 
181:          format common among all matrix types
182: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 
183:          format (which is in many cases the same as the default)
184: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
185:          size and structure (not the matrix entries)
186: -    PETSC_VIEWER_ASCII_INFO_LONG - prints more detailed information about
187:          the matrix structure

189:    Level: beginner

191:    Concepts: matrices^viewing
192:    Concepts: matrices^plotting
193:    Concepts: matrices^printing

195: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 
196:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
197: @*/
198: int MatView(Mat mat,PetscViewer viewer)
199: {
200:   int               ierr,rows,cols;
201:   PetscTruth        isascii;
202:   char              *cstr;
203:   PetscViewerFormat format;

208:   MatPreallocated(mat);
209:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mat->comm);
212:   if (!mat->assembled) SETERRQ(1,"Must call MatAssemblyBegin/End() before viewing matrix");

214:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
215:   if (isascii) {
216:     PetscViewerGetFormat(viewer,&format);
217:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
218:       if (mat->prefix) {
219:         PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)n",mat->prefix);
220:       } else {
221:         PetscViewerASCIIPrintf(viewer,"Matrix Object:n");
222:       }
223:       PetscViewerASCIIPushTab(viewer);
224:       MatGetType(mat,&cstr);
225:       MatGetSize(mat,&rows,&cols);
226:       PetscViewerASCIIPrintf(viewer,"type=%s, rows=%d, cols=%dn",cstr,rows,cols);
227:       if (mat->ops->getinfo) {
228:         MatInfo info;
229:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
230:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%d, allocated nonzeros=%dn",
231:                           (int)info.nz_used,(int)info.nz_allocated);
232:       }
233:     }
234:   }
235:   if (mat->ops->view) {
236:     PetscViewerASCIIPushTab(viewer);
237:     (*mat->ops->view)(mat,viewer);
238:     PetscViewerASCIIPopTab(viewer);
239:   } else if (!isascii) {
240:     SETERRQ1(1,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
241:   }
242:   if (isascii) {
243:     PetscViewerGetFormat(viewer,&format);
244:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
245:       PetscViewerASCIIPopTab(viewer);
246:     }
247:   }
248:   return(0);
249: }

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

257:    Input Parameter:
258: +  mat - the matrix
259: .  x - solution vector (or PETSC_NULL)
260: +  b - right hand side vector (or PETSC_NULL)


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.

268:    The SLES methods automatically call this routine when required
269:    (via PCPreSolve()) so it is rarely used directly.

271:    Level: Developer            

273:    Concepts: matrices^scaling

275: .seealso: MatUseScaledForm(), MatUnScaleSystem()
276: @*/
277: int MatScaleSystem(Mat mat,Vec x,Vec b)
278: {

284:   MatPreallocated(mat);

288:   if (mat->ops->scalesystem) {
289:     (*mat->ops->scalesystem)(mat,x,b);
290:   }
291:   return(0);
292: }

294: /*@C
295:    MatUnScaleSystem - Unscales a vector solution and right hand side to 
296:    match the original scaling of a scaled matrix.
297:   
298:    Collective on Mat

300:    Input Parameter:
301: +  mat - the matrix
302: .  x - solution vector (or PETSC_NULL)
303: +  b - right hand side vector (or PETSC_NULL)


306:    Notes: 
307:    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not 
308:    internally scaled, so this does nothing. For MPIROWBS it
309:    permutes and diagonally scales.

311:    The SLES methods automatically call this routine when required
312:    (via PCPreSolve()) so it is rarely used directly.

314:    Level: Developer            

316: .seealso: MatUseScaledForm(), MatScaleSystem()
317: @*/
318: int MatUnScaleSystem(Mat mat,Vec x,Vec b)
319: {

325:   MatPreallocated(mat);
328:   if (mat->ops->unscalesystem) {
329:     (*mat->ops->unscalesystem)(mat,x,b);
330:   }
331:   return(0);
332: }

334: /*@C
335:    MatUseScaledForm - For matrix storage formats that scale the 
336:    matrix (for example MPIRowBS matrices are diagonally scaled on
337:    assembly) indicates matrix operations (MatMult() etc) are 
338:    applied using the scaled matrix.
339:   
340:    Collective on Mat

342:    Input Parameter:
343: +  mat - the matrix
344: -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for 
345:             applying the original matrix

347:    Notes: 
348:    For scaled matrix formats, applying the original, unscaled matrix
349:    will be slightly more expensive

351:    Level: Developer            

353: .seealso: MatScaleSystem(), MatUnScaleSystem()
354: @*/
355: int MatUseScaledForm(Mat mat,PetscTruth scaled)
356: {

362:   MatPreallocated(mat);
363:   if (mat->ops->usescaledform) {
364:     (*mat->ops->usescaledform)(mat,scaled);
365:   }
366:   return(0);
367: }

369: /*@C
370:    MatDestroy - Frees space taken by a matrix.
371:   
372:    Collective on Mat

374:    Input Parameter:
375: .  A - the matrix

377:    Level: beginner

379: @*/
380: int MatDestroy(Mat A)
381: {

387:   MatPreallocated(A);
388:   if (--A->refct > 0) return(0);

390:   /* if memory was published with AMS then destroy it */
391:   PetscObjectDepublish(A);
392:   if (A->mapping) {
393:     ISLocalToGlobalMappingDestroy(A->mapping);
394:   }
395:   if (A->bmapping) {
396:     ISLocalToGlobalMappingDestroy(A->bmapping);
397:   }
398:   if (A->rmap) {
399:     PetscMapDestroy(A->rmap);
400:   }
401:   if (A->cmap) {
402:     PetscMapDestroy(A->cmap);
403:   }

405:   (*A->ops->destroy)(A);
406:   PetscLogObjectDestroy(A);
407:   PetscHeaderDestroy(A);
408:   return(0);
409: }

411: /*@
412:    MatValid - Checks whether a matrix object is valid.

414:    Collective on Mat

416:    Input Parameter:
417: .  m - the matrix to check 

419:    Output Parameter:
420:    flg - flag indicating matrix status, either
421:    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.

423:    Level: developer

425:    Concepts: matrices^validity
426: @*/
427: int MatValid(Mat m,PetscTruth *flg)
428: {
431:   if (!m)                           *flg = PETSC_FALSE;
432:   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
433:   else                              *flg = PETSC_TRUE;
434:   return(0);
435: }

437: /*@ 
438:    MatSetValues - Inserts or adds a block of values into a matrix.
439:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 
440:    MUST be called after all calls to MatSetValues() have been completed.

442:    Not Collective

444:    Input Parameters:
445: +  mat - the matrix
446: .  v - a logically two-dimensional array of values
447: .  m, idxm - the number of rows and their global indices 
448: .  n, idxn - the number of columns and their global indices
449: -  addv - either ADD_VALUES or INSERT_VALUES, where
450:    ADD_VALUES adds values to any existing entries, and
451:    INSERT_VALUES replaces existing entries with new values

453:    Notes:
454:    By default the values, v, are row-oriented and unsorted.
455:    See MatSetOption() for other options.

457:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 
458:    options cannot be mixed without intervening calls to the assembly
459:    routines.

461:    MatSetValues() uses 0-based row and column numbers in Fortran 
462:    as well as in C.

464:    Negative indices may be passed in idxm and idxn, these rows and columns are 
465:    simply ignored. This allows easily inserting element stiffness matrices
466:    with homogeneous Dirchlet boundary conditions that you don't want represented
467:    in the matrix.

469:    Efficiency Alert:
470:    The routine MatSetValuesBlocked() may offer much better efficiency
471:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

473:    Level: beginner

475:    Concepts: matrices^putting entries in

477: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
478: @*/
479: int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v,InsertMode addv)
480: {

484:   if (!m || !n) return(0); /* no values to insert */
487:   MatPreallocated(mat);
491:   if (mat->insertmode == NOT_SET_VALUES) {
492:     mat->insertmode = addv;
493:   }
494: #if defined(PETSC_USE_BOPT_g)
495:   else if (mat->insertmode != addv) {
496:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
497:   }
498:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
499: #endif

501:   if (mat->assembled) {
502:     mat->was_assembled = PETSC_TRUE;
503:     mat->assembled     = PETSC_FALSE;
504:   }
505:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
506:   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
507:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
508:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
509:   return(0);
510: }

512: /*@C 
513:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
514:      Using structured grid indexing

516:    Not Collective

518:    Input Parameters:
519: +  mat - the matrix
520: .  v - a logically two-dimensional array of values
521: .  m - number of rows being entered
522: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
523: .  n - number of columns being entered
524: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 
525: -  addv - either ADD_VALUES or INSERT_VALUES, where
526:    ADD_VALUES adds values to any existing entries, and
527:    INSERT_VALUES replaces existing entries with new values

529:    Notes:
530:    By default the values, v, are row-oriented and unsorted.
531:    See MatSetOption() for other options.

533:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 
534:    options cannot be mixed without intervening calls to the assembly
535:    routines.

537:    The grid coordinates are across the entire grid, not just the local portion

539:    MatSetValuesStencil() uses 0-based row and column numbers in Fortran 
540:    as well as in C.

542:    In order to use this routine you must either obtain the matrix with DAGetMatrix()
543:    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.

545:    In Fortran idxm and idxn should be declared as
546: $     MatStencil idxm(4,m),idxn(4,n)
547:    and the values inserted using
548: $    idxm(MatStencil_i,1) = i
549: $    idxm(MatStencil_j,1) = j
550: $    idxm(MatStencil_k,1) = k
551: $    idxm(MatStencil_c,1) = c
552:    etc

554:    Negative indices may be passed in idxm and idxn, these rows and columns are 
555:    simply ignored. This allows easily inserting element stiffness matrices
556:    with homogeneous Dirchlet boundary conditions that you don't want represented
557:    in the matrix.

559:    Inspired by the structured grid interface to the HYPRE package
560:    (http://www.llnl.gov/CASC/hypre)

562:    Efficiency Alert:
563:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
564:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

566:    Level: beginner

568:    Concepts: matrices^putting entries in

570: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
571:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix()
572: @*/
573: int MatSetValuesStencil(Mat mat,int m,MatStencil *idxm,int n,MatStencil *idxn,PetscScalar *v,InsertMode addv)
574: {
575:   int j,i,ierr,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
576:   int *starts = mat->stencil.starts,*dxm = (int*)idxm,*dxn = (int*)idxn,sdim = dim - (1 - (int)mat->stencil.noc);

579:   if (!m || !n) return(0); /* no values to insert */

586:   if (m > 128) SETERRQ1(1,"Can only set 128 rows at a time; trying to set %d",m);
587:   if (n > 128) SETERRQ1(1,"Can only set 256 columns at a time; trying to set %d",n);

589:   for (i=0; i<m; i++) {
590:     for (j=0; j<3-sdim; j++) dxm++;
591:     tmp = *dxm++ - starts[0];
592:     for (j=0; j<dim-1; j++) {
593:       tmp = tmp*dims[j] + *dxm++ - starts[j+1];
594:     }
595:     if (mat->stencil.noc) dxm++;
596:     jdxm[i] = tmp;
597:   }
598:   for (i=0; i<n; i++) {
599:     for (j=0; j<3-sdim; j++) dxn++;
600:     tmp = *dxn++ - starts[0];
601:     for (j=0; j<dim-1; j++) {
602:       tmp = tmp*dims[j] + *dxn++ - starts[j+1];
603:     }
604:     if (mat->stencil.noc) dxn++;
605:     jdxn[i] = tmp;
606:   }
607:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
608:   return(0);
609: }

611: /*@ 
612:    MatSetStencil - Sets the grid information for setting values into a matrix via
613:         MatSetStencil()

615:    Not Collective

617:    Input Parameters:
618: +  mat - the matrix
619: .  dim - dimension of the grid 1,2, or 3
620: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
621: .  starts - starting point of ghost nodes on your processor in x, y, and z direction 
622: -  dof - number of degrees of freedom per node


625:    Inspired by the structured grid interface to the HYPRE package
626:    (www.llnl.gov/CASC/hyper)

628:    Level: beginner

630:    Concepts: matrices^putting entries in

632: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
633:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
634: @*/
635: int MatSetStencil(Mat mat,int dim,int *dims,int *starts,int dof)
636: {
637:   int i;


644:   mat->stencil.dim = dim + (dof > 1);
645:   for (i=0; i<dim; i++) {
646:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
647:     mat->stencil.starts[i] = starts[dim-i-1];
648:   }
649:   mat->stencil.dims[dim]   = dof;
650:   mat->stencil.starts[dim] = 0;
651:   mat->stencil.noc         = (PetscTruth)(dof == 1);
652:   return(0);
653: }

655: /*@ 
656:    MatSetValuesBlocked - Inserts or adds a block of values into a matrix.

658:    Not Collective

660:    Input Parameters:
661: +  mat - the matrix
662: .  v - a logically two-dimensional array of values
663: .  m, idxm - the number of block rows and their global block indices 
664: .  n, idxn - the number of block columns and their global block indices
665: -  addv - either ADD_VALUES or INSERT_VALUES, where
666:    ADD_VALUES adds values to any existing entries, and
667:    INSERT_VALUES replaces existing entries with new values

669:    Notes:
670:    By default the values, v, are row-oriented and unsorted. So the layout of 
671:    v is the same as for MatSetValues(). See MatSetOption() for other options.

673:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
674:    options cannot be mixed without intervening calls to the assembly
675:    routines.

677:    MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 
678:    as well as in C.

680:    Negative indices may be passed in idxm and idxn, these rows and columns are 
681:    simply ignored. This allows easily inserting element stiffness matrices
682:    with homogeneous Dirchlet boundary conditions that you don't want represented
683:    in the matrix.

685:    Each time an entry is set within a sparse matrix via MatSetValues(),
686:    internal searching must be done to determine where to place the the
687:    data in the matrix storage space.  By instead inserting blocks of 
688:    entries via MatSetValuesBlocked(), the overhead of matrix assembly is
689:    reduced.

691:    Restrictions:
692:    MatSetValuesBlocked() is currently supported only for the block AIJ
693:    matrix format (MATSEQBAIJ and MATMPIBAIJ, which are created via
694:    MatCreateSeqBAIJ() and MatCreateMPIBAIJ()).

696:    Level: intermediate

698:    Concepts: matrices^putting entries in blocked

700: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
701: @*/
702: int MatSetValuesBlocked(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v,InsertMode addv)
703: {

707:   if (!m || !n) return(0); /* no values to insert */
710:   MatPreallocated(mat);
714:   if (mat->insertmode == NOT_SET_VALUES) {
715:     mat->insertmode = addv;
716:   }
717: #if defined(PETSC_USE_BOPT_g) 
718:   else if (mat->insertmode != addv) {
719:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
720:   }
721:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
722: #endif

724:   if (mat->assembled) {
725:     mat->was_assembled = PETSC_TRUE;
726:     mat->assembled     = PETSC_FALSE;
727:   }
728:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
729:   if (!mat->ops->setvaluesblocked) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
730:   (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
731:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
732:   return(0);
733: }

735: /*MC
736:    MatSetValue - Set a single entry into a matrix.

738:    Synopsis:
739:    int MatSetValue(Mat m,int row,int col,PetscScalar value,InsertMode mode);

741:    Not collective

743:    Input Parameters:
744: +  m - the matrix
745: .  row - the row location of the entry
746: .  col - the column location of the entry
747: .  value - the value to insert
748: -  mode - either INSERT_VALUES or ADD_VALUES

750:    Notes: 
751:    For efficiency one should use MatSetValues() and set several or many
752:    values simultaneously if possible.

754:    Note that VecSetValue() does NOT return an error code (since this
755:    is checked internally).

757:    Level: beginner

759: .seealso: MatSetValues()
760: M*/

762: /*@ 
763:    MatGetValues - Gets a block of values from a matrix.

765:    Not Collective; currently only returns a local block

767:    Input Parameters:
768: +  mat - the matrix
769: .  v - a logically two-dimensional array for storing the values
770: .  m, idxm - the number of rows and their global indices 
771: -  n, idxn - the number of columns and their global indices

773:    Notes:
774:    The user must allocate space (m*n PetscScalars) for the values, v.
775:    The values, v, are then returned in a row-oriented format, 
776:    analogous to that used by default in MatSetValues().

778:    MatGetValues() uses 0-based row and column numbers in
779:    Fortran as well as in C.

781:    MatGetValues() requires that the matrix has been assembled
782:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
783:    MatSetValues() and MatGetValues() CANNOT be made in succession
784:    without intermediate matrix assembly.

786:    Level: advanced

788:    Concepts: matrices^accessing values

790: .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
791: @*/
792: int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v)
793: {

799:   MatPreallocated(mat);
803:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
804:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
805:   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

807:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
808:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
809:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
810:   return(0);
811: }

813: /*@
814:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
815:    the routine MatSetValuesLocal() to allow users to insert matrix entries
816:    using a local (per-processor) numbering.

818:    Not Collective

820:    Input Parameters:
821: +  x - the matrix
822: -  mapping - mapping created with ISLocalToGlobalMappingCreate() 
823:              or ISLocalToGlobalMappingCreateIS()

825:    Level: intermediate

827:    Concepts: matrices^local to global mapping
828:    Concepts: local to global mapping^for matrices

830: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
831: @*/
832: int MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
833: {
838:   MatPreallocated(x);
840:   if (x->mapping) {
841:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
842:   }

844:   if (x->ops->setlocaltoglobalmapping) {
845:     (*x->ops->setlocaltoglobalmapping)(x,mapping);
846:   } else {
847:     x->mapping = mapping;
848:     PetscObjectReference((PetscObject)mapping);
849:   }
850:   return(0);
851: }

853: /*@
854:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
855:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
856:    entries using a local (per-processor) numbering.

858:    Not Collective

860:    Input Parameters:
861: +  x - the matrix
862: -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
863:              ISLocalToGlobalMappingCreateIS()

865:    Level: intermediate

867:    Concepts: matrices^local to global mapping blocked
868:    Concepts: local to global mapping^for matrices, blocked

870: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
871:            MatSetValuesBlocked(), MatSetValuesLocal()
872: @*/
873: int MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
874: {
879:   MatPreallocated(x);
881:   if (x->bmapping) {
882:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
883:   }
884: 
885:   x->bmapping = mapping;
886:   PetscObjectReference((PetscObject)mapping);
887:   return(0);
888: }

890: /*@
891:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
892:    using a local ordering of the nodes. 

894:    Not Collective

896:    Input Parameters:
897: +  x - the matrix
898: .  nrow, irow - number of rows and their local indices
899: .  ncol, icol - number of columns and their local indices
900: .  y -  a logically two-dimensional array of values
901: -  addv - either INSERT_VALUES or ADD_VALUES, where
902:    ADD_VALUES adds values to any existing entries, and
903:    INSERT_VALUES replaces existing entries with new values

905:    Notes:
906:    Before calling MatSetValuesLocal(), the user must first set the
907:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

909:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
910:    options cannot be mixed without intervening calls to the assembly
911:    routines.

913:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 
914:    MUST be called after all calls to MatSetValuesLocal() have been completed.

916:    Level: intermediate

918:    Concepts: matrices^putting entries in with local numbering

920: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
921:            MatSetValueLocal()
922: @*/
923: int MatSetValuesLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,PetscScalar *y,InsertMode addv)
924: {
925:   int ierr,irowm[2048],icolm[2048];

930:   MatPreallocated(mat);

935:   if (mat->insertmode == NOT_SET_VALUES) {
936:     mat->insertmode = addv;
937:   }
938: #if defined(PETSC_USE_BOPT_g) 
939:   else if (mat->insertmode != addv) {
940:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
941:   }
942:   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
943:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
944:   }
945:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
946: #endif

948:   if (mat->assembled) {
949:     mat->was_assembled = PETSC_TRUE;
950:     mat->assembled     = PETSC_FALSE;
951:   }
952:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
953:   if (!mat->ops->setvalueslocal) {
954:     ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);
955:     ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);
956:     (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);
957:   } else {
958:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
959:   }
960:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
961:   return(0);
962: }

964: /*@
965:    MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
966:    using a local ordering of the nodes a block at a time. 

968:    Not Collective

970:    Input Parameters:
971: +  x - the matrix
972: .  nrow, irow - number of rows and their local indices
973: .  ncol, icol - number of columns and their local indices
974: .  y -  a logically two-dimensional array of values
975: -  addv - either INSERT_VALUES or ADD_VALUES, where
976:    ADD_VALUES adds values to any existing entries, and
977:    INSERT_VALUES replaces existing entries with new values

979:    Notes:
980:    Before calling MatSetValuesBlockedLocal(), the user must first set the
981:    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
982:    where the mapping MUST be set for matrix blocks, not for matrix elements.

984:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
985:    options cannot be mixed without intervening calls to the assembly
986:    routines.

988:    These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 
989:    MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.

991:    Level: intermediate

993:    Concepts: matrices^putting blocked values in with local numbering

995: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
996: @*/
997: int MatSetValuesBlockedLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,PetscScalar *y,InsertMode addv)
998: {
999:   int ierr,irowm[2048],icolm[2048];

1004:   MatPreallocated(mat);
1008:   if (mat->insertmode == NOT_SET_VALUES) {
1009:     mat->insertmode = addv;
1010:   }
1011: #if defined(PETSC_USE_BOPT_g) 
1012:   else if (mat->insertmode != addv) {
1013:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1014:   }
1015:   if (!mat->bmapping) {
1016:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1017:   }
1018:   if (nrow > 2048 || ncol > 2048) {
1019:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
1020:   }
1021:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1022: #endif

1024:   if (mat->assembled) {
1025:     mat->was_assembled = PETSC_TRUE;
1026:     mat->assembled     = PETSC_FALSE;
1027:   }
1028:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1029:   ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);
1030:   ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);
1031:   (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);
1032:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1033:   return(0);
1034: }

1036: /* --------------------------------------------------------*/
1037: /*@
1038:    MatMult - Computes the matrix-vector product, y = Ax.

1040:    Collective on Mat and Vec

1042:    Input Parameters:
1043: +  mat - the matrix
1044: -  x   - the vector to be multilplied

1046:    Output Parameters:
1047: .  y - the result

1049:    Notes:
1050:    The vectors x and y cannot be the same.  I.e., one cannot
1051:    call MatMult(A,y,y).

1053:    Level: beginner

1055:    Concepts: matrix-vector product

1057: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1058: @*/
1059: int MatMult(Mat mat,Vec x,Vec y)
1060: {

1066:   MatPreallocated(mat);

1070:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1071:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1072:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1073: #ifndef PETSC_HAVE_CONSTRAINTS
1074:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1075:   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1076:   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1077: #endif

1079:   if (mat->nullsp) {
1080:     MatNullSpaceRemove(mat->nullsp,x,&x);
1081:   }

1083:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1084:   (*mat->ops->mult)(mat,x,y);
1085:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);

1087:   if (mat->nullsp) {
1088:     MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1089:   }
1090:   return(0);
1091: }

1093: /*@
1094:    MatMultTranspose - Computes matrix transpose times a vector.

1096:    Collective on Mat and Vec

1098:    Input Parameters:
1099: +  mat - the matrix
1100: -  x   - the vector to be multilplied

1102:    Output Parameters:
1103: .  y - the result

1105:    Notes:
1106:    The vectors x and y cannot be the same.  I.e., one cannot
1107:    call MatMultTranspose(A,y,y).

1109:    Level: beginner

1111:    Concepts: matrix vector product^transpose

1113: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1114: @*/
1115: int MatMultTranspose(Mat mat,Vec x,Vec y)
1116: {

1122:   MatPreallocated(mat);

1126:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1127:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1128:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1129: #ifndef PETSC_HAVE_CONSTRAINTS
1130:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1131:   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
1132: #endif

1134:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP, "Operation not supported");
1135:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1136:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1137:   (*mat->ops->multtranspose)(mat,x,y);
1138:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1139:   return(0);
1140: }

1142: /*@
1143:     MatMultAdd -  Computes v3 = v2 + A * v1.

1145:     Collective on Mat and Vec

1147:     Input Parameters:
1148: +   mat - the matrix
1149: -   v1, v2 - the vectors

1151:     Output Parameters:
1152: .   v3 - the result

1154:     Notes:
1155:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1156:     call MatMultAdd(A,v1,v2,v1).

1158:     Level: beginner

1160:     Concepts: matrix vector product^addition

1162: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1163: @*/
1164: int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1165: {

1171:   MatPreallocated(mat);

1176:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1177:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1178:   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N);
1179:   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N);
1180:   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N);
1181:   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n);
1182:   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n);
1183:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");

1185:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
1186:   (*mat->ops->multadd)(mat,v1,v2,v3);
1187:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
1188:   return(0);
1189: }

1191: /*@
1192:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

1194:    Collective on Mat and Vec

1196:    Input Parameters:
1197: +  mat - the matrix
1198: -  v1, v2 - the vectors

1200:    Output Parameters:
1201: .  v3 - the result

1203:    Notes:
1204:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1205:    call MatMultTransposeAdd(A,v1,v2,v1).

1207:    Level: beginner

1209:    Concepts: matrix vector product^transpose and addition

1211: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1212: @*/
1213: int MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1214: {

1220:   MatPreallocated(mat);

1225:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1226:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1227:   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1228:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1229:   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N);
1230:   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N);
1231:   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N);

1233:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
1234:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
1235:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
1236:   return(0);
1237: }

1239: /*@
1240:    MatMultConstrained - The inner multiplication routine for a
1241:    constrained matrix P^T A P.

1243:    Collective on Mat and Vec

1245:    Input Parameters:
1246: +  mat - the matrix
1247: -  x   - the vector to be multilplied

1249:    Output Parameters:
1250: .  y - the result

1252:    Notes:
1253:    The vectors x and y cannot be the same.  I.e., one cannot
1254:    call MatMult(A,y,y).

1256:    Level: beginner

1258: .keywords: matrix, multiply, matrix-vector product, constraint
1259: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1260: @*/
1261: int MatMultConstrained(Mat mat,Vec x,Vec y)
1262: {

1268:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1269:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1270:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1271:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1272:   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1273:   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);

1275:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1276:   (*mat->ops->multconstrained)(mat,x,y);
1277:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);

1279:   return(0);
1280: }

1282: /*@
1283:    MatMultTransposeConstrained - The inner multiplication routine for a
1284:    constrained matrix P^T A^T P.

1286:    Collective on Mat and Vec

1288:    Input Parameters:
1289: +  mat - the matrix
1290: -  x   - the vector to be multilplied

1292:    Output Parameters:
1293: .  y - the result

1295:    Notes:
1296:    The vectors x and y cannot be the same.  I.e., one cannot
1297:    call MatMult(A,y,y).

1299:    Level: beginner

1301: .keywords: matrix, multiply, matrix-vector product, constraint
1302: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1303: @*/
1304: int MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1305: {

1311:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1312:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1313:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1314:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1315:   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);

1317:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1318:   (*mat->ops->multtransposeconstrained)(mat,x,y);
1319:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);

1321:   return(0);
1322: }
1323: /* ------------------------------------------------------------*/
1324: /*@C
1325:    MatGetInfo - Returns information about matrix storage (number of
1326:    nonzeros, memory, etc.).

1328:    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1329:    as the flag

1331:    Input Parameters:
1332: .  mat - the matrix

1334:    Output Parameters:
1335: +  flag - flag indicating the type of parameters to be returned
1336:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1337:    MAT_GLOBAL_SUM - sum over all processors)
1338: -  info - matrix information context

1340:    Notes:
1341:    The MatInfo context contains a variety of matrix data, including
1342:    number of nonzeros allocated and used, number of mallocs during
1343:    matrix assembly, etc.  Additional information for factored matrices
1344:    is provided (such as the fill ratio, number of mallocs during
1345:    factorization, etc.).  Much of this info is printed to STDOUT
1346:    when using the runtime options 
1347: $       -log_info -mat_view_info

1349:    Example for C/C++ Users:
1350:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1351:    data within the MatInfo context.  For example, 
1352: .vb
1353:       MatInfo info;
1354:       Mat     A;
1355:       double  mal, nz_a, nz_u;

1357:       MatGetInfo(A,MAT_LOCAL,&info);
1358:       mal  = info.mallocs;
1359:       nz_a = info.nz_allocated;
1360: .ve

1362:    Example for Fortran Users:
1363:    Fortran users should declare info as a double precision
1364:    array of dimension MAT_INFO_SIZE, and then extract the parameters
1365:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1366:    a complete list of parameter names.
1367: .vb
1368:       double  precision info(MAT_INFO_SIZE)
1369:       double  precision mal, nz_a
1370:       Mat     A
1371:       integer ierr

1373:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1374:       mal = info(MAT_INFO_MALLOCS)
1375:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1376: .ve

1378:     Level: intermediate

1380:     Concepts: matrices^getting information on
1381:  
1382: @*/
1383: int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1384: {

1390:   MatPreallocated(mat);
1392:   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1393:   (*mat->ops->getinfo)(mat,flag,info);
1394:   return(0);
1395: }

1397: /* ----------------------------------------------------------*/
1398: /*@C  
1399:    MatILUDTFactor - Performs a drop tolerance ILU factorization.

1401:    Collective on Mat

1403:    Input Parameters:
1404: +  mat - the matrix
1405: .  info - information about the factorization to be done
1406: .  row - row permutation
1407: -  col - column permutation

1409:    Output Parameters:
1410: .  fact - the factored matrix

1412:    Level: developer

1414:    Notes:
1415:    Most users should employ the simplified SLES interface for linear solvers
1416:    instead of working directly with matrix algebra routines such as this.
1417:    See, e.g., SLESCreate().

1419:    This is currently only supported for the SeqAIJ matrix format using code
1420:    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
1421:    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
1422:    and thus can be distributed with PETSc.

1424:     Concepts: matrices^ILUDT factorization

1426: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo
1427: @*/
1428: int MatILUDTFactor(Mat mat,MatILUInfo *info,IS row,IS col,Mat *fact)
1429: {

1435:   MatPreallocated(mat);
1437:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1438:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1439:   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1441:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1442:   (*mat->ops->iludtfactor)(mat,info,row,col,fact);
1443:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);

1445:   return(0);
1446: }

1448: /*@  
1449:    MatLUFactor - Performs in-place LU factorization of matrix.

1451:    Collective on Mat

1453:    Input Parameters:
1454: +  mat - the matrix
1455: .  row - row permutation
1456: .  col - column permutation
1457: -  info - options for factorization, includes 
1458: $          fill - expected fill as ratio of original fill.
1459: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1460: $                   Run with the option -log_info to determine an optimal value to use

1462:    Notes:
1463:    Most users should employ the simplified SLES interface for linear solvers
1464:    instead of working directly with matrix algebra routines such as this.
1465:    See, e.g., SLESCreate().

1467:    This changes the state of the matrix to a factored matrix; it cannot be used
1468:    for example with MatSetValues() unless one first calls MatSetUnfactored().

1470:    Level: developer

1472:    Concepts: matrices^LU factorization

1474: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1475:           MatGetOrdering(), MatSetUnfactored(), MatLUInfo

1477: @*/
1478: int MatLUFactor(Mat mat,IS row,IS col,MatLUInfo *info)
1479: {

1485:   MatPreallocated(mat);
1486:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1487:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1488:   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1490:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
1491:   (*mat->ops->lufactor)(mat,row,col,info);
1492:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
1493:   return(0);
1494: }

1496: /*@  
1497:    MatILUFactor - Performs in-place ILU factorization of matrix.

1499:    Collective on Mat

1501:    Input Parameters:
1502: +  mat - the matrix
1503: .  row - row permutation
1504: .  col - column permutation
1505: -  info - structure containing 
1506: $      levels - number of levels of fill.
1507: $      expected fill - as ratio of original fill.
1508: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1509:                 missing diagonal entries)

1511:    Notes: 
1512:    Probably really in-place only when level of fill is zero, otherwise allocates
1513:    new space to store factored matrix and deletes previous memory.

1515:    Most users should employ the simplified SLES interface for linear solvers
1516:    instead of working directly with matrix algebra routines such as this.
1517:    See, e.g., SLESCreate().

1519:    Level: developer

1521:    Concepts: matrices^ILU factorization

1523: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo
1524: @*/
1525: int MatILUFactor(Mat mat,IS row,IS col,MatILUInfo *info)
1526: {

1532:   MatPreallocated(mat);
1533:   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1534:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1535:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1536:   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1538:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1539:   (*mat->ops->ilufactor)(mat,row,col,info);
1540:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
1541:   return(0);
1542: }

1544: /*@  
1545:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1546:    Call this routine before calling MatLUFactorNumeric().

1548:    Collective on Mat

1550:    Input Parameters:
1551: +  mat - the matrix
1552: .  row, col - row and column permutations
1553: -  info - options for factorization, includes 
1554: $          fill - expected fill as ratio of original fill.
1555: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1556: $                   Run with the option -log_info to determine an optimal value to use

1558:    Output Parameter:
1559: .  fact - new matrix that has been symbolically factored

1561:    Notes:
1562:    See the users manual for additional information about
1563:    choosing the fill factor for better efficiency.

1565:    Most users should employ the simplified SLES interface for linear solvers
1566:    instead of working directly with matrix algebra routines such as this.
1567:    See, e.g., SLESCreate().

1569:    Level: developer

1571:    Concepts: matrices^LU symbolic factorization

1573: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatLUInfo
1574: @*/
1575: int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatLUInfo *info,Mat *fact)
1576: {

1582:   MatPreallocated(mat);
1586:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1587:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1588:   if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",mat->type_name);

1590:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
1591:   (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);
1592:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
1593:   return(0);
1594: }

1596: /*@  
1597:    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1598:    Call this routine after first calling MatLUFactorSymbolic().

1600:    Collective on Mat

1602:    Input Parameters:
1603: +  mat - the matrix
1604: -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()

1606:    Notes:
1607:    See MatLUFactor() for in-place factorization.  See 
1608:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

1610:    Most users should employ the simplified SLES interface for linear solvers
1611:    instead of working directly with matrix algebra routines such as this.
1612:    See, e.g., SLESCreate().

1614:    Level: developer

1616:    Concepts: matrices^LU numeric factorization

1618: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1619: @*/
1620: int MatLUFactorNumeric(Mat mat,Mat *fact)
1621: {
1622:   int        ierr;
1623:   PetscTruth flg;

1628:   MatPreallocated(mat);
1631:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1632:   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1633:     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1634:             mat->M,(*fact)->M,mat->N,(*fact)->N);
1635:   }
1636:   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1638:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);
1639:   (*(*fact)->ops->lufactornumeric)(mat,fact);
1640:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);
1641:   PetscOptionsHasName(PETSC_NULL,"-mat_view_draw",&flg);
1642:   if (flg) {
1643:     PetscOptionsHasName(PETSC_NULL,"-mat_view_contour",&flg);
1644:     if (flg) {
1645:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);
1646:     }
1647:     MatView(*fact,PETSC_VIEWER_DRAW_(mat->comm));
1648:     PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));
1649:     if (flg) {
1650:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));
1651:     }
1652:   }
1653:   return(0);
1654: }

1656: /*@  
1657:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1658:    symmetric matrix. 

1660:    Collective on Mat

1662:    Input Parameters:
1663: +  mat - the matrix
1664: .  perm - row and column permutations
1665: -  f - expected fill as ratio of original fill

1667:    Notes:
1668:    See MatLUFactor() for the nonsymmetric case.  See also
1669:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

1671:    Most users should employ the simplified SLES interface for linear solvers
1672:    instead of working directly with matrix algebra routines such as this.
1673:    See, e.g., SLESCreate().

1675:    Level: developer

1677:    Concepts: matrices^Cholesky factorization

1679: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1680:           MatGetOrdering()

1682: @*/
1683: int MatCholeskyFactor(Mat mat,IS perm,PetscReal f)
1684: {

1690:   MatPreallocated(mat);
1692:   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1693:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1694:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1695:   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1697:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
1698:   (*mat->ops->choleskyfactor)(mat,perm,f);
1699:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
1700:   return(0);
1701: }

1703: /*@  
1704:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1705:    of a symmetric matrix. 

1707:    Collective on Mat

1709:    Input Parameters:
1710: +  mat - the matrix
1711: .  perm - row and column permutations
1712: -  f - expected fill as ratio of original

1714:    Output Parameter:
1715: .  fact - the factored matrix

1717:    Notes:
1718:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1719:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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().

1725:    Level: developer

1727:    Concepts: matrices^Cholesky symbolic factorization

1729: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1730:           MatGetOrdering()

1732: @*/
1733: int MatCholeskyFactorSymbolic(Mat mat,IS perm,PetscReal f,Mat *fact)
1734: {

1740:   MatPreallocated(mat);
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->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1747:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1748:   (*mat->ops->choleskyfactorsymbolic)(mat,perm,f,fact);
1749:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1750:   return(0);
1751: }

1753: /*@  
1754:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1755:    of a symmetric matrix. Call this routine after first calling
1756:    MatCholeskyFactorSymbolic().

1758:    Collective on Mat

1760:    Input Parameter:
1761: .  mat - the initial matrix

1763:    Output Parameter:
1764: .  fact - the factored matrix

1766:    Notes:
1767:    Most users should employ the simplified SLES interface for linear solvers
1768:    instead of working directly with matrix algebra routines such as this.
1769:    See, e.g., SLESCreate().

1771:    Level: developer

1773:    Concepts: matrices^Cholesky numeric factorization

1775: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1776: @*/
1777: int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1778: {

1784:   MatPreallocated(mat);
1786:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1787:   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1788:   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1789:     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1790:             mat->M,(*fact)->M,mat->N,(*fact)->N);
1791:   }

1793:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1794:   (*(*fact)->ops->choleskyfactornumeric)(mat,fact);
1795:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1796:   return(0);
1797: }

1799: /* ----------------------------------------------------------------*/
1800: /*@
1801:    MatSolve - Solves A x = b, given a factored matrix.

1803:    Collective on Mat and Vec

1805:    Input Parameters:
1806: +  mat - the factored matrix
1807: -  b - the right-hand-side vector

1809:    Output Parameter:
1810: .  x - the result vector

1812:    Notes:
1813:    The vectors b and x cannot be the same.  I.e., one cannot
1814:    call MatSolve(A,x,x).

1816:    Notes:
1817:    Most users should employ the simplified SLES interface for linear solvers
1818:    instead of working directly with matrix algebra routines such as this.
1819:    See, e.g., SLESCreate().

1821:    Level: developer

1823:    Concepts: matrices^triangular solves

1825: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
1826: @*/
1827: int MatSolve(Mat mat,Vec b,Vec x)
1828: {

1834:   MatPreallocated(mat);
1839:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1840:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1841:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1842:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1843:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
1844:   if (mat->M == 0 && mat->N == 0) return(0);

1846:   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1847:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
1848:   (*mat->ops->solve)(mat,b,x);
1849:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
1850:   return(0);
1851: }

1853: /* @
1854:    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU.

1856:    Collective on Mat and Vec

1858:    Input Parameters:
1859: +  mat - the factored matrix
1860: -  b - the right-hand-side vector

1862:    Output Parameter:
1863: .  x - the result vector

1865:    Notes:
1866:    MatSolve() should be used for most applications, as it performs
1867:    a forward solve followed by a backward solve.

1869:    The vectors b and x cannot be the same.  I.e., one cannot
1870:    call MatForwardSolve(A,x,x).

1872:    Most users should employ the simplified SLES interface for linear solvers
1873:    instead of working directly with matrix algebra routines such as this.
1874:    See, e.g., SLESCreate().

1876:    Level: developer

1878:    Concepts: matrices^forward solves

1880: .seealso: MatSolve(), MatBackwardSolve()
1881: @ */
1882: int MatForwardSolve(Mat mat,Vec b,Vec x)
1883: {

1889:   MatPreallocated(mat);
1894:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1895:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1896:   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
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);

1901:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
1902:   (*mat->ops->forwardsolve)(mat,b,x);
1903:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
1904:   return(0);
1905: }

1907: /* @
1908:    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.

1910:    Collective on Mat and Vec

1912:    Input Parameters:
1913: +  mat - the factored matrix
1914: -  b - the right-hand-side vector

1916:    Output Parameter:
1917: .  x - the result vector

1919:    Notes:
1920:    MatSolve() should be used for most applications, as it performs
1921:    a forward solve followed by a backward solve.

1923:    The vectors b and x cannot be the same.  I.e., one cannot
1924:    call MatBackwardSolve(A,x,x).

1926:    Most users should employ the simplified SLES interface for linear solvers
1927:    instead of working directly with matrix algebra routines such as this.
1928:    See, e.g., SLESCreate().

1930:    Level: developer

1932:    Concepts: matrices^backward solves

1934: .seealso: MatSolve(), MatForwardSolve()
1935: @ */
1936: int MatBackwardSolve(Mat mat,Vec b,Vec x)
1937: {

1943:   MatPreallocated(mat);
1948:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
1949:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
1950:   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1951:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1952:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
1953:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);

1955:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
1956:   (*mat->ops->backwardsolve)(mat,b,x);
1957:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
1958:   return(0);
1959: }

1961: /*@
1962:    MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.

1964:    Collective on Mat and Vec

1966:    Input Parameters:
1967: +  mat - the factored matrix
1968: .  b - the right-hand-side vector
1969: -  y - the vector to be added to 

1971:    Output Parameter:
1972: .  x - the result vector

1974:    Notes:
1975:    The vectors b and x cannot be the same.  I.e., one cannot
1976:    call MatSolveAdd(A,x,y,x).

1978:    Most users should employ the simplified SLES interface for linear solvers
1979:    instead of working directly with matrix algebra routines such as this.
1980:    See, e.g., SLESCreate().

1982:    Level: developer

1984:    Concepts: matrices^triangular solves

1986: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
1987: @*/
1988: int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
1989: {
1990:   PetscScalar one = 1.0;
1991:   Vec    tmp;
1992:   int    ierr;

1997:   MatPreallocated(mat);
2004:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2005:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2006:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2007:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2008:   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
2009:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2010:   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);

2012:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
2013:   if (mat->ops->solveadd)  {
2014:     (*mat->ops->solveadd)(mat,b,y,x);
2015:   } else {
2016:     /* do the solve then the add manually */
2017:     if (x != y) {
2018:       MatSolve(mat,b,x);
2019:       VecAXPY(&one,y,x);
2020:     } else {
2021:       VecDuplicate(x,&tmp);
2022:       PetscLogObjectParent(mat,tmp);
2023:       VecCopy(x,tmp);
2024:       MatSolve(mat,b,x);
2025:       VecAXPY(&one,tmp,x);
2026:       VecDestroy(tmp);
2027:     }
2028:   }
2029:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
2030:   return(0);
2031: }

2033: /*@
2034:    MatSolveTranspose - Solves A' x = b, given a factored matrix.

2036:    Collective on Mat and Vec

2038:    Input Parameters:
2039: +  mat - the factored matrix
2040: -  b - the right-hand-side vector

2042:    Output Parameter:
2043: .  x - the result vector

2045:    Notes:
2046:    The vectors b and x cannot be the same.  I.e., one cannot
2047:    call MatSolveTranspose(A,x,x).

2049:    Most users should employ the simplified SLES interface for linear solvers
2050:    instead of working directly with matrix algebra routines such as this.
2051:    See, e.g., SLESCreate().

2053:    Level: developer

2055:    Concepts: matrices^triangular solves

2057: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2058: @*/
2059: int MatSolveTranspose(Mat mat,Vec b,Vec x)
2060: {

2066:   MatPreallocated(mat);
2071:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2072:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2073:   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2074:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2075:   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);

2077:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
2078:   (*mat->ops->solvetranspose)(mat,b,x);
2079:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
2080:   return(0);
2081: }

2083: /*@
2084:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
2085:                       factored matrix. 

2087:    Collective on Mat and Vec

2089:    Input Parameters:
2090: +  mat - the factored matrix
2091: .  b - the right-hand-side vector
2092: -  y - the vector to be added to 

2094:    Output Parameter:
2095: .  x - the result vector

2097:    Notes:
2098:    The vectors b and x cannot be the same.  I.e., one cannot
2099:    call MatSolveTransposeAdd(A,x,y,x).

2101:    Most users should employ the simplified SLES interface for linear solvers
2102:    instead of working directly with matrix algebra routines such as this.
2103:    See, e.g., SLESCreate().

2105:    Level: developer

2107:    Concepts: matrices^triangular solves

2109: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2110: @*/
2111: int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2112: {
2113:   PetscScalar one = 1.0;
2114:   int         ierr;
2115:   Vec         tmp;

2120:   MatPreallocated(mat);
2127:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2128:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2129:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2130:   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2131:   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
2132:   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);

2134:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
2135:   if (mat->ops->solvetransposeadd) {
2136:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
2137:   } else {
2138:     /* do the solve then the add manually */
2139:     if (x != y) {
2140:       MatSolveTranspose(mat,b,x);
2141:       VecAXPY(&one,y,x);
2142:     } else {
2143:       VecDuplicate(x,&tmp);
2144:       PetscLogObjectParent(mat,tmp);
2145:       VecCopy(x,tmp);
2146:       MatSolveTranspose(mat,b,x);
2147:       VecAXPY(&one,tmp,x);
2148:       VecDestroy(tmp);
2149:     }
2150:   }
2151:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
2152:   return(0);
2153: }
2154: /* ----------------------------------------------------------------*/

2156: /*@
2157:    MatRelax - Computes one relaxation sweep.

2159:    Collective on Mat and Vec

2161:    Input Parameters:
2162: +  mat - the matrix
2163: .  b - the right hand side
2164: .  omega - the relaxation factor
2165: .  flag - flag indicating the type of SOR (see below)
2166: .  shift -  diagonal shift
2167: -  its - the number of iterations
2168: -  lits - the number of local iterations 

2170:    Output Parameters:
2171: .  x - the solution (can contain an initial guess)

2173:    SOR Flags:
2174: .     SOR_FORWARD_SWEEP - forward SOR
2175: .     SOR_BACKWARD_SWEEP - backward SOR
2176: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2177: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
2178: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
2179: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2180: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
2181:          upper/lower triangular part of matrix to
2182:          vector (with omega)
2183: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

2185:    Notes:
2186:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2187:    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
2188:    on each processor. 

2190:    Application programmers will not generally use MatRelax() directly,
2191:    but instead will employ the SLES/PC interface.

2193:    Notes for Advanced Users:
2194:    The flags are implemented as bitwise inclusive or operations.
2195:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2196:    to specify a zero initial guess for SSOR.

2198:    Most users should employ the simplified SLES interface for linear solvers
2199:    instead of working directly with matrix algebra routines such as this.
2200:    See, e.g., SLESCreate().

2202:    Level: developer

2204:    Concepts: matrices^relaxation
2205:    Concepts: matrices^SOR
2206:    Concepts: matrices^Gauss-Seidel

2208: @*/
2209: int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2210: {

2216:   MatPreallocated(mat);
2221:   if (!mat->ops->relax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2222:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2223:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2224:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2225:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2226:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);

2228:   PetscLogEventBegin(MAT_Relax,mat,b,x,0);
2229:   ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);
2230:   PetscLogEventEnd(MAT_Relax,mat,b,x,0);
2231:   return(0);
2232: }

2234: /*
2235:       Default matrix copy routine.
2236: */
2237: int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2238: {
2239:   int         ierr,i,rstart,rend,nz,*cwork;
2240:   PetscScalar *vwork;

2243:   MatZeroEntries(B);
2244:   MatGetOwnershipRange(A,&rstart,&rend);
2245:   for (i=rstart; i<rend; i++) {
2246:     MatGetRow(A,i,&nz,&cwork,&vwork);
2247:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
2248:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
2249:   }
2250:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
2251:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
2252:   return(0);
2253: }

2255: /*@C  
2256:    MatCopy - Copys a matrix to another matrix.

2258:    Collective on Mat

2260:    Input Parameters:
2261: +  A - the matrix
2262: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

2264:    Output Parameter:
2265: .  B - where the copy is put

2267:    Notes:
2268:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
2269:    same nonzero pattern or the routine will crash.

2271:    MatCopy() copies the matrix entries of a matrix to another existing
2272:    matrix (after first zeroing the second matrix).  A related routine is
2273:    MatConvert(), which first creates a new matrix and then copies the data.

2275:    Level: intermediate
2276:    
2277:    Concepts: matrices^copying

2279: .seealso: MatConvert()
2280: @*/
2281: int MatCopy(Mat A,Mat B,MatStructure str)
2282: {

2289:   MatPreallocated(A);
2291:   MatPreallocated(B);
2293:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2294:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2295:   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,
2296:                                              A->N,B->N);

2298:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
2299:   if (A->ops->copy) {
2300:     (*A->ops->copy)(A,B,str);
2301:   } else { /* generic conversion */
2302:     MatCopy_Basic(A,B,str);
2303:   }
2304:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
2305:   return(0);
2306: }

2308:  #include petscsys.h
2309: PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2310: PetscFList MatConvertList              = 0;

2312: /*@C
2313:     MatConvertRegister - Allows one to register a routine that reads matrices
2314:         from a binary file for a particular matrix type.

2316:   Not Collective

2318:   Input Parameters:
2319: +   type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ.
2320: -   Converter - the function that reads the matrix from the binary file.

2322:   Level: developer

2324: .seealso: MatConvertRegisterAll(), MatConvert()

2326: @*/
2327: int MatConvertRegister(char *sname,char *path,char *name,int (*function)(Mat,MatType,Mat*))
2328: {
2329:   int  ierr;
2330:   char fullname[256];

2333:   PetscFListConcat(path,name,fullname);
2334:   PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);
2335:   return(0);
2336: }

2338: /*@C  
2339:    MatConvert - Converts a matrix to another matrix, either of the same
2340:    or different type.

2342:    Collective on Mat

2344:    Input Parameters:
2345: +  mat - the matrix
2346: -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2347:    same type as the original matrix.

2349:    Output Parameter:
2350: .  M - pointer to place new matrix

2352:    Notes:
2353:    MatConvert() first creates a new matrix and then copies the data from
2354:    the first matrix.  A related routine is MatCopy(), which copies the matrix
2355:    entries of one matrix to another already existing matrix context.

2357:    Level: intermediate

2359:    Concepts: matrices^converting between storage formats

2361: .seealso: MatCopy(), MatDuplicate()
2362: @*/
2363: int MatConvert(Mat mat,MatType newtype,Mat *M)
2364: {
2365:   int        ierr;
2366:   PetscTruth sametype,issame,flg;
2367:   char       convname[256],mtype[256];

2372:   MatPreallocated(mat);
2374:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2375:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

2377:   PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);
2378:   if (flg) {
2379:     newtype = mtype;
2380:   }
2381:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
2382: 
2383:   PetscTypeCompare((PetscObject)mat,newtype,&sametype);
2384:   PetscStrcmp(newtype,"same",&issame);
2385:   if ((sametype || issame) && mat->ops->duplicate) {
2386:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
2387:   } else {
2388:     int (*conv)(Mat,MatType,Mat*);
2389:     if (!MatConvertRegisterAllCalled) {
2390:       MatConvertRegisterAll(PETSC_NULL);
2391:     }
2392:     PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);
2393:     if (conv) {
2394:       (*conv)(mat,newtype,M);
2395:     } else {
2396:       PetscStrcpy(convname,"MatConvert_");
2397:       PetscStrcat(convname,mat->type_name);
2398:       PetscStrcat(convname,"_");
2399:       PetscStrcat(convname,newtype);
2400:       PetscStrcat(convname,"_C");
2401:       PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
2402:       if (conv) {
2403:         (*conv)(mat,newtype,M);
2404:       } else {
2405:         if (mat->ops->convert) {
2406:           (*mat->ops->convert)(mat,newtype,M);
2407:         } else {
2408:           MatConvert_Basic(mat,newtype,M);
2409:         }
2410:       }
2411:     }
2412:   }
2413:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
2414:   return(0);
2415: }


2418: /*@C  
2419:    MatDuplicate - Duplicates a matrix including the non-zero structure.

2421:    Collective on Mat

2423:    Input Parameters:
2424: +  mat - the matrix
2425: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2426:         values as well or not

2428:    Output Parameter:
2429: .  M - pointer to place new matrix

2431:    Level: intermediate

2433:    Concepts: matrices^duplicating

2435: .seealso: MatCopy(), MatConvert()
2436: @*/
2437: int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2438: {

2444:   MatPreallocated(mat);
2446:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2447:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

2449:   *M  = 0;
2450:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
2451:   if (!mat->ops->duplicate) {
2452:     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2453:   }
2454:   (*mat->ops->duplicate)(mat,op,M);
2455:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
2456:   return(0);
2457: }

2459: /*@ 
2460:    MatGetDiagonal - Gets the diagonal of a matrix.

2462:    Collective on Mat and Vec

2464:    Input Parameters:
2465: +  mat - the matrix
2466: -  v - the vector for storing the diagonal

2468:    Output Parameter:
2469: .  v - the diagonal of the matrix

2471:    Notes:
2472:    For the SeqAIJ matrix format, this routine may also be called
2473:    on a LU factored matrix; in that case it routines the reciprocal of 
2474:    the diagonal entries in U. It returns the entries permuted by the 
2475:    row and column permutation used during the symbolic factorization.

2477:    Level: intermediate

2479:    Concepts: matrices^accessing diagonals

2481: .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2482: @*/
2483: int MatGetDiagonal(Mat mat,Vec v)
2484: {

2490:   MatPreallocated(mat);
2493:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2494:   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

2496:   (*mat->ops->getdiagonal)(mat,v);
2497:   return(0);
2498: }

2500: /*@ 
2501:    MatGetRowMax - Gets the maximum value (in absolute value) of each
2502:         row of the matrix

2504:    Collective on Mat and Vec

2506:    Input Parameters:
2507: .  mat - the matrix

2509:    Output Parameter:
2510: .  v - the vector for storing the maximums

2512:    Level: intermediate

2514:    Concepts: matrices^getting row maximums

2516: .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2517: @*/
2518: int MatGetRowMax(Mat mat,Vec v)
2519: {

2525:   MatPreallocated(mat);
2528:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2529:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

2531:   (*mat->ops->getrowmax)(mat,v);
2532:   return(0);
2533: }

2535: /*@C
2536:    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.

2538:    Collective on Mat

2540:    Input Parameter:
2541: .  mat - the matrix to transpose

2543:    Output Parameters:
2544: .  B - the transpose (or pass in PETSC_NULL for an in-place transpose)

2546:    Level: intermediate

2548:    Concepts: matrices^transposing

2550: .seealso: MatMultTranspose(), MatMultTransposeAdd()
2551: @*/
2552: int MatTranspose(Mat mat,Mat *B)
2553: {

2559:   MatPreallocated(mat);
2560:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2561:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2562:   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

2564:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
2565:   (*mat->ops->transpose)(mat,B);
2566:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
2567:   return(0);
2568: }

2570: /*@C
2571:    MatPermute - Creates a new matrix with rows and columns permuted from the 
2572:    original.

2574:    Collective on Mat

2576:    Input Parameters:
2577: +  mat - the matrix to permute
2578: .  row - row permutation, each processor supplies only the permutation for its rows
2579: -  col - column permutation, each processor needs the entire column permutation, that is
2580:          this is the same size as the total number of columns in the matrix

2582:    Output Parameters:
2583: .  B - the permuted matrix

2585:    Level: advanced

2587:    Concepts: matrices^permuting

2589: .seealso: MatGetOrdering()
2590: @*/
2591: int MatPermute(Mat mat,IS row,IS col,Mat *B)
2592: {

2598:   MatPreallocated(mat);
2601:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2602:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2603:   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2604:   (*mat->ops->permute)(mat,row,col,B);
2605:   return(0);
2606: }

2608: /*@C
2609:   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the 
2610:   original and sparsified to the prescribed tolerance.

2612:   Collective on Mat

2614:   Input Parameters:
2615: + A    - The matrix to permute
2616: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2617: . frac - The half-bandwidth as a fraction of the total size, or 0.0
2618: . tol  - The drop tolerance
2619: . rowp - The row permutation
2620: - colp - The column permutation

2622:   Output Parameter:
2623: . B    - The permuted, sparsified matrix

2625:   Level: advanced

2627:   Note:
2628:   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2629:   restrict the half-bandwidth of the resulting matrix to 5% of the
2630:   total matrix size.

2632: .keywords: matrix, permute, sparsify

2634: .seealso: MatGetOrdering(), MatPermute()
2635: @*/
2636: int MatPermuteSparsify(Mat A, int band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
2637: {
2638:   IS           irowp, icolp;
2639:   int         *rows, *cols;
2640:   int          M, N, locRowStart, locRowEnd;
2641:   int          nz, newNz;
2642:   int         *cwork, *cnew;
2643:   PetscScalar *vwork, *vnew;
2644:   int          bw, size;
2645:   int          row, locRow, newRow, col, newCol;
2646:   int          ierr;

2652:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
2653:   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
2654:   if (!A->ops->permutesparsify) {
2655:     MatGetSize(A, &M, &N);
2656:     MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
2657:     ISGetSize(rowp, &size);
2658:     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
2659:     ISGetSize(colp, &size);
2660:     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
2661:     ISInvertPermutation(rowp, 0, &irowp);
2662:     ISGetIndices(irowp, &rows);
2663:     ISInvertPermutation(colp, 0, &icolp);
2664:     ISGetIndices(icolp, &cols);
2665:     PetscMalloc(N * sizeof(int),         &cnew);
2666:     PetscMalloc(N * sizeof(PetscScalar), &vnew);

2668:     /* Setup bandwidth to include */
2669:     if (band == PETSC_DECIDE) {
2670:       if (frac <= 0.0)
2671:         bw = (int) (M * 0.05);
2672:       else
2673:         bw = (int) (M * frac);
2674:     } else {
2675:       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
2676:       bw = band;
2677:     }

2679:     /* Put values into new matrix */
2680:     MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
2681:     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
2682:       MatGetRow(A, row, &nz, &cwork, &vwork);
2683:       newRow   = rows[locRow]+locRowStart;
2684:       for(col = 0, newNz = 0; col < nz; col++) {
2685:         newCol = cols[cwork[col]];
2686:         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
2687:           cnew[newNz] = newCol;
2688:           vnew[newNz] = vwork[col];
2689:           newNz++;
2690:         }
2691:       }
2692:       MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
2693:       MatRestoreRow(A, row, &nz, &cwork, &vwork);
2694:     }
2695:     PetscFree(cnew);
2696:     PetscFree(vnew);
2697:     MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
2698:     MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
2699:     ISRestoreIndices(irowp, &rows);
2700:     ISRestoreIndices(icolp, &cols);
2701:     ISDestroy(irowp);
2702:     ISDestroy(icolp);
2703:   } else {
2704:     (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
2705:   }
2706:   return(0);
2707: }

2709: /*@
2710:    MatEqual - Compares two matrices.

2712:    Collective on Mat

2714:    Input Parameters:
2715: +  A - the first matrix
2716: -  B - the second matrix

2718:    Output Parameter:
2719: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

2721:    Level: intermediate

2723:    Concepts: matrices^equality between
2724: @*/
2725: int MatEqual(Mat A,Mat B,PetscTruth *flg)
2726: {

2733:   MatPreallocated(A);
2735:   MatPreallocated(B);
2738:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2739:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2740:   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);
2741:   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
2742:   (*A->ops->equal)(A,B,flg);
2743:   return(0);
2744: }

2746: /*@
2747:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
2748:    matrices that are stored as vectors.  Either of the two scaling
2749:    matrices can be PETSC_NULL.

2751:    Collective on Mat

2753:    Input Parameters:
2754: +  mat - the matrix to be scaled
2755: .  l - the left scaling vector (or PETSC_NULL)
2756: -  r - the right scaling vector (or PETSC_NULL)

2758:    Notes:
2759:    MatDiagonalScale() computes A = LAR, where
2760:    L = a diagonal matrix, R = a diagonal matrix

2762:    Level: intermediate

2764:    Concepts: matrices^diagonal scaling
2765:    Concepts: diagonal scaling of matrices

2767: .seealso: MatScale()
2768: @*/
2769: int MatDiagonalScale(Mat mat,Vec l,Vec r)
2770: {

2776:   MatPreallocated(mat);
2777:   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2780:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2781:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

2783:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
2784:   (*mat->ops->diagonalscale)(mat,l,r);
2785:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
2786:   return(0);
2787: }

2789: /*@
2790:     MatScale - Scales all elements of a matrix by a given number.

2792:     Collective on Mat

2794:     Input Parameters:
2795: +   mat - the matrix to be scaled
2796: -   a  - the scaling value

2798:     Output Parameter:
2799: .   mat - the scaled matrix

2801:     Level: intermediate

2803:     Concepts: matrices^scaling all entries

2805: .seealso: MatDiagonalScale()
2806: @*/
2807: int MatScale(PetscScalar *a,Mat mat)
2808: {

2814:   MatPreallocated(mat);
2816:   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2817:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2818:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

2820:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
2821:   (*mat->ops->scale)(a,mat);
2822:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
2823:   return(0);
2824: }

2826: /*@ 
2827:    MatNorm - Calculates various norms of a matrix.

2829:    Collective on Mat

2831:    Input Parameters:
2832: +  mat - the matrix
2833: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

2835:    Output Parameters:
2836: .  nrm - the resulting norm 

2838:    Level: intermediate

2840:    Concepts: matrices^norm
2841:    Concepts: norm^of matrix
2842: @*/
2843: int MatNorm(Mat mat,NormType type,PetscReal *nrm)
2844: {

2850:   MatPreallocated(mat);

2853:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2854:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2855:   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2856:   (*mat->ops->norm)(mat,type,nrm);
2857:   return(0);
2858: }

2860: /* 
2861:      This variable is used to prevent counting of MatAssemblyBegin() that
2862:    are called from within a MatAssemblyEnd().
2863: */
2864: static int MatAssemblyEnd_InUse = 0;
2865: /*@
2866:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
2867:    be called after completing all calls to MatSetValues().

2869:    Collective on Mat

2871:    Input Parameters:
2872: +  mat - the matrix 
2873: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
2874:  
2875:    Notes: 
2876:    MatSetValues() generally caches the values.  The matrix is ready to
2877:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
2878:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
2879:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
2880:    using the matrix.

2882:    Level: beginner

2884:    Concepts: matrices^assembling

2886: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
2887: @*/
2888: int MatAssemblyBegin(Mat mat,MatAssemblyType type)
2889: {

2895:   MatPreallocated(mat);
2896:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.nDid you forget to call MatSetUnfactored()?");
2897:   if (mat->assembled) {
2898:     mat->was_assembled = PETSC_TRUE;
2899:     mat->assembled     = PETSC_FALSE;
2900:   }
2901:   if (!MatAssemblyEnd_InUse) {
2902:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
2903:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
2904:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
2905:   } else {
2906:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
2907:   }
2908:   return(0);
2909: }

2911: /*@
2912:    MatAssembled - Indicates if a matrix has been assembled and is ready for
2913:      use; for example, in matrix-vector product.

2915:    Collective on Mat

2917:    Input Parameter:
2918: .  mat - the matrix 

2920:    Output Parameter:
2921: .  assembled - PETSC_TRUE or PETSC_FALSE

2923:    Level: advanced

2925:    Concepts: matrices^assembled?

2927: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
2928: @*/
2929: int MatAssembled(Mat mat,PetscTruth *assembled)
2930: {
2934:   MatPreallocated(mat);
2935:   *assembled = mat->assembled;
2936:   return(0);
2937: }

2939: /*
2940:     Processes command line options to determine if/how a matrix
2941:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
2942: */
2943: int MatView_Private(Mat mat)
2944: {
2945:   int        ierr;
2946:   PetscTruth flg;

2949:   PetscOptionsHasName(mat->prefix,"-mat_view_info",&flg);
2950:   if (flg) {
2951:     PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);
2952:     MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
2953:     PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));
2954:   }
2955:   PetscOptionsHasName(mat->prefix,"-mat_view_info_detailed",&flg);
2956:   if (flg) {
2957:     PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_LONG);
2958:     MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
2959:     PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));
2960:   }
2961:   PetscOptionsHasName(mat->prefix,"-mat_view",&flg);
2962:   if (flg) {
2963:     MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
2964:   }
2965:   PetscOptionsHasName(mat->prefix,"-mat_view_matlab",&flg);
2966:   if (flg) {
2967:     PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);
2968:     MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
2969:     PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));
2970:   }
2971:   PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);
2972:   if (flg) {
2973:     PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);
2974:     if (flg) {
2975:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);
2976:     }
2977:     MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));
2978:     PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));
2979:     if (flg) {
2980:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));
2981:     }
2982:   }
2983:   PetscOptionsHasName(mat->prefix,"-mat_view_socket",&flg);
2984:   if (flg) {
2985:     MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));
2986:     PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));
2987:   }
2988:   PetscOptionsHasName(mat->prefix,"-mat_view_binary",&flg);
2989:   if (flg) {
2990:     MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));
2991:     PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));
2992:   }
2993:   return(0);
2994: }

2996: /*@
2997:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
2998:    be called after MatAssemblyBegin().

3000:    Collective on Mat

3002:    Input Parameters:
3003: +  mat - the matrix 
3004: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

3006:    Options Database Keys:
3007: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3008: .  -mat_view_info_detailed - Prints more detailed info
3009: .  -mat_view - Prints matrix in ASCII format
3010: .  -mat_view_matlab - Prints matrix in Matlab format
3011: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3012: .  -display <name> - Sets display name (default is host)
3013: -  -draw_pause <sec> - Sets number of seconds to pause after display

3015:    Notes: 
3016:    MatSetValues() generally caches the values.  The matrix is ready to
3017:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3018:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3019:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3020:    using the matrix.

3022:    Level: beginner

3024: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled()
3025: @*/
3026: int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3027: {
3028:   int        ierr;
3029:   static int inassm = 0;

3034:   MatPreallocated(mat);

3036:   inassm++;
3037:   MatAssemblyEnd_InUse++;
3038:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3039:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
3040:     if (mat->ops->assemblyend) {
3041:       (*mat->ops->assemblyend)(mat,type);
3042:     }
3043:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
3044:   } else {
3045:     if (mat->ops->assemblyend) {
3046:       (*mat->ops->assemblyend)(mat,type);
3047:     }
3048:   }

3050:   /* Flush assembly is not a true assembly */
3051:   if (type != MAT_FLUSH_ASSEMBLY) {
3052:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3053:   }
3054:   mat->insertmode = NOT_SET_VALUES;
3055:   MatAssemblyEnd_InUse--;

3057:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3058:     MatView_Private(mat);
3059:   }
3060:   inassm--;
3061:   return(0);
3062: }


3065: /*@
3066:    MatCompress - Tries to store the matrix in as little space as 
3067:    possible.  May fail if memory is already fully used, since it
3068:    tries to allocate new space.

3070:    Collective on Mat

3072:    Input Parameters:
3073: .  mat - the matrix 

3075:    Level: advanced

3077: @*/
3078: int MatCompress(Mat mat)
3079: {

3085:   MatPreallocated(mat);
3086:   if (mat->ops->compress) {(*mat->ops->compress)(mat);}
3087:   return(0);
3088: }

3090: /*@
3091:    MatSetOption - Sets a parameter option for a matrix. Some options
3092:    may be specific to certain storage formats.  Some options
3093:    determine how values will be inserted (or added). Sorted, 
3094:    row-oriented input will generally assemble the fastest. The default
3095:    is row-oriented, nonsorted input. 

3097:    Collective on Mat

3099:    Input Parameters:
3100: +  mat - the matrix 
3101: -  option - the option, one of those listed below (and possibly others),
3102:              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR

3104:    Options Describing Matrix Structure:
3105: +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3106: -    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure

3108:    Options For Use with MatSetValues():
3109:    Insert a logically dense subblock, which can be
3110: +    MAT_ROW_ORIENTED - row-oriented (default)
3111: .    MAT_COLUMN_ORIENTED - column-oriented
3112: .    MAT_ROWS_SORTED - sorted by row
3113: .    MAT_ROWS_UNSORTED - not sorted by row (default)
3114: .    MAT_COLUMNS_SORTED - sorted by column
3115: -    MAT_COLUMNS_UNSORTED - not sorted by column (default)

3117:    Not these options reflect the data you pass in with MatSetValues(); it has 
3118:    nothing to do with how the data is stored internally in the matrix 
3119:    data structure.

3121:    When (re)assembling a matrix, we can restrict the input for
3122:    efficiency/debugging purposes.  These options include
3123: +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3124:         allowed if they generate a new nonzero
3125: .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3126: .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3127:          they generate a nonzero in a new diagonal (for block diagonal format only)
3128: .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3129: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3130: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3131: -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly

3133:    Notes:
3134:    Some options are relevant only for particular matrix types and
3135:    are thus ignored by others.  Other options are not supported by
3136:    certain matrix types and will generate an error message if set.

3138:    If using a Fortran 77 module to compute a matrix, one may need to 
3139:    use the column-oriented option (or convert to the row-oriented 
3140:    format).  

3142:    MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion 
3143:    that would generate a new entry in the nonzero structure is instead
3144:    ignored.  Thus, if memory has not alredy been allocated for this particular 
3145:    data, then the insertion is ignored. For dense matrices, in which
3146:    the entire array is allocated, no entries are ever ignored. 
3147:    Set after the first MatAssemblyEnd()

3149:    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion 
3150:    that would generate a new entry in the nonzero structure instead produces 
3151:    an error. (Currently supported for AIJ and BAIJ formats only.)
3152:    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3153:    SLESSetOperators() to ensure that the nonzero pattern truely does 
3154:    remain unchanged. Set after the first MatAssemblyEnd()

3156:    MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion 
3157:    that would generate a new entry that has not been preallocated will 
3158:    instead produce an error. (Currently supported for AIJ and BAIJ formats
3159:    only.) This is a useful flag when debugging matrix memory preallocation.

3161:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
3162:    other processors should be dropped, rather than stashed.
3163:    This is useful if you know that the "owning" processor is also 
3164:    always generating the correct matrix entries, so that PETSc need
3165:    not transfer duplicate entries generated on another processor.
3166:    
3167:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3168:    searches during matrix assembly. When this flag is set, the hash table
3169:    is created during the first Matrix Assembly. This hash table is
3170:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3171:    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag 
3172:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3173:    supported by MATMPIBAIJ format only.

3175:    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
3176:    are kept in the nonzero structure

3178:    MAT_IGNORE_ZERO_ENTRIES - when using ADD_VALUES for AIJ matrices this will stop
3179:    zero values from creating a zero location in the matrix

3181:    MAT_USE_INODES - indicates using inode version of the code - works with AIJ and 
3182:    ROWBS matrix types

3184:    MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works
3185:    with AIJ and ROWBS matrix types

3187:    Level: intermediate

3189:    Concepts: matrices^setting options

3191: @*/
3192: int MatSetOption(Mat mat,MatOption op)
3193: {

3199:   MatPreallocated(mat);
3200:   switch (op) {
3201:   case MAT_SYMMETRIC:
3202:     mat->symmetric              = PETSC_TRUE;
3203:     mat->structurally_symmetric = PETSC_TRUE;
3204:     break;
3205:   case MAT_STRUCTURALLY_SYMMETRIC:
3206:     mat->structurally_symmetric = PETSC_TRUE;
3207:     break;
3208:   default:
3209:     if (mat->ops->setoption) {(*mat->ops->setoption)(mat,op);}
3210:     break;
3211:   }
3212:   return(0);
3213: }

3215: /*@
3216:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3217:    this routine retains the old nonzero structure.

3219:    Collective on Mat

3221:    Input Parameters:
3222: .  mat - the matrix 

3224:    Level: intermediate

3226:    Concepts: matrices^zeroing

3228: .seealso: MatZeroRows()
3229: @*/
3230: int MatZeroEntries(Mat mat)
3231: {

3237:   MatPreallocated(mat);
3238:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3239:   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

3241:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
3242:   (*mat->ops->zeroentries)(mat);
3243:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
3244:   return(0);
3245: }

3247: /*@C
3248:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3249:    of a set of rows of a matrix.

3251:    Collective on Mat

3253:    Input Parameters:
3254: +  mat - the matrix
3255: .  is - index set of rows to remove
3256: -  diag - pointer to value put in all diagonals of eliminated rows.
3257:           Note that diag is not a pointer to an array, but merely a
3258:           pointer to a single value.

3260:    Notes:
3261:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3262:    but does not release memory.  For the dense and block diagonal
3263:    formats this does not alter the nonzero structure.

3265:    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3266:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3267:    merely zeroed.

3269:    The user can set a value in the diagonal entry (or for the AIJ and
3270:    row formats can optionally remove the main diagonal entry from the
3271:    nonzero structure as well, by passing a null pointer (PETSC_NULL 
3272:    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).

3274:    For the parallel case, all processes that share the matrix (i.e.,
3275:    those in the communicator used for matrix creation) MUST call this
3276:    routine, regardless of whether any rows being zeroed are owned by
3277:    them.

3279:   
3280:    Level: intermediate

3282:    Concepts: matrices^zeroing rows

3284: .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3285: @*/
3286: int MatZeroRows(Mat mat,IS is,PetscScalar *diag)
3287: {

3293:   MatPreallocated(mat);
3296:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3297:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3298:   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

3300:   (*mat->ops->zerorows)(mat,is,diag);
3301:   MatView_Private(mat);
3302:   return(0);
3303: }

3305: /*@C 
3306:    MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
3307:    of a set of rows of a matrix; using local numbering of rows.

3309:    Collective on Mat

3311:    Input Parameters:
3312: +  mat - the matrix
3313: .  is - index set of rows to remove
3314: -  diag - pointer to value put in all diagonals of eliminated rows.
3315:           Note that diag is not a pointer to an array, but merely a
3316:           pointer to a single value.

3318:    Notes:
3319:    Before calling MatZeroRowsLocal(), the user must first set the
3320:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

3322:    For the AIJ matrix formats this removes the old nonzero structure,
3323:    but does not release memory.  For the dense and block diagonal
3324:    formats this does not alter the nonzero structure.

3326:    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure
3327:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
3328:    merely zeroed.

3330:    The user can set a value in the diagonal entry (or for the AIJ and
3331:    row formats can optionally remove the main diagonal entry from the
3332:    nonzero structure as well, by passing a null pointer (PETSC_NULL
3333:    in C or PETSC_NULL_SCALAR in Fortran) as the final argument).

3335:    Level: intermediate

3337:    Concepts: matrices^zeroing

3339: .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3340: @*/
3341: int MatZeroRowsLocal(Mat mat,IS is,PetscScalar *diag)
3342: {
3344:   IS  newis;

3349:   MatPreallocated(mat);
3352:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3353:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

3355:   if (mat->ops->zerorowslocal) {
3356:     (*mat->ops->zerorowslocal)(mat,is,diag);
3357:   } else {
3358:     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3359:     ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
3360:     (*mat->ops->zerorows)(mat,newis,diag);
3361:     ISDestroy(newis);
3362:   }
3363:   return(0);
3364: }

3366: /*@
3367:    MatGetSize - Returns the numbers of rows and columns in a matrix.

3369:    Not Collective

3371:    Input Parameter:
3372: .  mat - the matrix

3374:    Output Parameters:
3375: +  m - the number of global rows
3376: -  n - the number of global columns

3378:    Level: beginner

3380:    Concepts: matrices^size

3382: .seealso: MatGetLocalSize()
3383: @*/
3384: int MatGetSize(Mat mat,int *m,int* n)
3385: {
3388:   if (m) *m = mat->M;
3389:   if (n) *n = mat->N;
3390:   return(0);
3391: }

3393: /*@
3394:    MatGetLocalSize - Returns the number of rows and columns in a matrix
3395:    stored locally.  This information may be implementation dependent, so
3396:    use with care.

3398:    Not Collective

3400:    Input Parameters:
3401: .  mat - the matrix

3403:    Output Parameters:
3404: +  m - the number of local rows
3405: -  n - the number of local columns

3407:    Level: beginner

3409:    Concepts: matrices^local size

3411: .seealso: MatGetSize()
3412: @*/
3413: int MatGetLocalSize(Mat mat,int *m,int* n)
3414: {
3417:   if (m) *m = mat->m;
3418:   if (n) *n = mat->n;
3419:   return(0);
3420: }

3422: /*@
3423:    MatGetOwnershipRange - Returns the range of matrix rows owned by
3424:    this processor, assuming that the matrix is laid out with the first
3425:    n1 rows on the first processor, the next n2 rows on the second, etc.
3426:    For certain parallel layouts this range may not be well defined.

3428:    Not Collective

3430:    Input Parameters:
3431: .  mat - the matrix

3433:    Output Parameters:
3434: +  m - the global index of the first local row
3435: -  n - one more than the global index of the last local row

3437:    Level: beginner

3439:    Concepts: matrices^row ownership
3440: @*/
3441: int MatGetOwnershipRange(Mat mat,int *m,int* n)
3442: {

3448:   MatPreallocated(mat);
3451:   PetscMapGetLocalRange(mat->rmap,m,n);
3452:   return(0);
3453: }

3455: /*@  
3456:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3457:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
3458:    to complete the factorization.

3460:    Collective on Mat

3462:    Input Parameters:
3463: +  mat - the matrix
3464: .  row - row permutation
3465: .  column - column permutation
3466: -  info - structure containing 
3467: $      levels - number of levels of fill.
3468: $      expected fill - as ratio of original fill.
3469: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3470:                 missing diagonal entries)

3472:    Output Parameters:
3473: .  fact - new matrix that has been symbolically factored

3475:    Notes:
3476:    See the users manual for additional information about
3477:    choosing the fill factor for better efficiency.

3479:    Most users should employ the simplified SLES interface for linear solvers
3480:    instead of working directly with matrix algebra routines such as this.
3481:    See, e.g., SLESCreate().

3483:    Level: developer

3485:   Concepts: matrices^symbolic LU factorization
3486:   Concepts: matrices^factorization
3487:   Concepts: LU^symbolic factorization

3489: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3490:           MatGetOrdering(), MatILUInfo

3492: @*/
3493: int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatILUInfo *info,Mat *fact)
3494: {

3500:   MatPreallocated(mat);
3504:   if (info && info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels);
3505:   if (info && info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3506:   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3507:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3508:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

3510:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
3511:   (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);
3512:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
3513:   return(0);
3514: }

3516: /*@  
3517:    MatICCFactorSymbolic - Performs symbolic incomplete
3518:    Cholesky factorization for a symmetric matrix.  Use 
3519:    MatCholeskyFactorNumeric() to complete the factorization.

3521:    Collective on Mat

3523:    Input Parameters:
3524: +  mat - the matrix
3525: .  perm - row and column permutation
3526: .  fill - levels of fill
3527: -  f - expected fill as ratio of original fill

3529:    Output Parameter:
3530: .  fact - the factored matrix

3532:    Notes:
3533:    Currently only no-fill factorization is supported.

3535:    Most users should employ the simplified SLES interface for linear solvers
3536:    instead of working directly with matrix algebra routines such as this.
3537:    See, e.g., SLESCreate().

3539:    Level: developer

3541:   Concepts: matrices^symbolic incomplete Cholesky factorization
3542:   Concepts: matrices^factorization
3543:   Concepts: Cholsky^symbolic factorization

3545: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor()
3546: @*/
3547: int MatICCFactorSymbolic(Mat mat,IS perm,PetscReal f,int fill,Mat *fact)
3548: {

3554:   MatPreallocated(mat);
3557:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3558:   if (fill < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Fill negative %d",fill);
3559:   if (f < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",f);
3560:   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
3561:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");

3563:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
3564:   (*mat->ops->iccfactorsymbolic)(mat,perm,f,fill,fact);
3565:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
3566:   return(0);
3567: }

3569: /*@C
3570:    MatGetArray - Returns a pointer to the element values in the matrix.
3571:    The result of this routine is dependent on the underlying matrix data
3572:    structure, and may not even work for certain matrix types.  You MUST
3573:    call MatRestoreArray() when you no longer need to access the array.

3575:    Not Collective

3577:    Input Parameter:
3578: .  mat - the matrix

3580:    Output Parameter:
3581: .  v - the location of the values


3584:    Fortran Note:
3585:    This routine is used differently from Fortran, e.g.,
3586: .vb
3587:         Mat         mat
3588:         PetscScalar mat_array(1)
3589:         PetscOffset i_mat
3590:         int         ierr
3591:         call MatGetArray(mat,mat_array,i_mat,ierr)

3593:   C  Access first local entry in matrix; note that array is
3594:   C  treated as one dimensional
3595:         value = mat_array(i_mat + 1)

3597:         [... other code ...]
3598:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3599: .ve

3601:    See the Fortran chapter of the users manual and 
3602:    petsc/src/mat/examples/tests for details.

3604:    Level: advanced

3606:    Concepts: matrices^access array

3608: .seealso: MatRestoreArray(), MatGetArrayF90()
3609: @*/
3610: int MatGetArray(Mat mat,PetscScalar **v)
3611: {

3617:   MatPreallocated(mat);
3619:   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3620:   (*mat->ops->getarray)(mat,v);
3621:   return(0);
3622: }

3624: /*@C
3625:    MatRestoreArray - Restores the matrix after MatGetArray() has been called.

3627:    Not Collective

3629:    Input Parameter:
3630: +  mat - the matrix
3631: -  v - the location of the values

3633:    Fortran Note:
3634:    This routine is used differently from Fortran, e.g.,
3635: .vb
3636:         Mat         mat
3637:         PetscScalar mat_array(1)
3638:         PetscOffset i_mat
3639:         int         ierr
3640:         call MatGetArray(mat,mat_array,i_mat,ierr)

3642:   C  Access first local entry in matrix; note that array is
3643:   C  treated as one dimensional
3644:         value = mat_array(i_mat + 1)

3646:         [... other code ...]
3647:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
3648: .ve

3650:    See the Fortran chapter of the users manual and 
3651:    petsc/src/mat/examples/tests for details

3653:    Level: advanced

3655: .seealso: MatGetArray(), MatRestoreArrayF90()
3656: @*/
3657: int MatRestoreArray(Mat mat,PetscScalar **v)
3658: {

3664:   MatPreallocated(mat);
3666:   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3667:   (*mat->ops->restorearray)(mat,v);
3668:   return(0);
3669: }

3671: /*@C
3672:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
3673:    points to an array of valid matrices, they may be reused to store the new
3674:    submatrices.

3676:    Collective on Mat

3678:    Input Parameters:
3679: +  mat - the matrix
3680: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
3681: .  irow, icol - index sets of rows and columns to extract
3682: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

3684:    Output Parameter:
3685: .  submat - the array of submatrices

3687:    Notes:
3688:    MatGetSubMatrices() can extract only sequential submatrices
3689:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
3690:    to extract a parallel submatrix.

3692:    When extracting submatrices from a parallel matrix, each processor can
3693:    form a different submatrix by setting the rows and columns of its
3694:    individual index sets according to the local submatrix desired.

3696:    When finished using the submatrices, the user should destroy
3697:    them with MatDestroyMatrices().

3699:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the 
3700:    original matrix has not changed from that last call to MatGetSubMatrices().

3702:    This routine creates the matrices submat; you should NOT create them before
3703:    calling it.

3705:    Fortran Note:
3706:    The Fortran interface is slightly different from that given below; it 
3707:    requires one to pass in  as submat a Mat (integer) array of size at least m.

3709:    Level: advanced

3711:    Concepts: matrices^accessing submatrices
3712:    Concepts: submatrices

3714: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
3715: @*/
3716: int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatReuse scall,Mat **submat)
3717: {
3718:   int        ierr;

3723:   MatPreallocated(mat);
3724:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3725:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");

3727:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
3728:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
3729:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
3730:   return(0);
3731: }

3733: /*@C
3734:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

3736:    Collective on Mat

3738:    Input Parameters:
3739: +  n - the number of local matrices
3740: -  mat - the matrices

3742:    Level: advanced

3744:     Notes: Frees not only the matrices, but also the array that contains the matrices

3746: .seealso: MatGetSubMatrices()
3747: @*/
3748: int MatDestroyMatrices(int n,Mat **mat)
3749: {
3750:   int ierr,i;

3753:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
3755:   for (i=0; i<n; i++) {
3756:     MatDestroy((*mat)[i]);
3757:   }
3758:   /* memory is allocated even if n = 0 */
3759:   PetscFree(*mat);
3760:   return(0);
3761: }

3763: /*@
3764:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
3765:    replaces the index sets by larger ones that represent submatrices with
3766:    additional overlap.

3768:    Collective on Mat

3770:    Input Parameters:
3771: +  mat - the matrix
3772: .  n   - the number of index sets
3773: .  is  - the array of pointers to index sets
3774: -  ov  - the additional overlap requested

3776:    Level: developer

3778:    Concepts: overlap
3779:    Concepts: ASM^computing overlap

3781: .seealso: MatGetSubMatrices()
3782: @*/
3783: int MatIncreaseOverlap(Mat mat,int n,IS *is,int ov)
3784: {

3790:   MatPreallocated(mat);
3791:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3792:   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

3794:   if (!ov) return(0);
3795:   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3796:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
3797:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
3798:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
3799:   return(0);
3800: }

3802: /*@
3803:    MatPrintHelp - Prints all the options for the matrix.

3805:    Collective on Mat

3807:    Input Parameter:
3808: .  mat - the matrix 

3810:    Options Database Keys:
3811: +  -help - Prints matrix options
3812: -  -h - Prints matrix options

3814:    Level: developer

3816: .seealso: MatCreate(), MatCreateXXX()
3817: @*/
3818: int MatPrintHelp(Mat mat)
3819: {
3820:   static PetscTruth called = PETSC_FALSE;
3821:   int               ierr;
3822:   MPI_Comm          comm;

3827:   MatPreallocated(mat);

3829:   comm = mat->comm;
3830:   if (!called) {
3831:     (*PetscHelpPrintf)(comm,"General matrix options:n");
3832:     (*PetscHelpPrintf)(comm,"  -mat_view_info: view basic matrix info during MatAssemblyEnd()n");
3833:     (*PetscHelpPrintf)(comm,"  -mat_view_info_detailed: view detailed matrix info during MatAssemblyEnd()n");
3834:     (*PetscHelpPrintf)(comm,"  -mat_view_draw: draw nonzero matrix structure during MatAssemblyEnd()n");
3835:     (*PetscHelpPrintf)(comm,"      -draw_pause <sec>: set seconds of display pausen");
3836:     (*PetscHelpPrintf)(comm,"      -display <name>: set alternate displayn");
3837:     called = PETSC_TRUE;
3838:   }
3839:   if (mat->ops->printhelp) {
3840:     (*mat->ops->printhelp)(mat);
3841:   }
3842:   return(0);
3843: }

3845: /*@
3846:    MatGetBlockSize - Returns the matrix block size; useful especially for the
3847:    block row and block diagonal formats.
3848:    
3849:    Not Collective

3851:    Input Parameter:
3852: .  mat - the matrix

3854:    Output Parameter:
3855: .  bs - block size

3857:    Notes:
3858:    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
3859:    Block row formats are MATSEQBAIJ, MATMPIBAIJ

3861:    Level: intermediate

3863:    Concepts: matrices^block size

3865: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
3866: @*/
3867: int MatGetBlockSize(Mat mat,int *bs)
3868: {

3874:   MatPreallocated(mat);
3876:   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3877:   (*mat->ops->getblocksize)(mat,bs);
3878:   return(0);
3879: }

3881: /*@C
3882:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

3884:    Collective on Mat

3886:     Input Parameters:
3887: +   mat - the matrix
3888: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
3889: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3890:                 symmetrized

3892:     Output Parameters:
3893: +   n - number of rows in the (possibly compressed) matrix
3894: .   ia - the row pointers
3895: .   ja - the column indices
3896: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

3898:     Level: developer

3900: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
3901: @*/
3902: int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3903: {

3909:   MatPreallocated(mat);
3913:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
3914:   else {
3915:     *done = PETSC_TRUE;
3916:     ierr  = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);
3917:   }
3918:   return(0);
3919: }

3921: /*@C
3922:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

3924:     Collective on Mat

3926:     Input Parameters:
3927: +   mat - the matrix
3928: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3929: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3930:                 symmetrized

3932:     Output Parameters:
3933: +   n - number of columns in the (possibly compressed) matrix
3934: .   ia - the column pointers
3935: .   ja - the row indices
3936: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

3938:     Level: developer

3940: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
3941: @*/
3942: int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3943: {

3949:   MatPreallocated(mat);

3954:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
3955:   else {
3956:     *done = PETSC_TRUE;
3957:     ierr  = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);
3958:   }
3959:   return(0);
3960: }

3962: /*@C
3963:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
3964:     MatGetRowIJ().

3966:     Collective on Mat

3968:     Input Parameters:
3969: +   mat - the matrix
3970: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
3971: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
3972:                 symmetrized

3974:     Output Parameters:
3975: +   n - size of (possibly compressed) matrix
3976: .   ia - the row pointers
3977: .   ja - the column indices
3978: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

3980:     Level: developer

3982: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
3983: @*/
3984: int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
3985: {

3991:   MatPreallocated(mat);

3996:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
3997:   else {
3998:     *done = PETSC_TRUE;
3999:     ierr  = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);
4000:   }
4001:   return(0);
4002: }

4004: /*@C
4005:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4006:     MatGetColumnIJ().

4008:     Collective on Mat

4010:     Input Parameters:
4011: +   mat - the matrix
4012: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4013: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4014:                 symmetrized

4016:     Output Parameters:
4017: +   n - size of (possibly compressed) matrix
4018: .   ia - the column pointers
4019: .   ja - the row indices
4020: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

4022:     Level: developer

4024: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4025: @*/
4026: int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done)
4027: {

4033:   MatPreallocated(mat);

4038:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4039:   else {
4040:     *done = PETSC_TRUE;
4041:     ierr  = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);
4042:   }
4043:   return(0);
4044: }

4046: /*@C
4047:     MatColoringPatch -Used inside matrix coloring routines that 
4048:     use MatGetRowIJ() and/or MatGetColumnIJ().

4050:     Collective on Mat

4052:     Input Parameters:
4053: +   mat - the matrix
4054: .   n   - number of colors
4055: -   colorarray - array indicating color for each column

4057:     Output Parameters:
4058: .   iscoloring - coloring generated using colorarray information

4060:     Level: developer

4062: .seealso: MatGetRowIJ(), MatGetColumnIJ()

4064: @*/
4065: int MatColoringPatch(Mat mat,int n,int ncolors,int *colorarray,ISColoring *iscoloring)
4066: {

4072:   MatPreallocated(mat);

4075:   if (!mat->ops->coloringpatch){
4076:     ISColoringCreate(mat->comm,n,colorarray,iscoloring);
4077:   } else {
4078:     (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);
4079:   }
4080:   return(0);
4081: }


4084: /*@
4085:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

4087:    Collective on Mat

4089:    Input Parameter:
4090: .  mat - the factored matrix to be reset

4092:    Notes: 
4093:    This routine should be used only with factored matrices formed by in-place
4094:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
4095:    format).  This option can save memory, for example, when solving nonlinear
4096:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
4097:    ILU(0) preconditioner.  

4099:    Note that one can specify in-place ILU(0) factorization by calling 
4100: .vb
4101:      PCType(pc,PCILU);
4102:      PCILUSeUseInPlace(pc);
4103: .ve
4104:    or by using the options -pc_type ilu -pc_ilu_in_place

4106:    In-place factorization ILU(0) can also be used as a local
4107:    solver for the blocks within the block Jacobi or additive Schwarz
4108:    methods (runtime option: -sub_pc_ilu_in_place).  See the discussion 
4109:    of these preconditioners in the users manual for details on setting
4110:    local solver options.

4112:    Most users should employ the simplified SLES interface for linear solvers
4113:    instead of working directly with matrix algebra routines such as this.
4114:    See, e.g., SLESCreate().

4116:    Level: developer

4118: .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace()

4120:    Concepts: matrices^unfactored

4122: @*/
4123: int MatSetUnfactored(Mat mat)
4124: {

4130:   MatPreallocated(mat);
4131:   mat->factor = 0;
4132:   if (!mat->ops->setunfactored) return(0);
4133:   (*mat->ops->setunfactored)(mat);
4134:   return(0);
4135: }

4137: /*MC
4138:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

4140:     Synopsis:
4141:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

4143:     Not collective

4145:     Input Parameter:
4146: .   x - matrix

4148:     Output Parameters:
4149: +   xx_v - the Fortran90 pointer to the array
4150: -   ierr - error code

4152:     Example of Usage: 
4153: .vb
4154:       PetscScalar, pointer xx_v(:)
4155:       ....
4156:       call MatGetArrayF90(x,xx_v,ierr)
4157:       a = xx_v(3)
4158:       call MatRestoreArrayF90(x,xx_v,ierr)
4159: .ve

4161:     Notes:
4162:     Not yet supported for all F90 compilers

4164:     Level: advanced

4166: .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()

4168:     Concepts: matrices^accessing array

4170: M*/

4172: /*MC
4173:     MatRestoreArrayF90 - Restores a matrix array that has been
4174:     accessed with MatGetArrayF90().

4176:     Synopsis:
4177:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

4179:     Not collective

4181:     Input Parameters:
4182: +   x - matrix
4183: -   xx_v - the Fortran90 pointer to the array

4185:     Output Parameter:
4186: .   ierr - error code

4188:     Example of Usage: 
4189: .vb
4190:        PetscScalar, pointer xx_v(:)
4191:        ....
4192:        call MatGetArrayF90(x,xx_v,ierr)
4193:        a = xx_v(3)
4194:        call MatRestoreArrayF90(x,xx_v,ierr)
4195: .ve
4196:    
4197:     Notes:
4198:     Not yet supported for all F90 compilers

4200:     Level: advanced

4202: .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()

4204: M*/


4207: /*@
4208:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4209:                       as the original matrix.

4211:     Collective on Mat

4213:     Input Parameters:
4214: +   mat - the original matrix
4215: .   isrow - rows this processor should obtain
4216: .   iscol - columns for all processors you wish to keep
4217: .   csize - number of columns "local" to this processor (does nothing for sequential 
4218:             matrices). This should match the result from VecGetLocalSize(x,...) if you 
4219:             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4220: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4222:     Output Parameter:
4223: .   newmat - the new submatrix, of the same type as the old

4225:     Level: advanced

4227:     Notes: the iscol argument MUST be the same on each processor. You might be 
4228:     able to create the iscol argument with ISAllGather().

4230:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
4231:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
4232:    to this routine with a mat of the same nonzero structure will reuse the matrix
4233:    generated the first time.

4235:     Concepts: matrices^submatrices

4237: .seealso: MatGetSubMatrices(), ISAllGather()
4238: @*/
4239: int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4240: {
4241:   int     ierr, size;
4242:   Mat     *local;

4246:   MatPreallocated(mat);
4247:   MPI_Comm_size(mat->comm,&size);

4249:   /* if original matrix is on just one processor then use submatrix generated */
4250:   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4251:     MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);
4252:     return(0);
4253:   } else if (!mat->ops->getsubmatrix && size == 1) {
4254:     ierr    = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);
4255:     *newmat = *local;
4256:     ierr    = PetscFree(local);
4257:     return(0);
4258:   }

4260:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4261:   (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);
4262:   return(0);
4263: }

4265: /*@C
4266:    MatGetPetscMaps - Returns the maps associated with the matrix.

4268:    Not Collective

4270:    Input Parameter:
4271: .  mat - the matrix

4273:    Output Parameters:
4274: +  rmap - the row (right) map
4275: -  cmap - the column (left) map  

4277:    Level: developer

4279:    Concepts: maps^getting from matrix

4281: @*/
4282: int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4283: {

4289:   MatPreallocated(mat);
4290:   (*mat->ops->getmaps)(mat,rmap,cmap);
4291:   return(0);
4292: }

4294: /*
4295:       Version that works for all PETSc matrices
4296: */
4297: int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4298: {
4300:   if (rmap) *rmap = mat->rmap;
4301:   if (cmap) *cmap = mat->cmap;
4302:   return(0);
4303: }

4305: /*@
4306:    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4307:    used during the assembly process to store values that belong to 
4308:    other processors.

4310:    Not Collective

4312:    Input Parameters:
4313: +  mat   - the matrix
4314: .  size  - the initial size of the stash.
4315: -  bsize - the initial size of the block-stash(if used).

4317:    Options Database Keys:
4318: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4319: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

4321:    Level: intermediate

4323:    Notes: 
4324:      The block-stash is used for values set with VecSetValuesBlocked() while
4325:      the stash is used for values set with VecSetValues()

4327:      Run with the option -log_info and look for output of the form
4328:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4329:      to determine the appropriate value, MM, to use for size and 
4330:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4331:      to determine the value, BMM to use for bsize

4333:    Concepts: stash^setting matrix size
4334:    Concepts: matrices^stash

4336: @*/
4337: int MatSetStashInitialSize(Mat mat,int size, int bsize)
4338: {

4344:   MatPreallocated(mat);
4345:   MatStashSetInitialSize_Private(&mat->stash,size);
4346:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
4347:   return(0);
4348: }

4350: /*@
4351:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
4352:      the matrix

4354:    Collective on Mat

4356:    Input Parameters:
4357: +  mat   - the matrix
4358: .  x,y - the vectors
4359: -  w - where the result is stored

4361:    Level: intermediate

4363:    Notes: 
4364:     w may be the same vector as y. 

4366:     This allows one to use either the restriction or interpolation (its transpose)
4367:     matrix to do the interpolation

4369:     Concepts: interpolation

4371: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

4373: @*/
4374: int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4375: {
4376:   int M,N,ierr;

4380:   MatPreallocated(A);
4381:   MatGetSize(A,&M,&N);
4382:   if (N > M) {
4383:     MatMultTransposeAdd(A,x,y,w);
4384:   } else {
4385:     MatMultAdd(A,x,y,w);
4386:   }
4387:   return(0);
4388: }

4390: /*@
4391:    MatInterpolate - y = A*x or A'*x depending on the shape of 
4392:      the matrix

4394:    Collective on Mat

4396:    Input Parameters:
4397: +  mat   - the matrix
4398: -  x,y - the vectors

4400:    Level: intermediate

4402:    Notes: 
4403:     This allows one to use either the restriction or interpolation (its transpose)
4404:     matrix to do the interpolation

4406:    Concepts: matrices^interpolation

4408: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

4410: @*/
4411: int MatInterpolate(Mat A,Vec x,Vec y)
4412: {
4413:   int M,N,ierr;

4417:   MatPreallocated(A);
4418:   MatGetSize(A,&M,&N);
4419:   if (N > M) {
4420:     MatMultTranspose(A,x,y);
4421:   } else {
4422:     MatMult(A,x,y);
4423:   }
4424:   return(0);
4425: }

4427: /*@
4428:    MatRestrict - y = A*x or A'*x

4430:    Collective on Mat

4432:    Input Parameters:
4433: +  mat   - the matrix
4434: -  x,y - the vectors

4436:    Level: intermediate

4438:    Notes: 
4439:     This allows one to use either the restriction or interpolation (its transpose)
4440:     matrix to do the restriction

4442:    Concepts: matrices^restriction

4444: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

4446: @*/
4447: int MatRestrict(Mat A,Vec x,Vec y)
4448: {
4449:   int M,N,ierr;

4453:   MatPreallocated(A);
4454:   MatGetSize(A,&M,&N);
4455:   if (N > M) {
4456:     MatMult(A,x,y);
4457:   } else {
4458:     MatMultTranspose(A,x,y);
4459:   }
4460:   return(0);
4461: }

4463: /*@C
4464:    MatNullSpaceAttach - attaches a null space to a matrix.
4465:         This null space will be removed from the resulting vector whenever
4466:         MatMult() is called

4468:    Collective on Mat

4470:    Input Parameters:
4471: +  mat - the matrix
4472: -  nullsp - the null space object

4474:    Level: developer

4476:    Notes:
4477:       Overwrites any previous null space that may have been attached

4479:    Concepts: null space^attaching to matrix

4481: .seealso: MatCreate(), MatNullSpaceCreate()
4482: @*/
4483: int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
4484: {

4490:   MatPreallocated(mat);

4493:   if (mat->nullsp) {
4494:     MatNullSpaceDestroy(mat->nullsp);
4495:   }
4496:   mat->nullsp = nullsp;
4497:   PetscObjectReference((PetscObject)nullsp);
4498:   return(0);
4499: }

4501: /*@  
4502:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

4504:    Collective on Mat

4506:    Input Parameters:
4507: +  mat - the matrix
4508: .  row - row/column permutation
4509: .  fill - expected fill factor >= 1.0
4510: -  level - level of fill, for ICC(k)

4512:    Notes: 
4513:    Probably really in-place only when level of fill is zero, otherwise allocates
4514:    new space to store factored matrix and deletes previous memory.

4516:    Most users should employ the simplified SLES interface for linear solvers
4517:    instead of working directly with matrix algebra routines such as this.
4518:    See, e.g., SLESCreate().

4520:    Level: developer

4522:    Concepts: matrices^incomplete Cholesky factorization
4523:    Concepts: Cholesky factorization

4525: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
4526: @*/
4527: int MatICCFactor(Mat mat,IS row,PetscReal fill,int level)
4528: {

4534:   MatPreallocated(mat);
4535:   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
4536:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4537:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4538:   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4539:   (*mat->ops->iccfactor)(mat,row,fill,level);
4540:   return(0);
4541: }

4543: /*@ 
4544:    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.

4546:    Not Collective

4548:    Input Parameters:
4549: +  mat - the matrix
4550: -  v - the values compute with ADIC

4552:    Level: developer

4554:    Notes:
4555:      Must call MatSetColoring() before using this routine. Also this matrix must already
4556:      have its nonzero pattern determined.

4558: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4559:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
4560: @*/
4561: int MatSetValuesAdic(Mat mat,void *v)
4562: {


4569:   if (!mat->assembled) {
4570:     SETERRQ(1,"Matrix must be already assembled");
4571:   }
4572:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
4573:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4574:   (*mat->ops->setvaluesadic)(mat,v);
4575:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
4576:   MatView_Private(mat);
4577:   return(0);
4578: }


4581: /*@ 
4582:    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()

4584:    Not Collective

4586:    Input Parameters:
4587: +  mat - the matrix
4588: -  coloring - the coloring

4590:    Level: developer

4592: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4593:           MatSetValues(), MatSetValuesAdic()
4594: @*/
4595: int MatSetColoring(Mat mat,ISColoring coloring)
4596: {


4603:   if (!mat->assembled) {
4604:     SETERRQ(1,"Matrix must be already assembled");
4605:   }
4606:   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4607:   (*mat->ops->setcoloring)(mat,coloring);
4608:   return(0);
4609: }

4611: /*@ 
4612:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

4614:    Not Collective

4616:    Input Parameters:
4617: +  mat - the matrix
4618: .  nl - leading dimension of v
4619: -  v - the values compute with ADIFOR

4621:    Level: developer

4623:    Notes:
4624:      Must call MatSetColoring() before using this routine. Also this matrix must already
4625:      have its nonzero pattern determined.

4627: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
4628:           MatSetValues(), MatSetColoring()
4629: @*/
4630: int MatSetValuesAdifor(Mat mat,int nl,void *v)
4631: {


4638:   if (!mat->assembled) {
4639:     SETERRQ(1,"Matrix must be already assembled");
4640:   }
4641:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
4642:   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4643:   (*mat->ops->setvaluesadifor)(mat,nl,v);
4644:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
4645:   return(0);
4646: }

4648: EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec);
4649: EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec);

4651: /*@ 
4652:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
4653:          ghosted ones.

4655:    Not Collective

4657:    Input Parameters:
4658: +  mat - the matrix
4659: -  diag = the diagonal values, including ghost ones

4661:    Level: developer

4663:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
4664:       
4665: .seealso: MatDiagonalScale()
4666: @*/
4667: int MatDiagonalScaleLocal(Mat mat,Vec diag)
4668: {
4669:   int        ierr;
4670:   PetscTruth flag;


4677:   if (!mat->assembled) {
4678:     SETERRQ(1,"Matrix must be already assembled");
4679:   }
4680:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4681:   PetscTypeCompare((PetscObject)mat,MATMPIAIJ,&flag);
4682:   if (flag) {
4683:     MatMPIAIJDiagonalScaleLocal(mat,diag);
4684:   } else {
4685:     PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flag);
4686:     if (flag) {
4687:       MatMPIBAIJDiagonalScaleLocal(mat,diag);
4688:     } else {
4689:       int size;
4690:       MPI_Comm_size(mat->comm,&size);
4691:       if (size == 1) {
4692:         int n,m;
4693:         VecGetSize(diag,&n);
4694:         MatGetSize(mat,0,&m);
4695:         if (m == n) {
4696:           MatDiagonalScale(mat,0,diag);
4697:         } else {
4698:           SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions");
4699:         }
4700:       } else {
4701:         SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
4702:       }
4703:     }
4704:   }
4705:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4706:   return(0);
4707: }