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 vecimpl.h

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

 22: /* nasty global values for MatSetValue() */
 23: int         MatSetValue_Row = 0, MatSetValue_Column = 0;
 24: PetscScalar MatSetValue_Value = 0.0;

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

 33:    Not Collective

 35:    Input Parameters:
 36: +  mat - the matrix
 37: -  row - the row to get

 39:    Output Parameters:
 40: +  ncols -  if not NULL, the number of nonzeros in the row
 41: .  cols - if not NULL, the column numbers
 42: -  vals - if not NULL, the values

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

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

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

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

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

 66:    Fortran Notes:
 67:    The calling sequence from Fortran is 
 68: .vb
 69:    MatGetRow(matrix,row,ncols,cols,values,ierr)
 70:          Mat     matrix (input)
 71:          integer row    (input)
 72:          integer ncols  (output)
 73:          integer cols(maxcols) (output)
 74:          double precision (or double complex) values(maxcols) output
 75: .ve
 76:    where maxcols >= maximum nonzeros in any row of the matrix.

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

 82:    Level: advanced

 84:    Concepts: matrices^row access

 86: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubmatrices(), MatGetDiagonal()
 87: @*/
 88: int MatGetRow(Mat mat,int row,int *ncols,int *cols[],PetscScalar *vals[])
 89: {
 90:   int   incols,ierr;

 95:   MatPreallocated(mat);
 96:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
 97:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
 98:   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
 99:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
100:   (*mat->ops->getrow)(mat,row,&incols,cols,vals);
101:   if (ncols) *ncols = incols;
102:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
103:   return(0);
104: }

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

111:    Not Collective

113:    Input Parameters:
114: +  mat - the matrix
115: .  row - the row to get
116: .  ncols, cols - the number of nonzeros and their columns
117: -  vals - if nonzero the column values

119:    Notes: 
120:    This routine should be called after you have finished examining the entries.

122:    Fortran Notes:
123:    The calling sequence from Fortran is 
124: .vb
125:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
126:       Mat     matrix (input)
127:       integer row    (input)
128:       integer ncols  (output)
129:       integer cols(maxcols) (output)
130:       double precision (or double complex) values(maxcols) output
131: .ve
132:    Where maxcols >= maximum nonzeros in any row of the matrix. 

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

137:    Level: advanced

139: .seealso:  MatGetRow()
140: @*/
141: int MatRestoreRow(Mat mat,int row,int *ncols,int *cols[],PetscScalar *vals[])
142: {

148:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
149:   if (!mat->ops->restorerow) return(0);
150:   (*mat->ops->restorerow)(mat,row,ncols,cols,vals);
151:   PetscObjectIncreaseState((PetscObject)mat);
152:   return(0);
153: }

157: /*@C
158:    MatView - Visualizes a matrix object.

160:    Collective on Mat

162:    Input Parameters:
163: +  mat - the matrix
164: -  viewer - visualization context

166:   Notes:
167:   The available visualization contexts include
168: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
169: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
170:         output where only the first processor opens
171:         the file.  All other processors send their 
172:         data to the first processor to print. 
173: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

175:    The user can open alternative visualization contexts with
176: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
177: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
178:          specified file; corresponding input uses MatLoad()
179: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to 
180:          an X window display
181: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
182:          Currently only the sequential dense and AIJ
183:          matrix types support the Socket viewer.

185:    The user can call PetscViewerSetFormat() to specify the output
186:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
187:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
188: +    PETSC_VIEWER_ASCII_DEFAULT - default, prints matrix contents
189: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
190: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
191: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 
192:          format common among all matrix types
193: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 
194:          format (which is in many cases the same as the default)
195: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
196:          size and structure (not the matrix entries)
197: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
198:          the matrix structure

200:    Options Database Keys:
201: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
202: .  -mat_view_info_detailed - Prints more detailed info
203: .  -mat_view - Prints matrix in ASCII format
204: .  -mat_view_matlab - Prints matrix in Matlab format
205: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
206: .  -display <name> - Sets display name (default is host)
207: .  -draw_pause <sec> - Sets number of seconds to pause after display
208: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
209: .  -viewer_socket_machine <machine>
210: .  -viewer_socket_port <port>
211: .  -mat_view_binary - save matrix to file in binary format
212: -  -viewer_binary_filename <name>
213:    Level: beginner

215:    Concepts: matrices^viewing
216:    Concepts: matrices^plotting
217:    Concepts: matrices^printing

219: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 
220:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
221: @*/
222: int MatView(Mat mat,PetscViewer viewer)
223: {
224:   int               ierr,rows,cols;
225:   PetscTruth        isascii;
226:   char              *cstr;
227:   PetscViewerFormat format;

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

238:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
239:   if (isascii) {
240:     PetscViewerGetFormat(viewer,&format);
241:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
242:       if (mat->prefix) {
243:         PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",mat->prefix);
244:       } else {
245:         PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");
246:       }
247:       PetscViewerASCIIPushTab(viewer);
248:       MatGetType(mat,&cstr);
249:       MatGetSize(mat,&rows,&cols);
250:       PetscViewerASCIIPrintf(viewer,"type=%s, rows=%d, cols=%d\n",cstr,rows,cols);
251:       if (mat->ops->getinfo) {
252:         MatInfo info;
253:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
254:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%d, allocated nonzeros=%d\n",
255:                           (int)info.nz_used,(int)info.nz_allocated);
256:       }
257:     }
258:   }
259:   if (mat->ops->view) {
260:     PetscViewerASCIIPushTab(viewer);
261:     (*mat->ops->view)(mat,viewer);
262:     PetscViewerASCIIPopTab(viewer);
263:   } else if (!isascii) {
264:     SETERRQ1(1,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
265:   }
266:   if (isascii) {
267:     PetscViewerGetFormat(viewer,&format);
268:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
269:       PetscViewerASCIIPopTab(viewer);
270:     }
271:   }
272:   return(0);
273: }

277: /*@C
278:    MatScaleSystem - Scale a vector solution and right hand side to 
279:    match the scaling of a scaled matrix.
280:   
281:    Collective on Mat

283:    Input Parameter:
284: +  mat - the matrix
285: .  x - solution vector (or PETSC_NULL)
286: -  b - right hand side vector (or PETSC_NULL)


289:    Notes: 
290:    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not 
291:    internally scaled, so this does nothing. For MPIROWBS it
292:    permutes and diagonally scales.

294:    The KSP methods automatically call this routine when required
295:    (via PCPreSolve()) so it is rarely used directly.

297:    Level: Developer            

299:    Concepts: matrices^scaling

301: .seealso: MatUseScaledForm(), MatUnScaleSystem()
302: @*/
303: int MatScaleSystem(Mat mat,Vec x,Vec b)
304: {

310:   MatPreallocated(mat);

314:   if (mat->ops->scalesystem) {
315:     (*mat->ops->scalesystem)(mat,x,b);
316:   }
317:   PetscObjectIncreaseState((PetscObject)mat);
318:   return(0);
319: }

323: /*@C
324:    MatUnScaleSystem - Unscales a vector solution and right hand side to 
325:    match the original scaling of a scaled matrix.
326:   
327:    Collective on Mat

329:    Input Parameter:
330: +  mat - the matrix
331: .  x - solution vector (or PETSC_NULL)
332: -  b - right hand side vector (or PETSC_NULL)


335:    Notes: 
336:    For AIJ, BAIJ, and BDiag matrix formats, the matrices are not 
337:    internally scaled, so this does nothing. For MPIROWBS it
338:    permutes and diagonally scales.

340:    The KSP methods automatically call this routine when required
341:    (via PCPreSolve()) so it is rarely used directly.

343:    Level: Developer            

345: .seealso: MatUseScaledForm(), MatScaleSystem()
346: @*/
347: int MatUnScaleSystem(Mat mat,Vec x,Vec b)
348: {

354:   MatPreallocated(mat);
357:   if (mat->ops->unscalesystem) {
358:     (*mat->ops->unscalesystem)(mat,x,b);
359:   }
360:   return(0);
361: }

365: /*@C
366:    MatUseScaledForm - For matrix storage formats that scale the 
367:    matrix (for example MPIRowBS matrices are diagonally scaled on
368:    assembly) indicates matrix operations (MatMult() etc) are 
369:    applied using the scaled matrix.
370:   
371:    Collective on Mat

373:    Input Parameter:
374: +  mat - the matrix
375: -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for 
376:             applying the original matrix

378:    Notes: 
379:    For scaled matrix formats, applying the original, unscaled matrix
380:    will be slightly more expensive

382:    Level: Developer            

384: .seealso: MatScaleSystem(), MatUnScaleSystem()
385: @*/
386: int MatUseScaledForm(Mat mat,PetscTruth scaled)
387: {

393:   MatPreallocated(mat);
394:   if (mat->ops->usescaledform) {
395:     (*mat->ops->usescaledform)(mat,scaled);
396:   }
397:   return(0);
398: }

402: /*@C
403:    MatDestroy - Frees space taken by a matrix.
404:   
405:    Collective on Mat

407:    Input Parameter:
408: .  A - the matrix

410:    Level: beginner

412: @*/
413: int MatDestroy(Mat A)
414: {

420:   MatPreallocated(A);
421:   if (--A->refct > 0) return(0);

423:   /* if memory was published with AMS then destroy it */
424:   PetscObjectDepublish(A);
425:   if (A->mapping) {
426:     ISLocalToGlobalMappingDestroy(A->mapping);
427:   }
428:   if (A->bmapping) {
429:     ISLocalToGlobalMappingDestroy(A->bmapping);
430:   }
431:   if (A->rmap) {
432:     PetscMapDestroy(A->rmap);
433:   }
434:   if (A->cmap) {
435:     PetscMapDestroy(A->cmap);
436:   }

438:   (*A->ops->destroy)(A);
439:   PetscLogObjectDestroy(A);
440:   PetscHeaderDestroy(A);
441:   return(0);
442: }

446: /*@
447:    MatValid - Checks whether a matrix object is valid.

449:    Collective on Mat

451:    Input Parameter:
452: .  m - the matrix to check 

454:    Output Parameter:
455:    flg - flag indicating matrix status, either
456:    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.

458:    Level: developer

460:    Concepts: matrices^validity
461: @*/
462: int MatValid(Mat m,PetscTruth *flg)
463: {
466:   if (!m)                           *flg = PETSC_FALSE;
467:   else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
468:   else                              *flg = PETSC_TRUE;
469:   return(0);
470: }

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

479:    Not Collective

481:    Input Parameters:
482: +  mat - the matrix
483: .  v - a logically two-dimensional array of values
484: .  m, idxm - the number of rows and their global indices 
485: .  n, idxn - the number of columns and their global indices
486: -  addv - either ADD_VALUES or INSERT_VALUES, where
487:    ADD_VALUES adds values to any existing entries, and
488:    INSERT_VALUES replaces existing entries with new values

490:    Notes:
491:    By default the values, v, are row-oriented and unsorted.
492:    See MatSetOption() for other options.

494:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 
495:    options cannot be mixed without intervening calls to the assembly
496:    routines.

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

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

506:    Efficiency Alert:
507:    The routine MatSetValuesBlocked() may offer much better efficiency
508:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

510:    Level: beginner

512:    Concepts: matrices^putting entries in

514: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
515: @*/
516: int MatSetValues(Mat mat,int m,const int idxm[],int n,const int idxn[],const PetscScalar v[],InsertMode addv)
517: {

521:   if (!m || !n) return(0); /* no values to insert */
524:   MatPreallocated(mat);
528:   if (mat->insertmode == NOT_SET_VALUES) {
529:     mat->insertmode = addv;
530:   }
531: #if defined(PETSC_USE_BOPT_g)
532:   else if (mat->insertmode != addv) {
533:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
534:   }
535:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
536: #endif

538:   if (mat->assembled) {
539:     mat->was_assembled = PETSC_TRUE;
540:     mat->assembled     = PETSC_FALSE;
541:   }
542:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
543:   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
544:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
545:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
546:   return(0);
547: }

551: /*@C 
552:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
553:      Using structured grid indexing

555:    Not Collective

557:    Input Parameters:
558: +  mat - the matrix
559: .  v - a logically two-dimensional array of values
560: .  m - number of rows being entered
561: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
562: .  n - number of columns being entered
563: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 
564: -  addv - either ADD_VALUES or INSERT_VALUES, where
565:    ADD_VALUES adds values to any existing entries, and
566:    INSERT_VALUES replaces existing entries with new values

568:    Notes:
569:    By default the values, v, are row-oriented and unsorted.
570:    See MatSetOption() for other options.

572:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 
573:    options cannot be mixed without intervening calls to the assembly
574:    routines.

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

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

581:    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine

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

586:    The columns and rows in the stencil passed in MUST be contained within the 
587:    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
588:    if you create a DA with an overlap of one grid level and on a particular process its first
589:    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
590:    first i index you can use in your column and row indices in MatSetStencil() is 5.

592:    In Fortran idxm and idxn should be declared as
593: $     MatStencil idxm(4,m),idxn(4,n)
594:    and the values inserted using
595: $    idxm(MatStencil_i,1) = i
596: $    idxm(MatStencil_j,1) = j
597: $    idxm(MatStencil_k,1) = k
598: $    idxm(MatStencil_c,1) = c
599:    etc

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

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

609:    Efficiency Alert:
610:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
611:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

613:    Level: beginner

615:    Concepts: matrices^putting entries in

617: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
618:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
619: @*/
620: int MatSetValuesStencil(Mat mat,int m,const MatStencil idxm[],int n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
621: {
622:   int j,i,ierr,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
623:   int *starts = mat->stencil.starts,*dxm = (int*)idxm,*dxn = (int*)idxn,sdim = dim - (1 - (int)mat->stencil.noc);

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

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

636:   for (i=0; i<m; i++) {
637:     for (j=0; j<3-sdim; j++) dxm++;
638:     tmp = *dxm++ - starts[0];
639:     for (j=0; j<dim-1; j++) {
640:       tmp = tmp*dims[j] + *dxm++ - starts[j+1];
641:     }
642:     if (mat->stencil.noc) dxm++;
643:     jdxm[i] = tmp;
644:   }
645:   for (i=0; i<n; i++) {
646:     for (j=0; j<3-sdim; j++) dxn++;
647:     tmp = *dxn++ - starts[0];
648:     for (j=0; j<dim-1; j++) {
649:       tmp = tmp*dims[j] + *dxn++ - starts[j+1];
650:     }
651:     if (mat->stencil.noc) dxn++;
652:     jdxn[i] = tmp;
653:   }
654:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
655:   return(0);
656: }

660: /*@C 
661:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
662:      Using structured grid indexing

664:    Not Collective

666:    Input Parameters:
667: +  mat - the matrix
668: .  v - a logically two-dimensional array of values
669: .  m - number of rows being entered
670: .  idxm - grid coordinates for matrix rows being entered
671: .  n - number of columns being entered
672: .  idxn - grid coordinates for matrix columns being entered 
673: -  addv - either ADD_VALUES or INSERT_VALUES, where
674:    ADD_VALUES adds values to any existing entries, and
675:    INSERT_VALUES replaces existing entries with new values

677:    Notes:
678:    By default the values, v, are row-oriented and unsorted.
679:    See MatSetOption() for other options.

681:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 
682:    options cannot be mixed without intervening calls to the assembly
683:    routines.

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

687:    MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 
688:    as well as in C.

690:    For setting/accessing vector values via array coordinates you can use the DAVecGetArray() routine

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

695:    The columns and rows in the stencil passed in MUST be contained within the 
696:    ghost region of the given process as set with DACreateXXX() or MatSetStencil(). For example,
697:    if you create a DA with an overlap of one grid level and on a particular process its first
698:    local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
699:    first i index you can use in your column and row indices in MatSetStencil() is 5.

701:    In Fortran idxm and idxn should be declared as
702: $     MatStencil idxm(4,m),idxn(4,n)
703:    and the values inserted using
704: $    idxm(MatStencil_i,1) = i
705: $    idxm(MatStencil_j,1) = j
706: $    idxm(MatStencil_k,1) = k
707:    etc

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

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

717:    Level: beginner

719:    Concepts: matrices^putting entries in

721: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
722:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
723: @*/
724: int MatSetValuesBlockedStencil(Mat mat,int m,const MatStencil idxm[],int n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
725: {
726:   int j,i,ierr,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
727:   int *starts = mat->stencil.starts,*dxm = (int*)idxm,*dxn = (int*)idxn,sdim = dim - (1 - (int)mat->stencil.noc);

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

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

740:   for (i=0; i<m; i++) {
741:     for (j=0; j<3-sdim; j++) dxm++;
742:     tmp = *dxm++ - starts[0];
743:     for (j=0; j<sdim-1; j++) {
744:       tmp = tmp*dims[j] + *dxm++ - starts[j+1];
745:     }
746:     dxm++;
747:     jdxm[i] = tmp;
748:   }
749:   for (i=0; i<n; i++) {
750:     for (j=0; j<3-sdim; j++) dxn++;
751:     tmp = *dxn++ - starts[0];
752:     for (j=0; j<sdim-1; j++) {
753:       tmp = tmp*dims[j] + *dxn++ - starts[j+1];
754:     }
755:     dxn++;
756:     jdxn[i] = tmp;
757:   }
758:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
759:   return(0);
760: }

764: /*@ 
765:    MatSetStencil - Sets the grid information for setting values into a matrix via
766:         MatSetValuesStencil()

768:    Not Collective

770:    Input Parameters:
771: +  mat - the matrix
772: .  dim - dimension of the grid 1, 2, or 3
773: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
774: .  starts - starting point of ghost nodes on your processor in x, y, and z direction 
775: -  dof - number of degrees of freedom per node


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

781:    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
782:    user.
783:    
784:    Level: beginner

786:    Concepts: matrices^putting entries in

788: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
789:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
790: @*/
791: int MatSetStencil(Mat mat,int dim,const int dims[],const int starts[],int dof)
792: {
793:   int i;


800:   mat->stencil.dim = dim + (dof > 1);
801:   for (i=0; i<dim; i++) {
802:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
803:     mat->stencil.starts[i] = starts[dim-i-1];
804:   }
805:   mat->stencil.dims[dim]   = dof;
806:   mat->stencil.starts[dim] = 0;
807:   mat->stencil.noc         = (PetscTruth)(dof == 1);
808:   return(0);
809: }

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

816:    Not Collective

818:    Input Parameters:
819: +  mat - the matrix
820: .  v - a logically two-dimensional array of values
821: .  m, idxm - the number of block rows and their global block indices 
822: .  n, idxn - the number of block columns and their global block indices
823: -  addv - either ADD_VALUES or INSERT_VALUES, where
824:    ADD_VALUES adds values to any existing entries, and
825:    INSERT_VALUES replaces existing entries with new values

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

831:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
832:    options cannot be mixed without intervening calls to the assembly
833:    routines.

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

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

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

849:    Restrictions:
850:    MatSetValuesBlocked() is currently supported only for the BAIJ and SBAIJ formats

852:    Level: intermediate

854:    Concepts: matrices^putting entries in blocked

856: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
857: @*/
858: int MatSetValuesBlocked(Mat mat,int m,const int idxm[],int n,const int idxn[],const PetscScalar v[],InsertMode addv)
859: {

863:   if (!m || !n) return(0); /* no values to insert */
866:   MatPreallocated(mat);
870:   if (mat->insertmode == NOT_SET_VALUES) {
871:     mat->insertmode = addv;
872:   }
873: #if defined(PETSC_USE_BOPT_g) 
874:   else if (mat->insertmode != addv) {
875:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
876:   }
877:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
878: #endif

880:   if (mat->assembled) {
881:     mat->was_assembled = PETSC_TRUE;
882:     mat->assembled     = PETSC_FALSE;
883:   }
884:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
885:   if (!mat->ops->setvaluesblocked) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
886:   (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
887:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
888:   return(0);
889: }

893: /*@ 
894:    MatGetValues - Gets a block of values from a matrix.

896:    Not Collective; currently only returns a local block

898:    Input Parameters:
899: +  mat - the matrix
900: .  v - a logically two-dimensional array for storing the values
901: .  m, idxm - the number of rows and their global indices 
902: -  n, idxn - the number of columns and their global indices

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

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

912:    MatGetValues() requires that the matrix has been assembled
913:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
914:    MatSetValues() and MatGetValues() CANNOT be made in succession
915:    without intermediate matrix assembly.

917:    Level: advanced

919:    Concepts: matrices^accessing values

921: .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues()
922: @*/
923: int MatGetValues(Mat mat,int m,const int idxm[],int n,const int idxn[],PetscScalar v[])
924: {

930:   MatPreallocated(mat);
934:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
935:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
936:   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

938:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
939:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
940:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
941:   return(0);
942: }

946: /*@
947:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
948:    the routine MatSetValuesLocal() to allow users to insert matrix entries
949:    using a local (per-processor) numbering.

951:    Not Collective

953:    Input Parameters:
954: +  x - the matrix
955: -  mapping - mapping created with ISLocalToGlobalMappingCreate() 
956:              or ISLocalToGlobalMappingCreateIS()

958:    Level: intermediate

960:    Concepts: matrices^local to global mapping
961:    Concepts: local to global mapping^for matrices

963: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
964: @*/
965: int MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
966: {
971:   MatPreallocated(x);
973:   if (x->mapping) {
974:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
975:   }

977:   if (x->ops->setlocaltoglobalmapping) {
978:     (*x->ops->setlocaltoglobalmapping)(x,mapping);
979:   } else {
980:     x->mapping = mapping;
981:     PetscObjectReference((PetscObject)mapping);
982:   }
983:   return(0);
984: }

988: /*@
989:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
990:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
991:    entries using a local (per-processor) numbering.

993:    Not Collective

995:    Input Parameters:
996: +  x - the matrix
997: -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
998:              ISLocalToGlobalMappingCreateIS()

1000:    Level: intermediate

1002:    Concepts: matrices^local to global mapping blocked
1003:    Concepts: local to global mapping^for matrices, blocked

1005: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1006:            MatSetValuesBlocked(), MatSetValuesLocal()
1007: @*/
1008: int MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1009: {
1014:   MatPreallocated(x);
1016:   if (x->bmapping) {
1017:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1018:   }
1019: 
1020:   x->bmapping = mapping;
1021:   PetscObjectReference((PetscObject)mapping);
1022:   return(0);
1023: }

1027: /*@
1028:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1029:    using a local ordering of the nodes. 

1031:    Not Collective

1033:    Input Parameters:
1034: +  x - the matrix
1035: .  nrow, irow - number of rows and their local indices
1036: .  ncol, icol - number of columns and their local indices
1037: .  y -  a logically two-dimensional array of values
1038: -  addv - either INSERT_VALUES or ADD_VALUES, where
1039:    ADD_VALUES adds values to any existing entries, and
1040:    INSERT_VALUES replaces existing entries with new values

1042:    Notes:
1043:    Before calling MatSetValuesLocal(), the user must first set the
1044:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

1046:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
1047:    options cannot be mixed without intervening calls to the assembly
1048:    routines.

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

1053:    Level: intermediate

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

1057: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1058:            MatSetValueLocal()
1059: @*/
1060: int MatSetValuesLocal(Mat mat,int nrow,const int irow[],int ncol,const int icol[],const PetscScalar y[],InsertMode addv)
1061: {
1062:   int ierr,irowm[2048],icolm[2048];

1067:   MatPreallocated(mat);

1072:   if (mat->insertmode == NOT_SET_VALUES) {
1073:     mat->insertmode = addv;
1074:   }
1075: #if defined(PETSC_USE_BOPT_g) 
1076:   else if (mat->insertmode != addv) {
1077:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1078:   }
1079:   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1080:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
1081:   }
1082:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1083: #endif

1085:   if (mat->assembled) {
1086:     mat->was_assembled = PETSC_TRUE;
1087:     mat->assembled     = PETSC_FALSE;
1088:   }
1089:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1090:   if (!mat->ops->setvalueslocal) {
1091:     ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);
1092:     ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);
1093:     (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);
1094:   } else {
1095:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1096:   }
1097:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1098:   return(0);
1099: }

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

1107:    Not Collective

1109:    Input Parameters:
1110: +  x - the matrix
1111: .  nrow, irow - number of rows and their local indices
1112: .  ncol, icol - number of columns and their local indices
1113: .  y -  a logically two-dimensional array of values
1114: -  addv - either INSERT_VALUES or ADD_VALUES, where
1115:    ADD_VALUES adds values to any existing entries, and
1116:    INSERT_VALUES replaces existing entries with new values

1118:    Notes:
1119:    Before calling MatSetValuesBlockedLocal(), the user must first set the
1120:    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1121:    where the mapping MUST be set for matrix blocks, not for matrix elements.

1123:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
1124:    options cannot be mixed without intervening calls to the assembly
1125:    routines.

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

1130:    Level: intermediate

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

1134: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1135: @*/
1136: int MatSetValuesBlockedLocal(Mat mat,int nrow,const int irow[],int ncol,const int icol[],const PetscScalar y[],InsertMode addv)
1137: {
1138:   int ierr,irowm[2048],icolm[2048];

1143:   MatPreallocated(mat);
1147:   if (mat->insertmode == NOT_SET_VALUES) {
1148:     mat->insertmode = addv;
1149:   }
1150: #if defined(PETSC_USE_BOPT_g) 
1151:   else if (mat->insertmode != addv) {
1152:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1153:   }
1154:   if (!mat->bmapping) {
1155:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1156:   }
1157:   if (nrow > 2048 || ncol > 2048) {
1158:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol);
1159:   }
1160:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1161: #endif

1163:   if (mat->assembled) {
1164:     mat->was_assembled = PETSC_TRUE;
1165:     mat->assembled     = PETSC_FALSE;
1166:   }
1167:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1168:   ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);
1169:   ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);
1170:   (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);
1171:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1172:   return(0);
1173: }

1175: /* --------------------------------------------------------*/
1178: /*@
1179:    MatMult - Computes the matrix-vector product, y = Ax.

1181:    Collective on Mat and Vec

1183:    Input Parameters:
1184: +  mat - the matrix
1185: -  x   - the vector to be multiplied

1187:    Output Parameters:
1188: .  y - the result

1190:    Notes:
1191:    The vectors x and y cannot be the same.  I.e., one cannot
1192:    call MatMult(A,y,y).

1194:    Level: beginner

1196:    Concepts: matrix-vector product

1198: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1199: @*/
1200: int MatMult(Mat mat,Vec x,Vec y)
1201: {

1207:   MatPreallocated(mat);

1211:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1212:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1213:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1214: #ifndef PETSC_HAVE_CONSTRAINTS
1215:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1216:   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1217:   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);
1218: #endif

1220:   if (mat->nullsp) {
1221:     MatNullSpaceRemove(mat->nullsp,x,&x);
1222:   }

1224:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1225:   (*mat->ops->mult)(mat,x,y);
1226:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);

1228:   if (mat->nullsp) {
1229:     MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1230:   }
1231:   PetscObjectIncreaseState((PetscObject)y);
1232:   return(0);
1233: }

1237: /*@
1238:    MatMultTranspose - Computes matrix transpose times a vector.

1240:    Collective on Mat and Vec

1242:    Input Parameters:
1243: +  mat - the matrix
1244: -  x   - the vector to be multilplied

1246:    Output Parameters:
1247: .  y - the result

1249:    Notes:
1250:    The vectors x and y cannot be the same.  I.e., one cannot
1251:    call MatMultTranspose(A,y,y).

1253:    Level: beginner

1255:    Concepts: matrix vector product^transpose

1257: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1258: @*/
1259: int MatMultTranspose(Mat mat,Vec x,Vec y)
1260: {
1262:   PetscTruth flg1, flg2;

1267:   MatPreallocated(mat);

1271:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1272:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1273:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1274: #ifndef PETSC_HAVE_CONSTRAINTS
1275:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
1276:   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
1277: #endif

1279:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP, "Operation not supported");
1280:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1281:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1282: 
1283:   PetscTypeCompare((PetscObject)mat,MATSEQSBAIJ,&flg1);
1284:   PetscTypeCompare((PetscObject)mat,MATMPISBAIJ,&flg2);
1285:   if (flg1 || flg2) { /* mat is in sbaij format */
1286:     (*mat->ops->mult)(mat,x,y);
1287:   } else {
1288:     (*mat->ops->multtranspose)(mat,x,y);
1289:   }
1290:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1291:   PetscObjectIncreaseState((PetscObject)y);
1292:   return(0);
1293: }

1297: /*@
1298:     MatMultAdd -  Computes v3 = v2 + A * v1.

1300:     Collective on Mat and Vec

1302:     Input Parameters:
1303: +   mat - the matrix
1304: -   v1, v2 - the vectors

1306:     Output Parameters:
1307: .   v3 - the result

1309:     Notes:
1310:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1311:     call MatMultAdd(A,v1,v2,v1).

1313:     Level: beginner

1315:     Concepts: matrix vector product^addition

1317: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1318: @*/
1319: int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1320: {

1326:   MatPreallocated(mat);

1331:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1332:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1333:   if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N);
1334:   if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N);
1335:   if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N);
1336:   if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n);
1337:   if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n);
1338:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");

1340:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
1341:   (*mat->ops->multadd)(mat,v1,v2,v3);
1342:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
1343:   PetscObjectIncreaseState((PetscObject)v3);
1344:   return(0);
1345: }

1349: /*@
1350:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

1352:    Collective on Mat and Vec

1354:    Input Parameters:
1355: +  mat - the matrix
1356: -  v1, v2 - the vectors

1358:    Output Parameters:
1359: .  v3 - the result

1361:    Notes:
1362:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1363:    call MatMultTransposeAdd(A,v1,v2,v1).

1365:    Level: beginner

1367:    Concepts: matrix vector product^transpose and addition

1369: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1370: @*/
1371: int MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1372: {

1378:   MatPreallocated(mat);

1383:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1384:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1385:   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1386:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1387:   if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N);
1388:   if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N);
1389:   if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N);

1391:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
1392:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
1393:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
1394:   PetscObjectIncreaseState((PetscObject)v3);
1395:   return(0);
1396: }

1400: /*@
1401:    MatMultConstrained - The inner multiplication routine for a
1402:    constrained matrix P^T A P.

1404:    Collective on Mat and Vec

1406:    Input Parameters:
1407: +  mat - the matrix
1408: -  x   - the vector to be multilplied

1410:    Output Parameters:
1411: .  y - the result

1413:    Notes:
1414:    The vectors x and y cannot be the same.  I.e., one cannot
1415:    call MatMult(A,y,y).

1417:    Level: beginner

1419: .keywords: matrix, multiply, matrix-vector product, constraint
1420: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1421: @*/
1422: int MatMultConstrained(Mat mat,Vec x,Vec y)
1423: {

1430:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1431:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1432:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1433:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1434:   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
1435:   if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n);

1437:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1438:   (*mat->ops->multconstrained)(mat,x,y);
1439:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1440:   PetscObjectIncreaseState((PetscObject)y);

1442:   return(0);
1443: }

1447: /*@
1448:    MatMultTransposeConstrained - The inner multiplication routine for a
1449:    constrained matrix P^T A^T P.

1451:    Collective on Mat and Vec

1453:    Input Parameters:
1454: +  mat - the matrix
1455: -  x   - the vector to be multilplied

1457:    Output Parameters:
1458: .  y - the result

1460:    Notes:
1461:    The vectors x and y cannot be the same.  I.e., one cannot
1462:    call MatMult(A,y,y).

1464:    Level: beginner

1466: .keywords: matrix, multiply, matrix-vector product, constraint
1467: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1468: @*/
1469: int MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
1470: {

1477:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1478:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1479:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1480:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
1481:   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);

1483:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1484:   (*mat->ops->multtransposeconstrained)(mat,x,y);
1485:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1486:   PetscObjectIncreaseState((PetscObject)y);

1488:   return(0);
1489: }
1490: /* ------------------------------------------------------------*/
1493: /*@C
1494:    MatGetInfo - Returns information about matrix storage (number of
1495:    nonzeros, memory, etc.).

1497:    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
1498:    as the flag

1500:    Input Parameters:
1501: .  mat - the matrix

1503:    Output Parameters:
1504: +  flag - flag indicating the type of parameters to be returned
1505:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
1506:    MAT_GLOBAL_SUM - sum over all processors)
1507: -  info - matrix information context

1509:    Notes:
1510:    The MatInfo context contains a variety of matrix data, including
1511:    number of nonzeros allocated and used, number of mallocs during
1512:    matrix assembly, etc.  Additional information for factored matrices
1513:    is provided (such as the fill ratio, number of mallocs during
1514:    factorization, etc.).  Much of this info is printed to STDOUT
1515:    when using the runtime options 
1516: $       -log_info -mat_view_info

1518:    Example for C/C++ Users:
1519:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
1520:    data within the MatInfo context.  For example, 
1521: .vb
1522:       MatInfo info;
1523:       Mat     A;
1524:       double  mal, nz_a, nz_u;

1526:       MatGetInfo(A,MAT_LOCAL,&info);
1527:       mal  = info.mallocs;
1528:       nz_a = info.nz_allocated;
1529: .ve

1531:    Example for Fortran Users:
1532:    Fortran users should declare info as a double precision
1533:    array of dimension MAT_INFO_SIZE, and then extract the parameters
1534:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
1535:    a complete list of parameter names.
1536: .vb
1537:       double  precision info(MAT_INFO_SIZE)
1538:       double  precision mal, nz_a
1539:       Mat     A
1540:       integer ierr

1542:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
1543:       mal = info(MAT_INFO_MALLOCS)
1544:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
1545: .ve

1547:     Level: intermediate

1549:     Concepts: matrices^getting information on
1550:  
1551: @*/
1552: int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
1553: {

1559:   MatPreallocated(mat);
1561:   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1562:   (*mat->ops->getinfo)(mat,flag,info);
1563:   return(0);
1564: }

1566: /* ----------------------------------------------------------*/
1569: /*@C  
1570:    MatILUDTFactor - Performs a drop tolerance ILU factorization.

1572:    Collective on Mat

1574:    Input Parameters:
1575: +  mat - the matrix
1576: .  info - information about the factorization to be done
1577: .  row - row permutation
1578: -  col - column permutation

1580:    Output Parameters:
1581: .  fact - the factored matrix

1583:    Level: developer

1585:    Notes:
1586:    Most users should employ the simplified KSP interface for linear solvers
1587:    instead of working directly with matrix algebra routines such as this.
1588:    See, e.g., KSPCreate().

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

1595:     Concepts: matrices^ILUDT factorization

1597: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1598: @*/
1599: int MatILUDTFactor(Mat mat,MatFactorInfo *info,IS row,IS col,Mat *fact)
1600: {

1606:   MatPreallocated(mat);
1611:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1612:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1613:   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1615:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1616:   (*mat->ops->iludtfactor)(mat,info,row,col,fact);
1617:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
1618:   PetscObjectIncreaseState((PetscObject)*fact);

1620:   return(0);
1621: }

1625: /*@  
1626:    MatLUFactor - Performs in-place LU factorization of matrix.

1628:    Collective on Mat

1630:    Input Parameters:
1631: +  mat - the matrix
1632: .  row - row permutation
1633: .  col - column permutation
1634: -  info - options for factorization, includes 
1635: $          fill - expected fill as ratio of original fill.
1636: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1637: $                   Run with the option -log_info to determine an optimal value to use

1639:    Notes:
1640:    Most users should employ the simplified KSP interface for linear solvers
1641:    instead of working directly with matrix algebra routines such as this.
1642:    See, e.g., KSPCreate().

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

1647:    Level: developer

1649:    Concepts: matrices^LU factorization

1651: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
1652:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo

1654: @*/
1655: int MatLUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1656: {

1665:   MatPreallocated(mat);
1666:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1667:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1668:   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1670:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
1671:   (*mat->ops->lufactor)(mat,row,col,info);
1672:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
1673:   PetscObjectIncreaseState((PetscObject)mat);
1674:   return(0);
1675: }

1679: /*@  
1680:    MatILUFactor - Performs in-place ILU factorization of matrix.

1682:    Collective on Mat

1684:    Input Parameters:
1685: +  mat - the matrix
1686: .  row - row permutation
1687: .  col - column permutation
1688: -  info - structure containing 
1689: $      levels - number of levels of fill.
1690: $      expected fill - as ratio of original fill.
1691: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
1692:                 missing diagonal entries)

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

1698:    Most users should employ the simplified KSP interface for linear solvers
1699:    instead of working directly with matrix algebra routines such as this.
1700:    See, e.g., KSPCreate().

1702:    Level: developer

1704:    Concepts: matrices^ILU factorization

1706: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1707: @*/
1708: int MatILUFactor(Mat mat,IS row,IS col,MatFactorInfo *info)
1709: {

1718:   MatPreallocated(mat);
1719:   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
1720:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1721:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1722:   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1724:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
1725:   (*mat->ops->ilufactor)(mat,row,col,info);
1726:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
1727:   PetscObjectIncreaseState((PetscObject)mat);
1728:   return(0);
1729: }

1733: /*@  
1734:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
1735:    Call this routine before calling MatLUFactorNumeric().

1737:    Collective on Mat

1739:    Input Parameters:
1740: +  mat - the matrix
1741: .  row, col - row and column permutations
1742: -  info - options for factorization, includes 
1743: $          fill - expected fill as ratio of original fill.
1744: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1745: $                   Run with the option -log_info to determine an optimal value to use

1747:    Output Parameter:
1748: .  fact - new matrix that has been symbolically factored

1750:    Notes:
1751:    See the users manual for additional information about
1752:    choosing the fill factor for better efficiency.

1754:    Most users should employ the simplified KSP interface for linear solvers
1755:    instead of working directly with matrix algebra routines such as this.
1756:    See, e.g., KSPCreate().

1758:    Level: developer

1760:    Concepts: matrices^LU symbolic factorization

1762: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
1763: @*/
1764: int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
1765: {

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

1780:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
1781:   (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);
1782:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
1783:   PetscObjectIncreaseState((PetscObject)*fact);
1784:   return(0);
1785: }

1789: /*@  
1790:    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
1791:    Call this routine after first calling MatLUFactorSymbolic().

1793:    Collective on Mat

1795:    Input Parameters:
1796: +  mat - the matrix
1797: -  fact - the matrix generated for the factor, from MatLUFactorSymbolic()

1799:    Notes:
1800:    See MatLUFactor() for in-place factorization.  See 
1801:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

1803:    Most users should employ the simplified KSP interface for linear solvers
1804:    instead of working directly with matrix algebra routines such as this.
1805:    See, e.g., KSPCreate().

1807:    Level: developer

1809:    Concepts: matrices^LU numeric factorization

1811: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
1812: @*/
1813: int MatLUFactorNumeric(Mat mat,Mat *fact)
1814: {
1815:   int        ierr;

1820:   MatPreallocated(mat);
1823:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1824:   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1825:     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d",
1826:             mat->M,(*fact)->M,mat->N,(*fact)->N);
1827:   }
1828:   if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1830:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);
1831:   (*(*fact)->ops->lufactornumeric)(mat,fact);
1832:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);

1834:   MatView_Private(*fact);
1835:   PetscObjectIncreaseState((PetscObject)*fact);
1836:   return(0);
1837: }

1841: /*@  
1842:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
1843:    symmetric matrix. 

1845:    Collective on Mat

1847:    Input Parameters:
1848: +  mat - the matrix
1849: .  perm - row and column permutations
1850: -  f - expected fill as ratio of original fill

1852:    Notes:
1853:    See MatLUFactor() for the nonsymmetric case.  See also
1854:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

1856:    Most users should employ the simplified KSP interface for linear solvers
1857:    instead of working directly with matrix algebra routines such as this.
1858:    See, e.g., KSPCreate().

1860:    Level: developer

1862:    Concepts: matrices^Cholesky factorization

1864: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
1865:           MatGetOrdering()

1867: @*/
1868: int MatCholeskyFactor(Mat mat,IS perm,MatFactorInfo *info)
1869: {

1875:   MatPreallocated(mat);
1878:   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1879:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1880:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1881:   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1883:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
1884:   (*mat->ops->choleskyfactor)(mat,perm,info);
1885:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
1886:   PetscObjectIncreaseState((PetscObject)mat);
1887:   return(0);
1888: }

1892: /*@  
1893:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
1894:    of a symmetric matrix. 

1896:    Collective on Mat

1898:    Input Parameters:
1899: +  mat - the matrix
1900: .  perm - row and column permutations
1901: -  info - options for factorization, includes 
1902: $          fill - expected fill as ratio of original fill.
1903: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
1904: $                   Run with the option -log_info to determine an optimal value to use

1906:    Output Parameter:
1907: .  fact - the factored matrix

1909:    Notes:
1910:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
1911:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

1913:    Most users should employ the simplified KSP interface for linear solvers
1914:    instead of working directly with matrix algebra routines such as this.
1915:    See, e.g., KSPCreate().

1917:    Level: developer

1919:    Concepts: matrices^Cholesky symbolic factorization

1921: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
1922:           MatGetOrdering()

1924: @*/
1925: int MatCholeskyFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
1926: {

1932:   MatPreallocated(mat);
1936:   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
1937:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1938:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1939:   if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

1941:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1942:   (*mat->ops->choleskyfactorsymbolic)(mat,perm,info,fact);
1943:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
1944:   PetscObjectIncreaseState((PetscObject)*fact);
1945:   return(0);
1946: }

1950: /*@  
1951:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
1952:    of a symmetric matrix. Call this routine after first calling
1953:    MatCholeskyFactorSymbolic().

1955:    Collective on Mat

1957:    Input Parameter:
1958: .  mat - the initial matrix

1960:    Output Parameter:
1961: .  fact - the factored matrix

1963:    Notes:
1964:    Most users should employ the simplified KSP interface for linear solvers
1965:    instead of working directly with matrix algebra routines such as this.
1966:    See, e.g., KSPCreate().

1968:    Level: developer

1970:    Concepts: matrices^Cholesky numeric factorization

1972: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
1973: @*/
1974: int MatCholeskyFactorNumeric(Mat mat,Mat *fact)
1975: {

1981:   MatPreallocated(mat);
1983:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1984:   if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
1985:   if (mat->M != (*fact)->M || mat->N != (*fact)->N) {
1986:     SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d",
1987:             mat->M,(*fact)->M,mat->N,(*fact)->N);
1988:   }

1990:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1991:   (*(*fact)->ops->choleskyfactornumeric)(mat,fact);
1992:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);
1993:   PetscObjectIncreaseState((PetscObject)*fact);
1994:   return(0);
1995: }

1997: /* ----------------------------------------------------------------*/
2000: /*@
2001:    MatSolve - Solves A x = b, given a factored matrix.

2003:    Collective on Mat and Vec

2005:    Input Parameters:
2006: +  mat - the factored matrix
2007: -  b - the right-hand-side vector

2009:    Output Parameter:
2010: .  x - the result vector

2012:    Notes:
2013:    The vectors b and x cannot be the same.  I.e., one cannot
2014:    call MatSolve(A,x,x).

2016:    Notes:
2017:    Most users should employ the simplified KSP interface for linear solvers
2018:    instead of working directly with matrix algebra routines such as this.
2019:    See, e.g., KSPCreate().

2021:    Level: developer

2023:    Concepts: matrices^triangular solves

2025: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2026: @*/
2027: int MatSolve(Mat mat,Vec b,Vec x)
2028: {

2034:   MatPreallocated(mat);
2039:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2040:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2041:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2042:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2043:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2044:   if (mat->M == 0 && mat->N == 0) return(0);

2046:   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2047:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2048:   (*mat->ops->solve)(mat,b,x);
2049:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2050:   PetscObjectIncreaseState((PetscObject)x);
2051:   return(0);
2052: }

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

2059:    Collective on Mat and Vec

2061:    Input Parameters:
2062: +  mat - the factored matrix
2063: -  b - the right-hand-side vector

2065:    Output Parameter:
2066: .  x - the result vector

2068:    Notes:
2069:    MatSolve() should be used for most applications, as it performs
2070:    a forward solve followed by a backward solve.

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

2075:    Most users should employ the simplified KSP interface for linear solvers
2076:    instead of working directly with matrix algebra routines such as this.
2077:    See, e.g., KSPCreate().

2079:    Level: developer

2081:    Concepts: matrices^forward solves

2083: .seealso: MatSolve(), MatBackwardSolve()
2084: @ */
2085: int MatForwardSolve(Mat mat,Vec b,Vec x)
2086: {

2092:   MatPreallocated(mat);
2097:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2098:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2099:   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2100:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2101:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2102:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);

2104:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2105:   (*mat->ops->forwardsolve)(mat,b,x);
2106:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2107:   PetscObjectIncreaseState((PetscObject)x);
2108:   return(0);
2109: }

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

2116:    Collective on Mat and Vec

2118:    Input Parameters:
2119: +  mat - the factored matrix
2120: -  b - the right-hand-side vector

2122:    Output Parameter:
2123: .  x - the result vector

2125:    Notes:
2126:    MatSolve() should be used for most applications, as it performs
2127:    a forward solve followed by a backward solve.

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

2132:    Most users should employ the simplified KSP interface for linear solvers
2133:    instead of working directly with matrix algebra routines such as this.
2134:    See, e.g., KSPCreate().

2136:    Level: developer

2138:    Concepts: matrices^backward solves

2140: .seealso: MatSolve(), MatForwardSolve()
2141: @ */
2142: int MatBackwardSolve(Mat mat,Vec b,Vec x)
2143: {

2149:   MatPreallocated(mat);
2154:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2155:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2156:   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2157:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2158:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2159:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);

2161:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
2162:   (*mat->ops->backwardsolve)(mat,b,x);
2163:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
2164:   PetscObjectIncreaseState((PetscObject)x);
2165:   return(0);
2166: }

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

2173:    Collective on Mat and Vec

2175:    Input Parameters:
2176: +  mat - the factored matrix
2177: .  b - the right-hand-side vector
2178: -  y - the vector to be added to 

2180:    Output Parameter:
2181: .  x - the result vector

2183:    Notes:
2184:    The vectors b and x cannot be the same.  I.e., one cannot
2185:    call MatSolveAdd(A,x,y,x).

2187:    Most users should employ the simplified KSP interface for linear solvers
2188:    instead of working directly with matrix algebra routines such as this.
2189:    See, e.g., KSPCreate().

2191:    Level: developer

2193:    Concepts: matrices^triangular solves

2195: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2196: @*/
2197: int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2198: {
2199:   PetscScalar one = 1.0;
2200:   Vec    tmp;
2201:   int    ierr;

2206:   MatPreallocated(mat);
2213:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2214:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2215:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2216:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2217:   if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N);
2218:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);
2219:   if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);

2221:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
2222:   if (mat->ops->solveadd)  {
2223:     (*mat->ops->solveadd)(mat,b,y,x);
2224:   } else {
2225:     /* do the solve then the add manually */
2226:     if (x != y) {
2227:       MatSolve(mat,b,x);
2228:       VecAXPY(&one,y,x);
2229:     } else {
2230:       VecDuplicate(x,&tmp);
2231:       PetscLogObjectParent(mat,tmp);
2232:       VecCopy(x,tmp);
2233:       MatSolve(mat,b,x);
2234:       VecAXPY(&one,tmp,x);
2235:       VecDestroy(tmp);
2236:     }
2237:   }
2238:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
2239:   PetscObjectIncreaseState((PetscObject)x);
2240:   return(0);
2241: }

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

2248:    Collective on Mat and Vec

2250:    Input Parameters:
2251: +  mat - the factored matrix
2252: -  b - the right-hand-side vector

2254:    Output Parameter:
2255: .  x - the result vector

2257:    Notes:
2258:    The vectors b and x cannot be the same.  I.e., one cannot
2259:    call MatSolveTranspose(A,x,x).

2261:    Most users should employ the simplified KSP interface for linear solvers
2262:    instead of working directly with matrix algebra routines such as this.
2263:    See, e.g., KSPCreate().

2265:    Level: developer

2267:    Concepts: matrices^triangular solves

2269: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2270: @*/
2271: int MatSolveTranspose(Mat mat,Vec b,Vec x)
2272: {

2278:   MatPreallocated(mat);
2283:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2284:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2285:   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name);
2286:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2287:   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);

2289:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
2290:   (*mat->ops->solvetranspose)(mat,b,x);
2291:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
2292:   PetscObjectIncreaseState((PetscObject)x);
2293:   return(0);
2294: }

2298: /*@
2299:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
2300:                       factored matrix. 

2302:    Collective on Mat and Vec

2304:    Input Parameters:
2305: +  mat - the factored matrix
2306: .  b - the right-hand-side vector
2307: -  y - the vector to be added to 

2309:    Output Parameter:
2310: .  x - the result vector

2312:    Notes:
2313:    The vectors b and x cannot be the same.  I.e., one cannot
2314:    call MatSolveTransposeAdd(A,x,y,x).

2316:    Most users should employ the simplified KSP interface for linear solvers
2317:    instead of working directly with matrix algebra routines such as this.
2318:    See, e.g., KSPCreate().

2320:    Level: developer

2322:    Concepts: matrices^triangular solves

2324: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2325: @*/
2326: int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
2327: {
2328:   PetscScalar one = 1.0;
2329:   int         ierr;
2330:   Vec         tmp;

2335:   MatPreallocated(mat);
2342:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2343:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2344:   if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N);
2345:   if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N);
2346:   if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N);
2347:   if (x->n != y->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n);

2349:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
2350:   if (mat->ops->solvetransposeadd) {
2351:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
2352:   } else {
2353:     /* do the solve then the add manually */
2354:     if (x != y) {
2355:       MatSolveTranspose(mat,b,x);
2356:       VecAXPY(&one,y,x);
2357:     } else {
2358:       VecDuplicate(x,&tmp);
2359:       PetscLogObjectParent(mat,tmp);
2360:       VecCopy(x,tmp);
2361:       MatSolveTranspose(mat,b,x);
2362:       VecAXPY(&one,tmp,x);
2363:       VecDestroy(tmp);
2364:     }
2365:   }
2366:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
2367:   PetscObjectIncreaseState((PetscObject)x);
2368:   return(0);
2369: }
2370: /* ----------------------------------------------------------------*/

2374: /*@
2375:    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.

2377:    Collective on Mat and Vec

2379:    Input Parameters:
2380: +  mat - the matrix
2381: .  b - the right hand side
2382: .  omega - the relaxation factor
2383: .  flag - flag indicating the type of SOR (see below)
2384: .  shift -  diagonal shift
2385: -  its - the number of iterations
2386: -  lits - the number of local iterations 

2388:    Output Parameters:
2389: .  x - the solution (can contain an initial guess)

2391:    SOR Flags:
2392: .     SOR_FORWARD_SWEEP - forward SOR
2393: .     SOR_BACKWARD_SWEEP - backward SOR
2394: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
2395: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
2396: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
2397: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
2398: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
2399:          upper/lower triangular part of matrix to
2400:          vector (with omega)
2401: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

2403:    Notes:
2404:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
2405:    SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings
2406:    on each processor. 

2408:    Application programmers will not generally use MatRelax() directly,
2409:    but instead will employ the KSP/PC interface.

2411:    Notes for Advanced Users:
2412:    The flags are implemented as bitwise inclusive or operations.
2413:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
2414:    to specify a zero initial guess for SSOR.

2416:    Most users should employ the simplified KSP interface for linear solvers
2417:    instead of working directly with matrix algebra routines such as this.
2418:    See, e.g., KSPCreate().

2420:    See also, MatPBRelax(). This routine will automatically call the point block
2421:    version if the point version is not available.

2423:    Level: developer

2425:    Concepts: matrices^relaxation
2426:    Concepts: matrices^SOR
2427:    Concepts: matrices^Gauss-Seidel

2429: @*/
2430: int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2431: {

2437:   MatPreallocated(mat);
2442:   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2443:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2444:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2445:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2446:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2447:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);

2449:   PetscLogEventBegin(MAT_Relax,mat,b,x,0);
2450:   if (mat->ops->relax) {
2451:     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);
2452:   } else {
2453:     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
2454:   }
2455:   PetscLogEventEnd(MAT_Relax,mat,b,x,0);
2456:   PetscObjectIncreaseState((PetscObject)x);
2457:   return(0);
2458: }

2462: /*@
2463:    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.

2465:    Collective on Mat and Vec

2467:    See MatRelax() for usage

2469:    For multi-component PDEs where the Jacobian is stored in a point block format
2470:    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at 
2471:    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
2472:    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.

2474:    Level: developer

2476: @*/
2477: int MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x)
2478: {

2484:   MatPreallocated(mat);
2489:   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2490:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2491:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2492:   if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N);
2493:   if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N);
2494:   if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n);

2496:   PetscLogEventBegin(MAT_Relax,mat,b,x,0);
2497:   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
2498:   PetscLogEventEnd(MAT_Relax,mat,b,x,0);
2499:   PetscObjectIncreaseState((PetscObject)x);
2500:   return(0);
2501: }

2505: /*
2506:       Default matrix copy routine.
2507: */
2508: int MatCopy_Basic(Mat A,Mat B,MatStructure str)
2509: {
2510:   int         ierr,i,rstart,rend,nz,*cwork;
2511:   PetscScalar *vwork;

2514:   MatZeroEntries(B);
2515:   MatGetOwnershipRange(A,&rstart,&rend);
2516:   for (i=rstart; i<rend; i++) {
2517:     MatGetRow(A,i,&nz,&cwork,&vwork);
2518:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
2519:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
2520:   }
2521:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
2522:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
2523:   PetscObjectIncreaseState((PetscObject)B);
2524:   return(0);
2525: }

2529: /*@C  
2530:    MatCopy - Copys a matrix to another matrix.

2532:    Collective on Mat

2534:    Input Parameters:
2535: +  A - the matrix
2536: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

2538:    Output Parameter:
2539: .  B - where the copy is put

2541:    Notes:
2542:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
2543:    same nonzero pattern or the routine will crash.

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

2549:    Level: intermediate
2550:    
2551:    Concepts: matrices^copying

2553: .seealso: MatConvert(), MatDuplicate()

2555: @*/
2556: int MatCopy(Mat A,Mat B,MatStructure str)
2557: {

2564:   MatPreallocated(A);
2566:   MatPreallocated(B);
2568:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2569:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2570:   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,
2571:                                              A->N,B->N);

2573:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
2574:   if (A->ops->copy) {
2575:     (*A->ops->copy)(A,B,str);
2576:   } else { /* generic conversion */
2577:     MatCopy_Basic(A,B,str);
2578:   }
2579:   if (A->mapping) {
2580:     if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
2581:     MatSetLocalToGlobalMapping(B,A->mapping);
2582:   }
2583:   if (A->bmapping) {
2584:     if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
2585:     MatSetLocalToGlobalMappingBlock(B,A->mapping);
2586:   }
2587:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
2588:   PetscObjectIncreaseState((PetscObject)B);
2589:   return(0);
2590: }

2592:  #include petscsys.h
2593: PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE;
2594: PetscFList MatConvertList              = 0;

2598: /*@C
2599:     MatConvertRegister - Allows one to register a routine that converts a sparse matrix
2600:         from one format to another.

2602:   Not Collective

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

2608:   Level: developer

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

2612: @*/
2613: int MatConvertRegister(const char sname[],const char path[],const char name[],int (*function)(Mat,MatType,Mat*))
2614: {
2615:   int  ierr;
2616:   char fullname[PETSC_MAX_PATH_LEN];

2619:   PetscFListConcat(path,name,fullname);
2620:   PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);
2621:   return(0);
2622: }

2626: /*@C  
2627:    MatConvert - Converts a matrix to another matrix, either of the same
2628:    or different type.

2630:    Collective on Mat

2632:    Input Parameters:
2633: +  mat - the matrix
2634: -  newtype - new matrix type.  Use MATSAME to create a new matrix of the
2635:    same type as the original matrix.

2637:    Output Parameter:
2638: .  M - pointer to place new matrix

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

2645:    Level: intermediate

2647:    Concepts: matrices^converting between storage formats

2649: .seealso: MatCopy(), MatDuplicate()
2650: @*/
2651: int MatConvert(Mat mat,const MatType newtype,Mat *M)
2652: {
2653:   int        ierr;
2654:   PetscTruth sametype,issame,flg;
2655:   char       convname[256],mtype[256];

2660:   MatPreallocated(mat);
2662:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2663:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

2665:   PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);
2666:   if (flg) {
2667:     newtype = mtype;
2668:   }
2669:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
2670: 
2671:   PetscTypeCompare((PetscObject)mat,newtype,&sametype);
2672:   PetscStrcmp(newtype,"same",&issame);
2673:   if ((sametype || issame) && mat->ops->duplicate) {
2674:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
2675:   } else {
2676:     int (*conv)(Mat,const MatType,Mat*)=PETSC_NULL;
2677:     /* 
2678:        Order of precedence:
2679:        1) See if a specialized converter is known to the current matrix.
2680:        2) See if a specialized converter is known to the desired matrix class.
2681:        3) See if a good general converter is registered for the desired class
2682:           (as of 6/27/03 only MATMPIADJ falls into this category).
2683:        4) See if a good general converter is known for the current matrix.
2684:        5) Use a really basic converter.
2685:     */
2686:     PetscStrcpy(convname,"MatConvert_");
2687:     PetscStrcat(convname,mat->type_name);
2688:     PetscStrcat(convname,"_");
2689:     PetscStrcat(convname,newtype);
2690:     PetscStrcat(convname,"_C");
2691:     PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
2692:     if (!conv) {
2693:       Mat B;
2694:       MatCreate(mat->comm,0,0,0,0,&B);
2695:       MatSetType(B,newtype);
2696:       PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
2697:       MatDestroy(B);
2698:       if (!conv) {
2699:         if (!MatConvertRegisterAllCalled) {
2700:           MatConvertRegisterAll(PETSC_NULL);
2701:         }
2702:         PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);
2703:         if (!conv) {
2704:           if (mat->ops->convert) {
2705:             conv = mat->ops->convert;
2706:           } else {
2707:             conv = MatConvert_Basic;
2708:           }
2709:         }
2710:       }
2711:     }
2712:     (*conv)(mat,newtype,M);
2713:   }
2714:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
2715:   PetscObjectIncreaseState((PetscObject)*M);
2716:   return(0);
2717: }


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

2725:    Collective on Mat

2727:    Input Parameters:
2728: +  mat - the matrix
2729: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
2730:         values as well or not

2732:    Output Parameter:
2733: .  M - pointer to place new matrix

2735:    Level: intermediate

2737:    Concepts: matrices^duplicating

2739: .seealso: MatCopy(), MatConvert()
2740: @*/
2741: int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
2742: {

2748:   MatPreallocated(mat);
2750:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2751:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

2753:   *M  = 0;
2754:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
2755:   if (!mat->ops->duplicate) {
2756:     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
2757:   }
2758:   (*mat->ops->duplicate)(mat,op,M);
2759:   if (mat->mapping) {
2760:     MatSetLocalToGlobalMapping(*M,mat->mapping);
2761:   }
2762:   if (mat->bmapping) {
2763:     MatSetLocalToGlobalMappingBlock(*M,mat->mapping);
2764:   }
2765:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
2766:   PetscObjectIncreaseState((PetscObject)*M);
2767:   return(0);
2768: }

2772: /*@ 
2773:    MatGetDiagonal - Gets the diagonal of a matrix.

2775:    Collective on Mat and Vec

2777:    Input Parameters:
2778: +  mat - the matrix
2779: -  v - the vector for storing the diagonal

2781:    Output Parameter:
2782: .  v - the diagonal of the matrix

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

2790:    Level: intermediate

2792:    Concepts: matrices^accessing diagonals

2794: .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax()
2795: @*/
2796: int MatGetDiagonal(Mat mat,Vec v)
2797: {

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

2808:   (*mat->ops->getdiagonal)(mat,v);
2809:   PetscObjectIncreaseState((PetscObject)v);
2810:   return(0);
2811: }

2815: /*@ 
2816:    MatGetRowMax - Gets the maximum value (in absolute value) of each
2817:         row of the matrix

2819:    Collective on Mat and Vec

2821:    Input Parameters:
2822: .  mat - the matrix

2824:    Output Parameter:
2825: .  v - the vector for storing the maximums

2827:    Level: intermediate

2829:    Concepts: matrices^getting row maximums

2831: .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix()
2832: @*/
2833: int MatGetRowMax(Mat mat,Vec v)
2834: {

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

2845:   (*mat->ops->getrowmax)(mat,v);
2846:   PetscObjectIncreaseState((PetscObject)v);
2847:   return(0);
2848: }

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

2855:    Collective on Mat

2857:    Input Parameter:
2858: .  mat - the matrix to transpose

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

2863:    Level: intermediate

2865:    Concepts: matrices^transposing

2867: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
2868: @*/
2869: int MatTranspose(Mat mat,Mat *B)
2870: {

2876:   MatPreallocated(mat);
2877:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2878:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2879:   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

2881:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
2882:   (*mat->ops->transpose)(mat,B);
2883:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
2884:   if (B) {PetscObjectIncreaseState((PetscObject)*B); }
2885:   return(0);
2886: }

2890: /*@C
2891:    MatIsTranspose - Test whether a matrix is another one's transpose, 
2892:         or its own, in which case it tests symmetry.

2894:    Collective on Mat

2896:    Input Parameter:
2897: +  A - the matrix to test
2898: -  B - the matrix to test against, this can equal the first parameter

2900:    Output Parameters:
2901: .  flg - the result

2903:    Notes:
2904:    Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
2905:    has a running time of the order of the number of nonzeros; the parallel
2906:    test involves parallel copies of the block-offdiagonal parts of the matrix.

2908:    Level: intermediate

2910:    Concepts: matrices^transposing, matrix^symmetry

2912: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
2913: @*/
2914: int MatIsTranspose(Mat A,Mat B,PetscTruth *flg)
2915: {
2916:   int ierr,(*f)(Mat,Mat,PetscTruth*),(*g)(Mat,Mat,PetscTruth*);

2922:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
2923:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
2924:   if (f && g) {
2925:     if (f==g) {
2926:       (*f)(A,B,flg);
2927:     } else {
2928:       SETERRQ(1,"Matrices do not have the same comparator for symmetry test");
2929:     }
2930:   }
2931:   return(0);
2932: }

2936: /*@C
2937:    MatPermute - Creates a new matrix with rows and columns permuted from the 
2938:    original.

2940:    Collective on Mat

2942:    Input Parameters:
2943: +  mat - the matrix to permute
2944: .  row - row permutation, each processor supplies only the permutation for its rows
2945: -  col - column permutation, each processor needs the entire column permutation, that is
2946:          this is the same size as the total number of columns in the matrix

2948:    Output Parameters:
2949: .  B - the permuted matrix

2951:    Level: advanced

2953:    Concepts: matrices^permuting

2955: .seealso: MatGetOrdering()
2956: @*/
2957: int MatPermute(Mat mat,IS row,IS col,Mat *B)
2958: {

2964:   MatPreallocated(mat);
2968:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2969:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2970:   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
2971:   (*mat->ops->permute)(mat,row,col,B);
2972:   PetscObjectIncreaseState((PetscObject)*B);
2973:   return(0);
2974: }

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

2982:   Collective on Mat

2984:   Input Parameters:
2985: + A    - The matrix to permute
2986: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
2987: . frac - The half-bandwidth as a fraction of the total size, or 0.0
2988: . tol  - The drop tolerance
2989: . rowp - The row permutation
2990: - colp - The column permutation

2992:   Output Parameter:
2993: . B    - The permuted, sparsified matrix

2995:   Level: advanced

2997:   Note:
2998:   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
2999:   restrict the half-bandwidth of the resulting matrix to 5% of the
3000:   total matrix size.

3002: .keywords: matrix, permute, sparsify

3004: .seealso: MatGetOrdering(), MatPermute()
3005: @*/
3006: int MatPermuteSparsify(Mat A, int band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
3007: {
3008:   IS           irowp, icolp;
3009:   int         *rows, *cols;
3010:   int          M, N, locRowStart, locRowEnd;
3011:   int          nz, newNz;
3012:   int         *cwork, *cnew;
3013:   PetscScalar *vwork, *vnew;
3014:   int          bw, size;
3015:   int          row, locRow, newRow, col, newCol;
3016:   int          ierr;

3023:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3024:   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3025:   if (!A->ops->permutesparsify) {
3026:     MatGetSize(A, &M, &N);
3027:     MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
3028:     ISGetSize(rowp, &size);
3029:     if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M);
3030:     ISGetSize(colp, &size);
3031:     if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N);
3032:     ISInvertPermutation(rowp, 0, &irowp);
3033:     ISGetIndices(irowp, &rows);
3034:     ISInvertPermutation(colp, 0, &icolp);
3035:     ISGetIndices(icolp, &cols);
3036:     PetscMalloc(N * sizeof(int),         &cnew);
3037:     PetscMalloc(N * sizeof(PetscScalar), &vnew);

3039:     /* Setup bandwidth to include */
3040:     if (band == PETSC_DECIDE) {
3041:       if (frac <= 0.0)
3042:         bw = (int) (M * 0.05);
3043:       else
3044:         bw = (int) (M * frac);
3045:     } else {
3046:       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
3047:       bw = band;
3048:     }

3050:     /* Put values into new matrix */
3051:     MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
3052:     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
3053:       MatGetRow(A, row, &nz, &cwork, &vwork);
3054:       newRow   = rows[locRow]+locRowStart;
3055:       for(col = 0, newNz = 0; col < nz; col++) {
3056:         newCol = cols[cwork[col]];
3057:         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
3058:           cnew[newNz] = newCol;
3059:           vnew[newNz] = vwork[col];
3060:           newNz++;
3061:         }
3062:       }
3063:       MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
3064:       MatRestoreRow(A, row, &nz, &cwork, &vwork);
3065:     }
3066:     PetscFree(cnew);
3067:     PetscFree(vnew);
3068:     MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
3069:     MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
3070:     ISRestoreIndices(irowp, &rows);
3071:     ISRestoreIndices(icolp, &cols);
3072:     ISDestroy(irowp);
3073:     ISDestroy(icolp);
3074:   } else {
3075:     (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
3076:   }
3077:   PetscObjectIncreaseState((PetscObject)*B);
3078:   return(0);
3079: }

3083: /*@
3084:    MatEqual - Compares two matrices.

3086:    Collective on Mat

3088:    Input Parameters:
3089: +  A - the first matrix
3090: -  B - the second matrix

3092:    Output Parameter:
3093: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

3095:    Level: intermediate

3097:    Concepts: matrices^equality between
3098: @*/
3099: int MatEqual(Mat A,Mat B,PetscTruth *flg)
3100: {

3107:   MatPreallocated(A);
3109:   MatPreallocated(B);
3112:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3113:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3114:   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);
3115:   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name);
3116:   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",B->type_name);
3117:   if (A->ops->equal != B->ops->equal) SETERRQ2(PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",A->type_name,B->type_name);
3118:   (*A->ops->equal)(A,B,flg);
3119:   return(0);
3120: }

3124: /*@
3125:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
3126:    matrices that are stored as vectors.  Either of the two scaling
3127:    matrices can be PETSC_NULL.

3129:    Collective on Mat

3131:    Input Parameters:
3132: +  mat - the matrix to be scaled
3133: .  l - the left scaling vector (or PETSC_NULL)
3134: -  r - the right scaling vector (or PETSC_NULL)

3136:    Notes:
3137:    MatDiagonalScale() computes A = LAR, where
3138:    L = a diagonal matrix, R = a diagonal matrix

3140:    Level: intermediate

3142:    Concepts: matrices^diagonal scaling
3143:    Concepts: diagonal scaling of matrices

3145: .seealso: MatScale()
3146: @*/
3147: int MatDiagonalScale(Mat mat,Vec l,Vec r)
3148: {

3154:   MatPreallocated(mat);
3155:   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3158:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3159:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

3161:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
3162:   (*mat->ops->diagonalscale)(mat,l,r);
3163:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
3164:   PetscObjectIncreaseState((PetscObject)mat);
3165:   return(0);
3166: }

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

3173:     Collective on Mat

3175:     Input Parameters:
3176: +   mat - the matrix to be scaled
3177: -   a  - the scaling value

3179:     Output Parameter:
3180: .   mat - the scaled matrix

3182:     Level: intermediate

3184:     Concepts: matrices^scaling all entries

3186: .seealso: MatDiagonalScale()
3187: @*/
3188: int MatScale(const PetscScalar *a,Mat mat)
3189: {

3196:   MatPreallocated(mat);
3197:   if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3198:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3199:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

3201:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
3202:   (*mat->ops->scale)(a,mat);
3203:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
3204:   PetscObjectIncreaseState((PetscObject)mat);
3205:   return(0);
3206: }

3210: /*@ 
3211:    MatNorm - Calculates various norms of a matrix.

3213:    Collective on Mat

3215:    Input Parameters:
3216: +  mat - the matrix
3217: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

3219:    Output Parameters:
3220: .  nrm - the resulting norm 

3222:    Level: intermediate

3224:    Concepts: matrices^norm
3225:    Concepts: norm^of matrix
3226: @*/
3227: int MatNorm(Mat mat,NormType type,PetscReal *nrm)
3228: {

3234:   MatPreallocated(mat);

3237:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3238:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3239:   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
3240:   (*mat->ops->norm)(mat,type,nrm);
3241:   return(0);
3242: }

3244: /* 
3245:      This variable is used to prevent counting of MatAssemblyBegin() that
3246:    are called from within a MatAssemblyEnd().
3247: */
3248: static int MatAssemblyEnd_InUse = 0;
3251: /*@
3252:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
3253:    be called after completing all calls to MatSetValues().

3255:    Collective on Mat

3257:    Input Parameters:
3258: +  mat - the matrix 
3259: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
3260:  
3261:    Notes: 
3262:    MatSetValues() generally caches the values.  The matrix is ready to
3263:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3264:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3265:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3266:    using the matrix.

3268:    Level: beginner

3270:    Concepts: matrices^assembling

3272: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
3273: @*/
3274: int MatAssemblyBegin(Mat mat,MatAssemblyType type)
3275: {

3281:   MatPreallocated(mat);
3282:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
3283:   if (mat->assembled) {
3284:     mat->was_assembled = PETSC_TRUE;
3285:     mat->assembled     = PETSC_FALSE;
3286:   }
3287:   if (!MatAssemblyEnd_InUse) {
3288:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
3289:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
3290:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
3291:   } else {
3292:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
3293:   }
3294:   return(0);
3295: }

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

3303:    Collective on Mat

3305:    Input Parameter:
3306: .  mat - the matrix 

3308:    Output Parameter:
3309: .  assembled - PETSC_TRUE or PETSC_FALSE

3311:    Level: advanced

3313:    Concepts: matrices^assembled?

3315: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
3316: @*/
3317: int MatAssembled(Mat mat,PetscTruth *assembled)
3318: {
3322:   MatPreallocated(mat);
3324:   *assembled = mat->assembled;
3325:   return(0);
3326: }

3330: /*
3331:     Processes command line options to determine if/how a matrix
3332:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
3333: */
3334: int MatView_Private(Mat mat)
3335: {
3336:   int               ierr;
3337:   PetscTruth        flg;
3338:   static PetscTruth incall = PETSC_FALSE;

3341:   if (incall) return(0);
3342:   incall = PETSC_TRUE;
3343:   PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");
3344:     PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);
3345:     if (flg) {
3346:       PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);
3347:       MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
3348:       PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));
3349:     }
3350:     PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);
3351:     if (flg) {
3352:       PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);
3353:       MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
3354:       PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));
3355:     }
3356:     PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);
3357:     if (flg) {
3358:       MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
3359:     }
3360:     PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);
3361:     if (flg) {
3362:       PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);
3363:       MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));
3364:       PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));
3365:     }
3366:     PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);
3367:     if (flg) {
3368:       MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));
3369:       PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));
3370:     }
3371:     PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);
3372:     if (flg) {
3373:       MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));
3374:       PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));
3375:     }
3376:   PetscOptionsEnd();
3377:   /* cannot have inside PetscOptionsBegin() because uses PetscOptionsBegin() */
3378:   PetscOptionsHasName(mat->prefix,"-mat_view_draw",&flg);
3379:   if (flg) {
3380:     PetscOptionsHasName(mat->prefix,"-mat_view_contour",&flg);
3381:     if (flg) {
3382:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);
3383:     }
3384:     MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));
3385:     PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));
3386:     if (flg) {
3387:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));
3388:     }
3389:   }
3390:   incall = PETSC_FALSE;
3391:   return(0);
3392: }

3396: /*@
3397:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
3398:    be called after MatAssemblyBegin().

3400:    Collective on Mat

3402:    Input Parameters:
3403: +  mat - the matrix 
3404: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

3406:    Options Database Keys:
3407: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
3408: .  -mat_view_info_detailed - Prints more detailed info
3409: .  -mat_view - Prints matrix in ASCII format
3410: .  -mat_view_matlab - Prints matrix in Matlab format
3411: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
3412: .  -display <name> - Sets display name (default is host)
3413: .  -draw_pause <sec> - Sets number of seconds to pause after display
3414: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
3415: .  -viewer_socket_machine <machine>
3416: .  -viewer_socket_port <port>
3417: .  -mat_view_binary - save matrix to file in binary format
3418: -  -viewer_binary_filename <name>

3420:    Notes: 
3421:    MatSetValues() generally caches the values.  The matrix is ready to
3422:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
3423:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
3424:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
3425:    using the matrix.

3427:    Level: beginner

3429: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
3430: @*/
3431: int MatAssemblyEnd(Mat mat,MatAssemblyType type)
3432: {
3433:   int        ierr;
3434:   static int inassm = 0;
3435:   PetscTruth flg;

3440:   MatPreallocated(mat);

3442:   inassm++;
3443:   MatAssemblyEnd_InUse++;
3444:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
3445:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
3446:     if (mat->ops->assemblyend) {
3447:       (*mat->ops->assemblyend)(mat,type);
3448:     }
3449:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
3450:   } else {
3451:     if (mat->ops->assemblyend) {
3452:       (*mat->ops->assemblyend)(mat,type);
3453:     }
3454:   }

3456:   /* Flush assembly is not a true assembly */
3457:   if (type != MAT_FLUSH_ASSEMBLY) {
3458:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
3459:   }
3460:   mat->insertmode = NOT_SET_VALUES;
3461:   MatAssemblyEnd_InUse--;
3462:   PetscObjectIncreaseState((PetscObject)mat);
3463:   if (!mat->symmetric_eternal) {
3464:     mat->symmetric_set              = PETSC_FALSE;
3465:     mat->hermitian_set              = PETSC_FALSE;
3466:     mat->structurally_symmetric_set = PETSC_FALSE;
3467:   }
3468:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
3469:     MatView_Private(mat);
3470:   }
3471:   inassm--;
3472:   PetscOptionsHasName(mat->prefix,"-help",&flg);
3473:   if (flg) {
3474:     MatPrintHelp(mat);
3475:   }
3476:   return(0);
3477: }


3482: /*@
3483:    MatCompress - Tries to store the matrix in as little space as 
3484:    possible.  May fail if memory is already fully used, since it
3485:    tries to allocate new space.

3487:    Collective on Mat

3489:    Input Parameters:
3490: .  mat - the matrix 

3492:    Level: advanced

3494: @*/
3495: int MatCompress(Mat mat)
3496: {

3502:   MatPreallocated(mat);
3503:   if (mat->ops->compress) {(*mat->ops->compress)(mat);}
3504:   return(0);
3505: }

3509: /*@
3510:    MatSetOption - Sets a parameter option for a matrix. Some options
3511:    may be specific to certain storage formats.  Some options
3512:    determine how values will be inserted (or added). Sorted, 
3513:    row-oriented input will generally assemble the fastest. The default
3514:    is row-oriented, nonsorted input. 

3516:    Collective on Mat

3518:    Input Parameters:
3519: +  mat - the matrix 
3520: -  option - the option, one of those listed below (and possibly others),
3521:              e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR

3523:    Options Describing Matrix Structure:
3524: +    MAT_SYMMETRIC - symmetric in terms of both structure and value
3525: .    MAT_HERMITIAN - transpose is the complex conjugation
3526: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
3527: .    MAT_NOT_SYMMETRIC - not symmetric in value
3528: .    MAT_NOT_HERMITIAN - transpose is not the complex conjugation
3529: .    MAT_NOT_STRUCTURALLY_SYMMETRIC - not symmetric nonzero structure
3530: .    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
3531:                             you set to be kept with all future use of the matrix
3532:                             including after MatAssemblyBegin/End() which could
3533:                             potentially change the symmetry structure, i.e. you 
3534:                             KNOW the matrix will ALWAYS have the property you set.
3535: -    MAT_NOT_SYMMETRY_ETERNAL - if MatAssemblyBegin/End() is called then the 
3536:                                 flags you set will be dropped (in case potentially
3537:                                 the symmetry etc was lost).

3539:    Options For Use with MatSetValues():
3540:    Insert a logically dense subblock, which can be
3541: +    MAT_ROW_ORIENTED - row-oriented (default)
3542: .    MAT_COLUMN_ORIENTED - column-oriented
3543: .    MAT_ROWS_SORTED - sorted by row
3544: .    MAT_ROWS_UNSORTED - not sorted by row (default)
3545: .    MAT_COLUMNS_SORTED - sorted by column
3546: -    MAT_COLUMNS_UNSORTED - not sorted by column (default)

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

3552:    When (re)assembling a matrix, we can restrict the input for
3553:    efficiency/debugging purposes.  These options include
3554: +    MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be
3555:         allowed if they generate a new nonzero
3556: .    MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed
3557: .    MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if
3558:          they generate a nonzero in a new diagonal (for block diagonal format only)
3559: .    MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
3560: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
3561: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
3562: -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly

3564:    Notes:
3565:    Some options are relevant only for particular matrix types and
3566:    are thus ignored by others.  Other options are not supported by
3567:    certain matrix types and will generate an error message if set.

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

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

3580:    MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion 
3581:    that would generate a new entry in the nonzero structure instead produces 
3582:    an error. (Currently supported for AIJ and BAIJ formats only.)
3583:    This is a useful flag when using SAME_NONZERO_PATTERN in calling
3584:    KSPSetOperators() to ensure that the nonzero pattern truely does 
3585:    remain unchanged. Set after the first MatAssemblyEnd()

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

3592:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
3593:    other processors should be dropped, rather than stashed.
3594:    This is useful if you know that the "owning" processor is also 
3595:    always generating the correct matrix entries, so that PETSc need
3596:    not transfer duplicate entries generated on another processor.
3597:    
3598:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
3599:    searches during matrix assembly. When this flag is set, the hash table
3600:    is created during the first Matrix Assembly. This hash table is
3601:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
3602:    to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag 
3603:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
3604:    supported by MATMPIBAIJ format only.

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

3609:    MAT_IGNORE_ZERO_ENTRIES - for AIJ matrices this will stop zero values from creating
3610:    a zero location in the matrix

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

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

3618:    Level: intermediate

3620:    Concepts: matrices^setting options

3622: @*/
3623: int MatSetOption(Mat mat,MatOption op)
3624: {

3630:   MatPreallocated(mat);
3631:   switch (op) {
3632:   case MAT_SYMMETRIC:
3633:     mat->symmetric                  = PETSC_TRUE;
3634:     mat->structurally_symmetric     = PETSC_TRUE;
3635:     mat->symmetric_set              = PETSC_TRUE;
3636:     mat->structurally_symmetric_set = PETSC_TRUE;
3637:     break;
3638:   case MAT_HERMITIAN:
3639:     mat->hermitian                  = PETSC_TRUE;
3640:     mat->structurally_symmetric     = PETSC_TRUE;
3641:     mat->hermitian_set              = PETSC_TRUE;
3642:     mat->structurally_symmetric_set = PETSC_TRUE;
3643:     break;
3644:   case MAT_STRUCTURALLY_SYMMETRIC:
3645:     mat->structurally_symmetric     = PETSC_TRUE;
3646:     mat->structurally_symmetric_set = PETSC_TRUE;
3647:     break;
3648:   case MAT_NOT_SYMMETRIC:
3649:     mat->symmetric                  = PETSC_FALSE;
3650:     mat->symmetric_set              = PETSC_TRUE;
3651:     break;
3652:   case MAT_NOT_HERMITIAN:
3653:     mat->hermitian                  = PETSC_FALSE;
3654:     mat->hermitian_set              = PETSC_TRUE;
3655:     break;
3656:   case MAT_NOT_STRUCTURALLY_SYMMETRIC:
3657:     mat->structurally_symmetric     = PETSC_FALSE;
3658:     mat->structurally_symmetric_set = PETSC_TRUE;
3659:     break;
3660:   case MAT_SYMMETRY_ETERNAL:
3661:     mat->symmetric_eternal          = PETSC_TRUE;
3662:   case MAT_NOT_SYMMETRY_ETERNAL:
3663:     mat->symmetric_eternal          = PETSC_FALSE;
3664:   default:
3665:     break;
3666:   }
3667:   if (mat->ops->setoption) {
3668:     (*mat->ops->setoption)(mat,op);
3669:   }
3670:   return(0);
3671: }

3675: /*@
3676:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
3677:    this routine retains the old nonzero structure.

3679:    Collective on Mat

3681:    Input Parameters:
3682: .  mat - the matrix 

3684:    Level: intermediate

3686:    Concepts: matrices^zeroing

3688: .seealso: MatZeroRows()
3689: @*/
3690: int MatZeroEntries(Mat mat)
3691: {

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

3701:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
3702:   (*mat->ops->zeroentries)(mat);
3703:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
3704:   PetscObjectIncreaseState((PetscObject)mat);
3705:   return(0);
3706: }

3710: /*@C
3711:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
3712:    of a set of rows of a matrix.

3714:    Collective on Mat

3716:    Input Parameters:
3717: +  mat - the matrix
3718: .  is - index set of rows to remove
3719: -  diag - pointer to value put in all diagonals of eliminated rows.
3720:           Note that diag is not a pointer to an array, but merely a
3721:           pointer to a single value.

3723:    Notes:
3724:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
3725:    but does not release memory.  For the dense and block diagonal
3726:    formats this does not alter the nonzero structure.

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

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

3737:    For the parallel case, all processes that share the matrix (i.e.,
3738:    those in the communicator used for matrix creation) MUST call this
3739:    routine, regardless of whether any rows being zeroed are owned by
3740:    them.
3741:   
3742:    Level: intermediate

3744:    Concepts: matrices^zeroing rows

3746: .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
3747: @*/
3748: int MatZeroRows(Mat mat,IS is,const PetscScalar *diag)
3749: {

3755:   MatPreallocated(mat);
3758:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3759:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3760:   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);

3762:   (*mat->ops->zerorows)(mat,is,diag);
3763:   MatView_Private(mat);
3764:   PetscObjectIncreaseState((PetscObject)mat);
3765:   return(0);
3766: }

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

3774:    Collective on Mat

3776:    Input Parameters:
3777: +  mat - the matrix
3778: .  is - index set of rows to remove
3779: -  diag - pointer to value put in all diagonals of eliminated rows.
3780:           Note that diag is not a pointer to an array, but merely a
3781:           pointer to a single value.

3783:    Notes:
3784:    Before calling MatZeroRowsLocal(), the user must first set the
3785:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

3787:    For the AIJ matrix formats this removes the old nonzero structure,
3788:    but does not release memory.  For the dense and block diagonal
3789:    formats this does not alter the nonzero structure.

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

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

3800:    Level: intermediate

3802:    Concepts: matrices^zeroing

3804: .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
3805: @*/
3806: int MatZeroRowsLocal(Mat mat,IS is,const PetscScalar *diag)
3807: {
3809:   IS  newis;

3814:   MatPreallocated(mat);
3817:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3818:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

3820:   if (mat->ops->zerorowslocal) {
3821:     (*mat->ops->zerorowslocal)(mat,is,diag);
3822:   } else {
3823:     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
3824:     ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
3825:     (*mat->ops->zerorows)(mat,newis,diag);
3826:     ISDestroy(newis);
3827:   }
3828:   PetscObjectIncreaseState((PetscObject)mat);
3829:   return(0);
3830: }

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

3837:    Not Collective

3839:    Input Parameter:
3840: .  mat - the matrix

3842:    Output Parameters:
3843: +  m - the number of global rows
3844: -  n - the number of global columns

3846:    Level: beginner

3848:    Concepts: matrices^size

3850: .seealso: MatGetLocalSize()
3851: @*/
3852: int MatGetSize(Mat mat,int *m,int* n)
3853: {
3856:   if (m) *m = mat->M;
3857:   if (n) *n = mat->N;
3858:   return(0);
3859: }

3863: /*@
3864:    MatGetLocalSize - Returns the number of rows and columns in a matrix
3865:    stored locally.  This information may be implementation dependent, so
3866:    use with care.

3868:    Not Collective

3870:    Input Parameters:
3871: .  mat - the matrix

3873:    Output Parameters:
3874: +  m - the number of local rows
3875: -  n - the number of local columns

3877:    Level: beginner

3879:    Concepts: matrices^local size

3881: .seealso: MatGetSize()
3882: @*/
3883: int MatGetLocalSize(Mat mat,int *m,int* n)
3884: {
3889:   if (m) *m = mat->m;
3890:   if (n) *n = mat->n;
3891:   return(0);
3892: }

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

3902:    Not Collective

3904:    Input Parameters:
3905: .  mat - the matrix

3907:    Output Parameters:
3908: +  m - the global index of the first local row
3909: -  n - one more than the global index of the last local row

3911:    Level: beginner

3913:    Concepts: matrices^row ownership
3914: @*/
3915: int MatGetOwnershipRange(Mat mat,int *m,int* n)
3916: {

3922:   MatPreallocated(mat);
3925:   PetscMapGetLocalRange(mat->rmap,m,n);
3926:   return(0);
3927: }

3931: /*@  
3932:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
3933:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
3934:    to complete the factorization.

3936:    Collective on Mat

3938:    Input Parameters:
3939: +  mat - the matrix
3940: .  row - row permutation
3941: .  column - column permutation
3942: -  info - structure containing 
3943: $      levels - number of levels of fill.
3944: $      expected fill - as ratio of original fill.
3945: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
3946:                 missing diagonal entries)

3948:    Output Parameters:
3949: .  fact - new matrix that has been symbolically factored

3951:    Notes:
3952:    See the users manual for additional information about
3953:    choosing the fill factor for better efficiency.

3955:    Most users should employ the simplified KSP interface for linear solvers
3956:    instead of working directly with matrix algebra routines such as this.
3957:    See, e.g., KSPCreate().

3959:    Level: developer

3961:   Concepts: matrices^symbolic LU factorization
3962:   Concepts: matrices^factorization
3963:   Concepts: LU^symbolic factorization

3965: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
3966:           MatGetOrdering(), MatFactorInfo

3968: @*/
3969: int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatFactorInfo *info,Mat *fact)
3970: {

3976:   MatPreallocated(mat);
3981:   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels);
3982:   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
3983:   if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",mat->type_name);
3984:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3985:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

3987:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
3988:   (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);
3989:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
3990:   return(0);
3991: }

3995: /*@  
3996:    MatICCFactorSymbolic - Performs symbolic incomplete
3997:    Cholesky factorization for a symmetric matrix.  Use 
3998:    MatCholeskyFactorNumeric() to complete the factorization.

4000:    Collective on Mat

4002:    Input Parameters:
4003: +  mat - the matrix
4004: .  perm - row and column permutation
4005: -  info - structure containing 
4006: $      levels - number of levels of fill.
4007: $      expected fill - as ratio of original fill.

4009:    Output Parameter:
4010: .  fact - the factored matrix

4012:    Notes:
4013:    Currently only no-fill factorization is supported.

4015:    Most users should employ the simplified KSP interface for linear solvers
4016:    instead of working directly with matrix algebra routines such as this.
4017:    See, e.g., KSPCreate().

4019:    Level: developer

4021:   Concepts: matrices^symbolic incomplete Cholesky factorization
4022:   Concepts: matrices^factorization
4023:   Concepts: Cholsky^symbolic factorization

4025: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
4026: @*/
4027: int MatICCFactorSymbolic(Mat mat,IS perm,MatFactorInfo *info,Mat *fact)
4028: {

4034:   MatPreallocated(mat);
4038:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4039:   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %d",(int) info->levels);
4040:   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill);
4041:   if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",mat->type_name);
4042:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");

4044:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
4045:   (*mat->ops->iccfactorsymbolic)(mat,perm,info,fact);
4046:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
4047:   return(0);
4048: }

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

4058:    Not Collective

4060:    Input Parameter:
4061: .  mat - the matrix

4063:    Output Parameter:
4064: .  v - the location of the values


4067:    Fortran Note:
4068:    This routine is used differently from Fortran, e.g.,
4069: .vb
4070:         Mat         mat
4071:         PetscScalar mat_array(1)
4072:         PetscOffset i_mat
4073:         int         ierr
4074:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

4080:         [... other code ...]
4081:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4082: .ve

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

4087:    Level: advanced

4089:    Concepts: matrices^access array

4091: .seealso: MatRestoreArray(), MatGetArrayF90()
4092: @*/
4093: int MatGetArray(Mat mat,PetscScalar *v[])
4094: {

4100:   MatPreallocated(mat);
4102:   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4103:   (*mat->ops->getarray)(mat,v);
4104:   return(0);
4105: }

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

4112:    Not Collective

4114:    Input Parameter:
4115: +  mat - the matrix
4116: -  v - the location of the values

4118:    Fortran Note:
4119:    This routine is used differently from Fortran, e.g.,
4120: .vb
4121:         Mat         mat
4122:         PetscScalar mat_array(1)
4123:         PetscOffset i_mat
4124:         int         ierr
4125:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

4131:         [... other code ...]
4132:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
4133: .ve

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

4138:    Level: advanced

4140: .seealso: MatGetArray(), MatRestoreArrayF90()
4141: @*/
4142: int MatRestoreArray(Mat mat,PetscScalar *v[])
4143: {

4149:   MatPreallocated(mat);
4151: #if defined(PETSC_USE_BOPT_g)
4152:   CHKMEMQ;
4153: #endif
4154:   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4155:   (*mat->ops->restorearray)(mat,v);
4156:   PetscObjectIncreaseState((PetscObject)mat);
4157:   return(0);
4158: }

4162: /*@C
4163:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
4164:    points to an array of valid matrices, they may be reused to store the new
4165:    submatrices.

4167:    Collective on Mat

4169:    Input Parameters:
4170: +  mat - the matrix
4171: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
4172: .  irow, icol - index sets of rows and columns to extract
4173: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4175:    Output Parameter:
4176: .  submat - the array of submatrices

4178:    Notes:
4179:    MatGetSubMatrices() can extract only sequential submatrices
4180:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
4181:    to extract a parallel submatrix.

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

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

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

4193:    This routine creates the matrices in submat; you should NOT create them before
4194:    calling it. It also allocates the array of matrix pointers submat.

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

4200:    Level: advanced

4202:    Concepts: matrices^accessing submatrices
4203:    Concepts: submatrices

4205: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal()
4206: @*/
4207: int MatGetSubMatrices(Mat mat,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
4208: {
4209:   int        ierr;

4214:   MatPreallocated(mat);
4215:   if (n) {
4220:   }
4222:   if (n && scall == MAT_REUSE_MATRIX) {
4225:   }
4226:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4227:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4228:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

4230:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
4231:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
4232:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
4233:   return(0);
4234: }

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

4241:    Collective on Mat

4243:    Input Parameters:
4244: +  n - the number of local matrices
4245: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
4246:                        sequence of MatGetSubMatrices())

4248:    Level: advanced

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

4252: .seealso: MatGetSubMatrices()
4253: @*/
4254: int MatDestroyMatrices(int n,Mat *mat[])
4255: {
4256:   int ierr,i;

4259:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n);
4261:   for (i=0; i<n; i++) {
4262:     MatDestroy((*mat)[i]);
4263:   }
4264:   /* memory is allocated even if n = 0 */
4265:   PetscFree(*mat);
4266:   return(0);
4267: }

4271: /*@
4272:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
4273:    replaces the index sets by larger ones that represent submatrices with
4274:    additional overlap.

4276:    Collective on Mat

4278:    Input Parameters:
4279: +  mat - the matrix
4280: .  n   - the number of index sets
4281: .  is  - the array of index sets (these index sets will changed during the call)
4282: -  ov  - the additional overlap requested

4284:    Level: developer

4286:    Concepts: overlap
4287:    Concepts: ASM^computing overlap

4289: .seealso: MatGetSubMatrices()
4290: @*/
4291: int MatIncreaseOverlap(Mat mat,int n,IS is[],int ov)
4292: {

4298:   MatPreallocated(mat);
4299:   if (n < 0) SETERRQ1(1,"Must have one or more domains, you have %d",n);
4300:   if (n) {
4303:   }
4304:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4305:   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

4307:   if (!ov) return(0);
4308:   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4309:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
4310:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
4311:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
4312:   return(0);
4313: }

4317: /*@
4318:    MatPrintHelp - Prints all the options for the matrix.

4320:    Collective on Mat

4322:    Input Parameter:
4323: .  mat - the matrix 

4325:    Options Database Keys:
4326: +  -help - Prints matrix options
4327: -  -h - Prints matrix options

4329:    Level: developer

4331: .seealso: MatCreate(), MatCreateXXX()
4332: @*/
4333: int MatPrintHelp(Mat mat)
4334: {
4335:   static PetscTruth called = PETSC_FALSE;
4336:   int               ierr;

4341:   MatPreallocated(mat);

4343:   if (!called) {
4344:     if (mat->ops->printhelp) {
4345:       (*mat->ops->printhelp)(mat);
4346:     }
4347:     called = PETSC_TRUE;
4348:   }
4349:   return(0);
4350: }

4354: /*@
4355:    MatGetBlockSize - Returns the matrix block size; useful especially for the
4356:    block row and block diagonal formats.
4357:    
4358:    Not Collective

4360:    Input Parameter:
4361: .  mat - the matrix

4363:    Output Parameter:
4364: .  bs - block size

4366:    Notes:
4367:    Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG.
4368:    Block row formats are MATSEQBAIJ, MATMPIBAIJ

4370:    Level: intermediate

4372:    Concepts: matrices^block size

4374: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag()
4375: @*/
4376: int MatGetBlockSize(Mat mat,int *bs)
4377: {

4383:   MatPreallocated(mat);
4385:   if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4386:   (*mat->ops->getblocksize)(mat,bs);
4387:   return(0);
4388: }

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

4395:    Collective on Mat

4397:     Input Parameters:
4398: +   mat - the matrix
4399: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
4400: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4401:                 symmetrized

4403:     Output Parameters:
4404: +   n - number of rows in the (possibly compressed) matrix
4405: .   ia - the row pointers
4406: .   ja - the column indices
4407: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

4409:     Level: developer

4411: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4412: @*/
4413: int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4414: {

4420:   MatPreallocated(mat);
4425:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
4426:   else {
4427:     *done = PETSC_TRUE;
4428:     (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);
4429:   }
4430:   return(0);
4431: }

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

4438:     Collective on Mat

4440:     Input Parameters:
4441: +   mat - the matrix
4442: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4443: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4444:                 symmetrized

4446:     Output Parameters:
4447: +   n - number of columns in the (possibly compressed) matrix
4448: .   ia - the column pointers
4449: .   ja - the row indices
4450: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

4452:     Level: developer

4454: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4455: @*/
4456: int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4457: {

4463:   MatPreallocated(mat);

4469:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
4470:   else {
4471:     *done = PETSC_TRUE;
4472:     (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);
4473:   }
4474:   return(0);
4475: }

4479: /*@C
4480:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
4481:     MatGetRowIJ().

4483:     Collective on Mat

4485:     Input Parameters:
4486: +   mat - the matrix
4487: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4488: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4489:                 symmetrized

4491:     Output Parameters:
4492: +   n - size of (possibly compressed) matrix
4493: .   ia - the row pointers
4494: .   ja - the column indices
4495: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

4497:     Level: developer

4499: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
4500: @*/
4501: int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4502: {

4508:   MatPreallocated(mat);

4513:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
4514:   else {
4515:     *done = PETSC_TRUE;
4516:     (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);
4517:   }
4518:   return(0);
4519: }

4523: /*@C
4524:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
4525:     MatGetColumnIJ().

4527:     Collective on Mat

4529:     Input Parameters:
4530: +   mat - the matrix
4531: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
4532: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
4533:                 symmetrized

4535:     Output Parameters:
4536: +   n - size of (possibly compressed) matrix
4537: .   ia - the column pointers
4538: .   ja - the row indices
4539: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

4541:     Level: developer

4543: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
4544: @*/
4545: int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int *ia[],int* ja[],PetscTruth *done)
4546: {

4552:   MatPreallocated(mat);

4557:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
4558:   else {
4559:     *done = PETSC_TRUE;
4560:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);
4561:   }
4562:   return(0);
4563: }

4567: /*@C
4568:     MatColoringPatch -Used inside matrix coloring routines that 
4569:     use MatGetRowIJ() and/or MatGetColumnIJ().

4571:     Collective on Mat

4573:     Input Parameters:
4574: +   mat - the matrix
4575: .   n   - number of colors
4576: -   colorarray - array indicating color for each column

4578:     Output Parameters:
4579: .   iscoloring - coloring generated using colorarray information

4581:     Level: developer

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

4585: @*/
4586: int MatColoringPatch(Mat mat,int n,int ncolors,const ISColoringValue colorarray[],ISColoring *iscoloring)
4587: {

4593:   MatPreallocated(mat);

4597:   if (!mat->ops->coloringpatch){
4598:     ISColoringCreate(mat->comm,n,colorarray,iscoloring);
4599:   } else {
4600:     (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);
4601:   }
4602:   return(0);
4603: }


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

4611:    Collective on Mat

4613:    Input Parameter:
4614: .  mat - the factored matrix to be reset

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

4623:    Note that one can specify in-place ILU(0) factorization by calling 
4624: .vb
4625:      PCType(pc,PCILU);
4626:      PCILUSeUseInPlace(pc);
4627: .ve
4628:    or by using the options -pc_type ilu -pc_ilu_in_place

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

4636:    Most users should employ the simplified KSP interface for linear solvers
4637:    instead of working directly with matrix algebra routines such as this.
4638:    See, e.g., KSPCreate().

4640:    Level: developer

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

4644:    Concepts: matrices^unfactored

4646: @*/
4647: int MatSetUnfactored(Mat mat)
4648: {

4654:   MatPreallocated(mat);
4655:   mat->factor = 0;
4656:   if (!mat->ops->setunfactored) return(0);
4657:   (*mat->ops->setunfactored)(mat);
4658:   return(0);
4659: }

4661: /*MC
4662:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

4664:     Synopsis:
4665:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

4667:     Not collective

4669:     Input Parameter:
4670: .   x - matrix

4672:     Output Parameters:
4673: +   xx_v - the Fortran90 pointer to the array
4674: -   ierr - error code

4676:     Example of Usage: 
4677: .vb
4678:       PetscScalar, pointer xx_v(:)
4679:       ....
4680:       call MatGetArrayF90(x,xx_v,ierr)
4681:       a = xx_v(3)
4682:       call MatRestoreArrayF90(x,xx_v,ierr)
4683: .ve

4685:     Notes:
4686:     Not yet supported for all F90 compilers

4688:     Level: advanced

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

4692:     Concepts: matrices^accessing array

4694: M*/

4696: /*MC
4697:     MatRestoreArrayF90 - Restores a matrix array that has been
4698:     accessed with MatGetArrayF90().

4700:     Synopsis:
4701:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

4703:     Not collective

4705:     Input Parameters:
4706: +   x - matrix
4707: -   xx_v - the Fortran90 pointer to the array

4709:     Output Parameter:
4710: .   ierr - error code

4712:     Example of Usage: 
4713: .vb
4714:        PetscScalar, pointer xx_v(:)
4715:        ....
4716:        call MatGetArrayF90(x,xx_v,ierr)
4717:        a = xx_v(3)
4718:        call MatRestoreArrayF90(x,xx_v,ierr)
4719: .ve
4720:    
4721:     Notes:
4722:     Not yet supported for all F90 compilers

4724:     Level: advanced

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

4728: M*/


4733: /*@
4734:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
4735:                       as the original matrix.

4737:     Collective on Mat

4739:     Input Parameters:
4740: +   mat - the original matrix
4741: .   isrow - rows this processor should obtain
4742: .   iscol - columns for all processors you wish to keep
4743: .   csize - number of columns "local" to this processor (does nothing for sequential 
4744:             matrices). This should match the result from VecGetLocalSize(x,...) if you 
4745:             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
4746: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4748:     Output Parameter:
4749: .   newmat - the new submatrix, of the same type as the old

4751:     Level: advanced

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

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

4761:     Concepts: matrices^submatrices

4763: .seealso: MatGetSubMatrices(), ISAllGather()
4764: @*/
4765: int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat)
4766: {
4767:   int     ierr, size;
4768:   Mat     *local;

4777:   MatPreallocated(mat);
4778:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4779:   MPI_Comm_size(mat->comm,&size);

4781:   /* if original matrix is on just one processor then use submatrix generated */
4782:   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
4783:     MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);
4784:     return(0);
4785:   } else if (!mat->ops->getsubmatrix && size == 1) {
4786:     MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);
4787:     *newmat = *local;
4788:     PetscFree(local);
4789:     return(0);
4790:   }

4792:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
4793:   (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);
4794:   PetscObjectIncreaseState((PetscObject)*newmat);
4795:   return(0);
4796: }

4800: /*@C
4801:    MatGetPetscMaps - Returns the maps associated with the matrix.

4803:    Not Collective

4805:    Input Parameter:
4806: .  mat - the matrix

4808:    Output Parameters:
4809: +  rmap - the row (right) map
4810: -  cmap - the column (left) map  

4812:    Level: developer

4814:    Concepts: maps^getting from matrix

4816: @*/
4817: int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap)
4818: {

4824:   MatPreallocated(mat);
4825:   (*mat->ops->getmaps)(mat,rmap,cmap);
4826:   return(0);
4827: }

4829: /*
4830:       Version that works for all PETSc matrices
4831: */
4834: int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap)
4835: {
4837:   if (rmap) *rmap = mat->rmap;
4838:   if (cmap) *cmap = mat->cmap;
4839:   return(0);
4840: }

4844: /*@
4845:    MatSetStashInitialSize - sets the sizes of the matrix stash, that is
4846:    used during the assembly process to store values that belong to 
4847:    other processors.

4849:    Not Collective

4851:    Input Parameters:
4852: +  mat   - the matrix
4853: .  size  - the initial size of the stash.
4854: -  bsize - the initial size of the block-stash(if used).

4856:    Options Database Keys:
4857: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
4858: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

4860:    Level: intermediate

4862:    Notes: 
4863:      The block-stash is used for values set with VecSetValuesBlocked() while
4864:      the stash is used for values set with VecSetValues()

4866:      Run with the option -log_info and look for output of the form
4867:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
4868:      to determine the appropriate value, MM, to use for size and 
4869:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
4870:      to determine the value, BMM to use for bsize

4872:    Concepts: stash^setting matrix size
4873:    Concepts: matrices^stash

4875: @*/
4876: int MatSetStashInitialSize(Mat mat,int size, int bsize)
4877: {

4883:   MatPreallocated(mat);
4884:   MatStashSetInitialSize_Private(&mat->stash,size);
4885:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
4886:   return(0);
4887: }

4891: /*@
4892:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
4893:      the matrix

4895:    Collective on Mat

4897:    Input Parameters:
4898: +  mat   - the matrix
4899: .  x,y - the vectors
4900: -  w - where the result is stored

4902:    Level: intermediate

4904:    Notes: 
4905:     w may be the same vector as y. 

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

4910:     Concepts: interpolation

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

4914: @*/
4915: int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
4916: {
4917:   int M,N,ierr;

4925:   MatPreallocated(A);
4926:   MatGetSize(A,&M,&N);
4927:   if (N > M) {
4928:     MatMultTransposeAdd(A,x,y,w);
4929:   } else {
4930:     MatMultAdd(A,x,y,w);
4931:   }
4932:   return(0);
4933: }

4937: /*@
4938:    MatInterpolate - y = A*x or A'*x depending on the shape of 
4939:      the matrix

4941:    Collective on Mat

4943:    Input Parameters:
4944: +  mat   - the matrix
4945: -  x,y - the vectors

4947:    Level: intermediate

4949:    Notes: 
4950:     This allows one to use either the restriction or interpolation (its transpose)
4951:     matrix to do the interpolation

4953:    Concepts: matrices^interpolation

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

4957: @*/
4958: int MatInterpolate(Mat A,Vec x,Vec y)
4959: {
4960:   int M,N,ierr;

4967:   MatPreallocated(A);
4968:   MatGetSize(A,&M,&N);
4969:   if (N > M) {
4970:     MatMultTranspose(A,x,y);
4971:   } else {
4972:     MatMult(A,x,y);
4973:   }
4974:   return(0);
4975: }

4979: /*@
4980:    MatRestrict - y = A*x or A'*x

4982:    Collective on Mat

4984:    Input Parameters:
4985: +  mat   - the matrix
4986: -  x,y - the vectors

4988:    Level: intermediate

4990:    Notes: 
4991:     This allows one to use either the restriction or interpolation (its transpose)
4992:     matrix to do the restriction

4994:    Concepts: matrices^restriction

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

4998: @*/
4999: int MatRestrict(Mat A,Vec x,Vec y)
5000: {
5001:   int M,N,ierr;

5008:   MatPreallocated(A);
5009:   MatGetSize(A,&M,&N);
5010:   if (N > M) {
5011:     MatMult(A,x,y);
5012:   } else {
5013:     MatMultTranspose(A,x,y);
5014:   }
5015:   return(0);
5016: }

5020: /*@C
5021:    MatNullSpaceAttach - attaches a null space to a matrix.
5022:         This null space will be removed from the resulting vector whenever
5023:         MatMult() is called

5025:    Collective on Mat

5027:    Input Parameters:
5028: +  mat - the matrix
5029: -  nullsp - the null space object

5031:    Level: developer

5033:    Notes:
5034:       Overwrites any previous null space that may have been attached

5036:    Concepts: null space^attaching to matrix

5038: .seealso: MatCreate(), MatNullSpaceCreate()
5039: @*/
5040: int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
5041: {

5047:   MatPreallocated(mat);

5050:   if (mat->nullsp) {
5051:     MatNullSpaceDestroy(mat->nullsp);
5052:   }
5053:   mat->nullsp = nullsp;
5054:   PetscObjectReference((PetscObject)nullsp);
5055:   return(0);
5056: }

5060: /*@  
5061:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

5063:    Collective on Mat

5065:    Input Parameters:
5066: +  mat - the matrix
5067: .  row - row/column permutation
5068: .  fill - expected fill factor >= 1.0
5069: -  level - level of fill, for ICC(k)

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

5075:    Most users should employ the simplified KSP interface for linear solvers
5076:    instead of working directly with matrix algebra routines such as this.
5077:    See, e.g., KSPCreate().

5079:    Level: developer

5081:    Concepts: matrices^incomplete Cholesky factorization
5082:    Concepts: Cholesky factorization

5084: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5085: @*/
5086: int MatICCFactor(Mat mat,IS row,MatFactorInfo* info)
5087: {

5093:   MatPreallocated(mat);
5096:   if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
5097:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5098:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5099:   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5100:   (*mat->ops->iccfactor)(mat,row,info);
5101:   PetscObjectIncreaseState((PetscObject)mat);
5102:   return(0);
5103: }

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

5110:    Not Collective

5112:    Input Parameters:
5113: +  mat - the matrix
5114: -  v - the values compute with ADIC

5116:    Level: developer

5118:    Notes:
5119:      Must call MatSetColoring() before using this routine. Also this matrix must already
5120:      have its nonzero pattern determined.

5122: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5123:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
5124: @*/
5125: int MatSetValuesAdic(Mat mat,void *v)
5126: {


5134:   if (!mat->assembled) {
5135:     SETERRQ(1,"Matrix must be already assembled");
5136:   }
5137:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
5138:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5139:   (*mat->ops->setvaluesadic)(mat,v);
5140:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
5141:   MatView_Private(mat);
5142:   PetscObjectIncreaseState((PetscObject)mat);
5143:   return(0);
5144: }


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

5152:    Not Collective

5154:    Input Parameters:
5155: +  mat - the matrix
5156: -  coloring - the coloring

5158:    Level: developer

5160: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5161:           MatSetValues(), MatSetValuesAdic()
5162: @*/
5163: int MatSetColoring(Mat mat,ISColoring coloring)
5164: {


5172:   if (!mat->assembled) {
5173:     SETERRQ(1,"Matrix must be already assembled");
5174:   }
5175:   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5176:   (*mat->ops->setcoloring)(mat,coloring);
5177:   return(0);
5178: }

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

5185:    Not Collective

5187:    Input Parameters:
5188: +  mat - the matrix
5189: .  nl - leading dimension of v
5190: -  v - the values compute with ADIFOR

5192:    Level: developer

5194:    Notes:
5195:      Must call MatSetColoring() before using this routine. Also this matrix must already
5196:      have its nonzero pattern determined.

5198: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
5199:           MatSetValues(), MatSetColoring()
5200: @*/
5201: int MatSetValuesAdifor(Mat mat,int nl,void *v)
5202: {


5210:   if (!mat->assembled) {
5211:     SETERRQ(1,"Matrix must be already assembled");
5212:   }
5213:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
5214:   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5215:   (*mat->ops->setvaluesadifor)(mat,nl,v);
5216:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
5217:   PetscObjectIncreaseState((PetscObject)mat);
5218:   return(0);
5219: }

5221: EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec);
5222: EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec);

5226: /*@ 
5227:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
5228:          ghosted ones.

5230:    Not Collective

5232:    Input Parameters:
5233: +  mat - the matrix
5234: -  diag = the diagonal values, including ghost ones

5236:    Level: developer

5238:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
5239:       
5240: .seealso: MatDiagonalScale()
5241: @*/
5242: int MatDiagonalScaleLocal(Mat mat,Vec diag)
5243: {
5244:   int        ierr,size;


5251:   if (!mat->assembled) {
5252:     SETERRQ(1,"Matrix must be already assembled");
5253:   }
5254:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5255:   MPI_Comm_size(mat->comm,&size);
5256:   if (size == 1) {
5257:     int n,m;
5258:     VecGetSize(diag,&n);
5259:     MatGetSize(mat,0,&m);
5260:     if (m == n) {
5261:       MatDiagonalScale(mat,0,diag);
5262:     } else {
5263:       SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions");
5264:     }
5265:   } else {
5266:     int (*f)(Mat,Vec);
5267:     PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
5268:     if (f) {
5269:       (*f)(mat,diag);
5270:     } else {
5271:       SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
5272:     }
5273:   }
5274:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5275:   PetscObjectIncreaseState((PetscObject)mat);
5276:   return(0);
5277: }

5281: /*@ 
5282:    MatGetInertia - Gets the inertia from a factored matrix

5284:    Collective on Mat

5286:    Input Parameter:
5287: .  mat - the matrix

5289:    Output Parameters:
5290: +   nneg - number of negative eigenvalues
5291: .   nzero - number of zero eigenvalues
5292: -   npos - number of positive eigenvalues

5294:    Level: advanced

5296:    Notes: Matrix must have been factored by MatCholeskyFactor()


5299: @*/
5300: int MatGetInertia(Mat mat,int *nneg,int *nzero,int *npos)
5301: {
5302:   int        ierr;

5307:   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5308:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
5309:   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5310:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
5311:   return(0);
5312: }

5314: /* ----------------------------------------------------------------*/
5317: /*@
5318:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

5320:    Collective on Mat and Vecs

5322:    Input Parameters:
5323: +  mat - the factored matrix
5324: -  b - the right-hand-side vectors

5326:    Output Parameter:
5327: .  x - the result vectors

5329:    Notes:
5330:    The vectors b and x cannot be the same.  I.e., one cannot
5331:    call MatSolves(A,x,x).

5333:    Notes:
5334:    Most users should employ the simplified KSP interface for linear solvers
5335:    instead of working directly with matrix algebra routines such as this.
5336:    See, e.g., KSPCreate().

5338:    Level: developer

5340:    Concepts: matrices^triangular solves

5342: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
5343: @*/
5344: int MatSolves(Mat mat,Vecs b,Vecs x)
5345: {

5351:   MatPreallocated(mat);
5352:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
5353:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
5354:   if (mat->M == 0 && mat->N == 0) return(0);

5356:   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name);
5357:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
5358:   (*mat->ops->solves)(mat,b,x);
5359:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
5360:   return(0);
5361: }

5365: /*@C
5366:    MatIsSymmetric - Test whether a matrix is symmetric

5368:    Collective on Mat

5370:    Input Parameter:
5371: .  A - the matrix to test

5373:    Output Parameters:
5374: .  flg - the result

5376:    Level: intermediate

5378:    Concepts: matrix^symmetry

5380: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption()
5381: @*/
5382: int MatIsSymmetric(Mat A,PetscTruth *flg)
5383: {

5389:   if (!A->symmetric_set) {
5390:     if (!A->ops->issymmetric) {
5391:       MatType mattype;
5392:       MatGetType(A,&mattype);
5393:       SETERRQ1(1,"Matrix of type <%s> does not support checking for symmetric",
5394:                mattype);
5395:     }
5396:     (*A->ops->issymmetric)(A,&A->symmetric);
5397:     A->symmetric_set = PETSC_TRUE;
5398:     if (A->symmetric) {
5399:       A->structurally_symmetric_set = PETSC_TRUE;
5400:       A->structurally_symmetric     = PETSC_TRUE;
5401:     }
5402:   }
5403:   *flg = A->symmetric;
5404:   return(0);
5405: }

5409: /*@C
5410:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

5412:    Collective on Mat

5414:    Input Parameter:
5415: .  A - the matrix to test

5417:    Output Parameters:
5418: .  flg - the result

5420:    Level: intermediate

5422:    Concepts: matrix^symmetry

5424: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
5425: @*/
5426: int MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
5427: {

5433:   if (!A->structurally_symmetric_set) {
5434:     if (!A->ops->isstructurallysymmetric) SETERRQ(1,"Matrix does not support checking for structural symmetric");
5435:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
5436:     A->structurally_symmetric_set = PETSC_TRUE;
5437:   }
5438:   *flg = A->structurally_symmetric;
5439:   return(0);
5440: }

5444: /*@C
5445:    MatIsHermitian - Test whether a matrix is Hermitian, i.e. it is the complex conjugate of its transpose.

5447:    Collective on Mat

5449:    Input Parameter:
5450: .  A - the matrix to test

5452:    Output Parameters:
5453: .  flg - the result

5455:    Level: intermediate

5457:    Concepts: matrix^symmetry

5459: .seealso: MatTranspose(), MatIsTranspose(), MatIsSymmetric(), MatIsStructurallySymmetric(), MatSetOption()
5460: @*/
5461: int MatIsHermitian(Mat A,PetscTruth *flg)
5462: {

5468:   if (!A->hermitian_set) {
5469:     if (!A->ops->ishermitian) SETERRQ(1,"Matrix does not support checking for being Hermitian");
5470:     (*A->ops->ishermitian)(A,&A->hermitian);
5471:     A->hermitian_set = PETSC_TRUE;
5472:     if (A->hermitian) {
5473:       A->structurally_symmetric_set = PETSC_TRUE;
5474:       A->structurally_symmetric     = PETSC_TRUE;
5475:     }
5476:   }
5477:   *flg = A->hermitian;
5478:   return(0);
5479: }