Actual source code: matrix.c

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

  6: #include <private/matimpl.h>        /*I "petscmat.h" I*/
  7: #include <private/vecimpl.h>  

  9: /* Logging support */
 10: PetscClassId  MAT_CLASSID;
 11: PetscClassId  MAT_FDCOLORING_CLASSID;

 13: PetscLogEvent  MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
 14: PetscLogEvent  MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
 15: PetscLogEvent  MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
 16: PetscLogEvent  MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
 17: PetscLogEvent  MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
 18: PetscLogEvent  MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
 19: PetscLogEvent  MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
 20: PetscLogEvent  MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
 21: PetscLogEvent  MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
 22: PetscLogEvent  MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
 23: PetscLogEvent  MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
 24: PetscLogEvent  MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
 25: PetscLogEvent  MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
 26: PetscLogEvent  MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
 27: PetscLogEvent  MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
 28: PetscLogEvent  MAT_GetMultiProcBlock;
 29: PetscLogEvent  MAT_CUSPCopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;

 31: /* nasty global values for MatSetValue() */
 32: PetscInt     MatSetValue_Row = 0;
 33: PetscInt     MatSetValue_Column = 0;
 34: PetscScalar  MatSetValue_Value = 0.0;

 36: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};

 40: /*@C
 41:       MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix

 43:   Input Parameter:
 44: .    A  - the matrix 

 46:   Output Parameter:
 47: .    keptrows - the rows that are not completely zero

 49:   Level: intermediate

 51:  @*/
 52: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
 53: {
 54:   PetscErrorCode    ierr;

 58:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
 59:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
 60:   if (!mat->ops->findnonzerorows) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not coded for this matrix type");
 61:   (*mat->ops->findnonzerorows)(mat,keptrows);
 62:   return(0);
 63: }

 67: /*@
 68:    MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling

 70:    Not Collective

 72:    Input Parameters:
 73: .   A - the matrix

 75:    Output Parameters:
 76: .   a - the diagonal part (which is a SEQUENTIAL matrix)

 78:    Notes: see the manual page for MatCreateMPIAIJ() for more information on the "diagonal part" of the matrix.

 80:    Level: advanced

 82: @*/
 83: PetscErrorCode  MatGetDiagonalBlock(Mat A,Mat *a)
 84: {
 85:   PetscErrorCode ierr,(*f)(Mat,Mat*);
 86:   PetscMPIInt    size;

 92:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
 93:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
 94:   MPI_Comm_size(((PetscObject)A)->comm,&size);
 95:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);
 96:   if (f) {
 97:     (*f)(A,a);
 98:     return(0);
 99:   } else if (size == 1) {
100:     *a = A;
101:   } else {
102:     const MatType mattype;
103:     MatGetType(A,&mattype);
104:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
105:   }
106:   return(0);
107: }

111: /*@
112:    MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.

114:    Collective on Mat

116:    Input Parameters:
117: .  mat - the matrix

119:    Output Parameter:
120: .   trace - the sum of the diagonal entries

122:    Level: advanced

124: @*/
125: PetscErrorCode  MatGetTrace(Mat mat,PetscScalar *trace)
126: {
128:    Vec            diag;

131:    MatGetVecs(mat,&diag,PETSC_NULL);
132:    MatGetDiagonal(mat,diag);
133:    VecSum(diag,trace);
134:    VecDestroy(&diag);
135:    return(0);
136: }

140: /*@
141:    MatRealPart - Zeros out the imaginary part of the matrix

143:    Logically Collective on Mat

145:    Input Parameters:
146: .  mat - the matrix

148:    Level: advanced


151: .seealso: MatImaginaryPart()
152: @*/
153: PetscErrorCode  MatRealPart(Mat mat)
154: {

160:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
161:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
162:   if (!mat->ops->realpart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
163:   MatPreallocated(mat);
164:   (*mat->ops->realpart)(mat);
165: #if defined(PETSC_HAVE_CUSP)
166:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
167:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
168:   }
169: #endif
170:   return(0);
171: }

175: /*@C
176:    MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix

178:    Collective on Mat

180:    Input Parameter:
181: .  mat - the matrix

183:    Output Parameters:
184: +   nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
185: -   ghosts - the global indices of the ghost points

187:    Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()

189:    Level: advanced

191: @*/
192: PetscErrorCode  MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
193: {

199:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
200:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
201:   if (!mat->ops->getghosts) {
202:     if (nghosts) *nghosts = 0;
203:     if (ghosts) *ghosts = 0;
204:   } else {
205:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
206:   }
207:   return(0);
208: }


213: /*@
214:    MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part

216:    Logically Collective on Mat

218:    Input Parameters:
219: .  mat - the matrix

221:    Level: advanced


224: .seealso: MatRealPart()
225: @*/
226: PetscErrorCode  MatImaginaryPart(Mat mat)
227: {

233:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
234:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
235:   if (!mat->ops->imaginarypart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
236:   MatPreallocated(mat);
237:   (*mat->ops->imaginarypart)(mat);
238: #if defined(PETSC_HAVE_CUSP)
239:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
240:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
241:   }
242: #endif
243:   return(0);
244: }

248: /*@
249:    MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)

251:    Collective on Mat

253:    Input Parameter:
254: .  mat - the matrix

256:    Output Parameters:
257: +  missing - is any diagonal missing
258: -  dd - first diagonal entry that is missing (optional)

260:    Level: advanced


263: .seealso: MatRealPart()
264: @*/
265: PetscErrorCode  MatMissingDiagonal(Mat mat,PetscBool  *missing,PetscInt *dd)
266: {

272:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
273:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
274:   if (!mat->ops->missingdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
275:   (*mat->ops->missingdiagonal)(mat,missing,dd);
276:   return(0);
277: }

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

286:    Not Collective

288:    Input Parameters:
289: +  mat - the matrix
290: -  row - the row to get

292:    Output Parameters:
293: +  ncols -  if not NULL, the number of nonzeros in the row
294: .  cols - if not NULL, the column numbers
295: -  vals - if not NULL, the values

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

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

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

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

312:    You can only have one call to MatGetRow() outstanding for a particular
313:    matrix at a time, per processor. MatGetRow() can only obtain rows
314:    associated with the given processor, it cannot get rows from the 
315:    other processors; for that we suggest using MatGetSubMatrices(), then
316:    MatGetRow() on the submatrix. The row indix passed to MatGetRows() 
317:    is in the global number of rows.

319:    Fortran Notes:
320:    The calling sequence from Fortran is 
321: .vb
322:    MatGetRow(matrix,row,ncols,cols,values,ierr)
323:          Mat     matrix (input)
324:          integer row    (input)
325:          integer ncols  (output)
326:          integer cols(maxcols) (output)
327:          double precision (or double complex) values(maxcols) output
328: .ve
329:    where maxcols >= maximum nonzeros in any row of the matrix.


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

336:    Level: advanced

338:    Concepts: matrices^row access

340: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
341: @*/
342: PetscErrorCode  MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
343: {
345:   PetscInt       incols;

350:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353:   MatPreallocated(mat);
354:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
355:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
356:   if (ncols) *ncols = incols;
357:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
358:   return(0);
359: }

363: /*@
364:    MatConjugate - replaces the matrix values with their complex conjugates

366:    Logically Collective on Mat

368:    Input Parameters:
369: .  mat - the matrix

371:    Level: advanced

373: .seealso:  VecConjugate()
374: @*/
375: PetscErrorCode  MatConjugate(Mat mat)
376: {

381:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
382:   if (!mat->ops->conjugate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
383:   (*mat->ops->conjugate)(mat);
384: #if defined(PETSC_HAVE_CUSP)
385:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
386:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
387:   }
388: #endif
389:   return(0);
390: }

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

397:    Not Collective

399:    Input Parameters:
400: +  mat - the matrix
401: .  row - the row to get
402: .  ncols, cols - the number of nonzeros and their columns
403: -  vals - if nonzero the column values

405:    Notes: 
406:    This routine should be called after you have finished examining the entries.

408:    Fortran Notes:
409:    The calling sequence from Fortran is 
410: .vb
411:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
412:       Mat     matrix (input)
413:       integer row    (input)
414:       integer ncols  (output)
415:       integer cols(maxcols) (output)
416:       double precision (or double complex) values(maxcols) output
417: .ve
418:    Where maxcols >= maximum nonzeros in any row of the matrix. 

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

423:    Level: advanced

425: .seealso:  MatGetRow()
426: @*/
427: PetscErrorCode  MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
428: {

434:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
435:   if (!mat->ops->restorerow) return(0);
436:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
437:   return(0);
438: }

442: /*@
443:    MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.  
444:    You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 

446:    Not Collective

448:    Input Parameters:
449: +  mat - the matrix

451:    Notes:
452:    The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format.

454:    Level: advanced

456:    Concepts: matrices^row access

458: .seealso: MatRestoreRowRowUpperTriangular()
459: @*/
460: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
461: {

467:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
468:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
469:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
470:   MatPreallocated(mat);
471:   (*mat->ops->getrowuppertriangular)(mat);
472:   return(0);
473: }

477: /*@
478:    MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.  

480:    Not Collective

482:    Input Parameters:
483: +  mat - the matrix

485:    Notes: 
486:    This routine should be called after you have finished MatGetRow/MatRestoreRow().


489:    Level: advanced

491: .seealso:  MatGetRowUpperTriangular()
492: @*/
493: PetscErrorCode  MatRestoreRowUpperTriangular(Mat mat)
494: {

499:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
500:   if (!mat->ops->restorerowuppertriangular) return(0);
501:   (*mat->ops->restorerowuppertriangular)(mat);
502:   return(0);
503: }

507: /*@C
508:    MatSetOptionsPrefix - Sets the prefix used for searching for all 
509:    Mat options in the database.

511:    Logically Collective on Mat

513:    Input Parameter:
514: +  A - the Mat context
515: -  prefix - the prefix to prepend to all option names

517:    Notes:
518:    A hyphen (-) must NOT be given at the beginning of the prefix name.
519:    The first character of all runtime options is AUTOMATICALLY the hyphen.

521:    Level: advanced

523: .keywords: Mat, set, options, prefix, database

525: .seealso: MatSetFromOptions()
526: @*/
527: PetscErrorCode  MatSetOptionsPrefix(Mat A,const char prefix[])
528: {

533:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
534:   return(0);
535: }

539: /*@C
540:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all 
541:    Mat options in the database.

543:    Logically Collective on Mat

545:    Input Parameters:
546: +  A - the Mat context
547: -  prefix - the prefix to prepend to all option names

549:    Notes:
550:    A hyphen (-) must NOT be given at the beginning of the prefix name.
551:    The first character of all runtime options is AUTOMATICALLY the hyphen.

553:    Level: advanced

555: .keywords: Mat, append, options, prefix, database

557: .seealso: MatGetOptionsPrefix()
558: @*/
559: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
560: {
562: 
565:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
566:   return(0);
567: }

571: /*@C
572:    MatGetOptionsPrefix - Sets the prefix used for searching for all 
573:    Mat options in the database.

575:    Not Collective

577:    Input Parameter:
578: .  A - the Mat context

580:    Output Parameter:
581: .  prefix - pointer to the prefix string used

583:    Notes: On the fortran side, the user should pass in a string 'prefix' of
584:    sufficient length to hold the prefix.

586:    Level: advanced

588: .keywords: Mat, get, options, prefix, database

590: .seealso: MatAppendOptionsPrefix()
591: @*/
592: PetscErrorCode  MatGetOptionsPrefix(Mat A,const char *prefix[])
593: {

598:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
599:   return(0);
600: }

604: /*@
605:    MatSetUp - Sets up the internal matrix data structures for the later use.

607:    Collective on Mat

609:    Input Parameters:
610: .  A - the Mat context

612:    Notes:
613:    For basic use of the Mat classes the user need not explicitly call
614:    MatSetUp(), since these actions will happen automatically.

616:    Level: advanced

618: .keywords: Mat, setup

620: .seealso: MatCreate(), MatDestroy()
621: @*/
622: PetscErrorCode  MatSetUp(Mat A)
623: {
624:   PetscMPIInt    size;

629:   if (!((PetscObject)A)->type_name) {
630:     MPI_Comm_size(((PetscObject)A)->comm, &size);
631:     if (size == 1) {
632:       MatSetType(A, MATSEQAIJ);
633:     } else {
634:       MatSetType(A, MATMPIAIJ);
635:     }
636:   }
637:   MatSetUpPreallocation(A);
638:   return(0);
639: }


644: /*@C
645:    MatView - Visualizes a matrix object.

647:    Collective on Mat

649:    Input Parameters:
650: +  mat - the matrix
651: -  viewer - visualization context

653:   Notes:
654:   The available visualization contexts include
655: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
656: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
657:         output where only the first processor opens
658:         the file.  All other processors send their 
659:         data to the first processor to print. 
660: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

662:    The user can open alternative visualization contexts with
663: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
664: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
665:          specified file; corresponding input uses MatLoad()
666: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to 
667:          an X window display
668: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
669:          Currently only the sequential dense and AIJ
670:          matrix types support the Socket viewer.

672:    The user can call PetscViewerSetFormat() to specify the output
673:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
674:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
675: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
676: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
677: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
678: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 
679:          format common among all matrix types
680: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 
681:          format (which is in many cases the same as the default)
682: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
683:          size and structure (not the matrix entries)
684: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
685:          the matrix structure

687:    Options Database Keys:
688: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
689: .  -mat_view_info_detailed - Prints more detailed info
690: .  -mat_view - Prints matrix in ASCII format
691: .  -mat_view_matlab - Prints matrix in Matlab format
692: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
693: .  -display <name> - Sets display name (default is host)
694: .  -draw_pause <sec> - Sets number of seconds to pause after display
695: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
696: .  -viewer_socket_machine <machine>
697: .  -viewer_socket_port <port>
698: .  -mat_view_binary - save matrix to file in binary format
699: -  -viewer_binary_filename <name>
700:    Level: beginner

702:    Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
703:       viewer is used.

705:       See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
706:       viewer is used.

708:    Concepts: matrices^viewing
709:    Concepts: matrices^plotting
710:    Concepts: matrices^printing

712: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 
713:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
714: @*/
715: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
716: {
717:   PetscErrorCode    ierr;
718:   PetscInt          rows,cols;
719:   PetscBool         iascii;
720:   PetscViewerFormat format;

725:   if (!viewer) {
726:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
727:   }
730:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
731:   MatPreallocated(mat);

733:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
734:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
735:   if (iascii) {
736:     PetscViewerGetFormat(viewer,&format);
737:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
738:       PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
739:       PetscViewerASCIIPushTab(viewer);
740:       MatGetSize(mat,&rows,&cols);
741:       PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
742:       if (mat->factortype) {
743:         const MatSolverPackage solver;
744:         MatFactorGetSolverPackage(mat,&solver);
745:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
746:       }
747:       if (mat->ops->getinfo) {
748:         MatInfo info;
749:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
750:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
751:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
752:       }
753:     }
754:   }
755:   if (mat->ops->view) {
756:     PetscViewerASCIIPushTab(viewer);
757:     (*mat->ops->view)(mat,viewer);
758:     PetscViewerASCIIPopTab(viewer);
759:   } else if (!iascii) {
760:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
761:   }
762:   if (iascii) {
763:     PetscViewerGetFormat(viewer,&format);
764:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
765:       PetscViewerASCIIPopTab(viewer);
766:     }
767:   }
768:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
769:   return(0);
770: }

772: #if defined(PETSC_USE_DEBUG)
773: #include <../src/sys/totalview/tv_data_display.h>
774: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
775: {
776:   TV_add_row("Local rows", "int", &mat->rmap->n);
777:   TV_add_row("Local columns", "int", &mat->cmap->n);
778:   TV_add_row("Global rows", "int", &mat->rmap->N);
779:   TV_add_row("Global columns", "int", &mat->cmap->N);
780:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
781:   return TV_format_OK;
782: }
783: #endif

787: /*@C
788:    MatLoad - Loads a matrix that has been stored in binary format
789:    with MatView().  The matrix format is determined from the options database.
790:    Generates a parallel MPI matrix if the communicator has more than one
791:    processor.  The default matrix type is AIJ.

793:    Collective on PetscViewer

795:    Input Parameters:
796: +  newmat - the newly loaded matrix, this needs to have been created with MatCreate()
797:             or some related function before a call to MatLoad()
798: -  viewer - binary file viewer, created with PetscViewerBinaryOpen()

800:    Options Database Keys:
801:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
802:    block size
803: .    -matload_block_size <bs>

805:    Level: beginner

807:    Notes:
808:    If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 
809:    Mat before calling this routine if you wish to set it from the options database.

811:    MatLoad() automatically loads into the options database any options
812:    given in the file filename.info where filename is the name of the file
813:    that was passed to the PetscViewerBinaryOpen(). The options in the info
814:    file will be ignored if you use the -viewer_binary_skip_info option.

816:    If the type or size of newmat is not set before a call to MatLoad, PETSc
817:    sets the default matrix type AIJ and sets the local and global sizes.
818:    If type and/or size is already set, then the same are used.     

820:    In parallel, each processor can load a subset of rows (or the
821:    entire matrix).  This routine is especially useful when a large
822:    matrix is stored on disk and only part of it is desired on each
823:    processor.  For example, a parallel solver may access only some of
824:    the rows from each processor.  The algorithm used here reads
825:    relatively small blocks of data rather than reading the entire
826:    matrix and then subsetting it.

828:    Notes for advanced users:
829:    Most users should not need to know the details of the binary storage
830:    format, since MatLoad() and MatView() completely hide these details.
831:    But for anyone who's interested, the standard binary matrix storage
832:    format is

834: $    int    MAT_FILE_CLASSID
835: $    int    number of rows
836: $    int    number of columns
837: $    int    total number of nonzeros
838: $    int    *number nonzeros in each row
839: $    int    *column indices of all nonzeros (starting index is zero)
840: $    PetscScalar *values of all nonzeros

842:    PETSc automatically does the byte swapping for
843: machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
844: linux, Windows and the paragon; thus if you write your own binary
845: read/write routines you have to swap the bytes; see PetscBinaryRead()
846: and PetscBinaryWrite() to see how this may be done.

848: .keywords: matrix, load, binary, input

850: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()

852:  @*/
853: PetscErrorCode  MatLoad(Mat newmat,PetscViewer viewer)
854: {
856:   PetscBool      isbinary,flg;

861:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
862:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");

864:   if (!((PetscObject)newmat)->type_name) {
865:     MatSetType(newmat,MATAIJ);
866:   }

868:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
869:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
870:   (*newmat->ops->load)(newmat,viewer);
871:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

873:   flg  = PETSC_FALSE;
874:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,PETSC_NULL);
875:   if (flg) {
876:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
877:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
878:   }
879:   flg  = PETSC_FALSE;
880:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,PETSC_NULL);
881:   if (flg) {
882:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
883:   }
884:   return(0);
885: }

889: /*@
890:    MatScaleSystem - Scale a vector solution and right hand side to 
891:    match the scaling of a scaled matrix.
892:   
893:    Collective on Mat

895:    Input Parameter:
896: +  mat - the matrix
897: .  b - right hand side vector (or PETSC_NULL)
898: -  x - solution vector (or PETSC_NULL)


901:    Notes: 
902:    For AIJ, and BAIJ matrix formats, the matrices are not 
903:    internally scaled, so this does nothing. 

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

908:    Level: Developer            

910:    Concepts: matrices^scaling

912: .seealso: MatUseScaledForm(), MatUnScaleSystem()
913: @*/
914: PetscErrorCode  MatScaleSystem(Mat mat,Vec b,Vec x)
915: {

921:   MatPreallocated(mat);

925:   if (mat->ops->scalesystem) {
926:     (*mat->ops->scalesystem)(mat,b,x);
927:   }
928:   return(0);
929: }

933: /*@
934:    MatUnScaleSystem - Unscales a vector solution and right hand side to 
935:    match the original scaling of a scaled matrix.
936:   
937:    Collective on Mat

939:    Input Parameter:
940: +  mat - the matrix
941: .  b - right hand side vector (or PETSC_NULL)
942: -  x - solution vector (or PETSC_NULL)


945:    Notes: 
946:    For AIJ and BAIJ matrix formats, the matrices are not 
947:    internally scaled, so this does nothing. 

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

952:    Level: Developer            

954: .seealso: MatUseScaledForm(), MatScaleSystem()
955: @*/
956: PetscErrorCode  MatUnScaleSystem(Mat mat,Vec b,Vec x)
957: {

963:   MatPreallocated(mat);
966:   if (mat->ops->unscalesystem) {
967:     (*mat->ops->unscalesystem)(mat,b,x);
968:   }
969:   return(0);
970: }

974: /*@
975:    MatUseScaledForm - For matrix storage formats that scale the 
976:    matrix indicates matrix operations (MatMult() etc) are 
977:    applied using the scaled matrix.
978:   
979:    Logically Collective on Mat

981:    Input Parameter:
982: +  mat - the matrix
983: -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for 
984:             applying the original matrix

986:    Notes: 
987:    For scaled matrix formats, applying the original, unscaled matrix
988:    will be slightly more expensive

990:    Level: Developer            

992: .seealso: MatScaleSystem(), MatUnScaleSystem()
993: @*/
994: PetscErrorCode  MatUseScaledForm(Mat mat,PetscBool  scaled)
995: {

1002:   MatPreallocated(mat);
1003:   if (mat->ops->usescaledform) {
1004:     (*mat->ops->usescaledform)(mat,scaled);
1005:   }
1006:   return(0);
1007: }

1011: /*@
1012:    MatDestroy - Frees space taken by a matrix.

1014:    Collective on Mat

1016:    Input Parameter:
1017: .  A - the matrix

1019:    Level: beginner

1021: @*/
1022: PetscErrorCode  MatDestroy(Mat *A)
1023: {

1027:   if (!*A) return(0);
1029:   if (--((PetscObject)(*A))->refct > 0) {*A = PETSC_NULL; return(0);}

1031:   /* if memory was published with AMS then destroy it */
1032:   PetscObjectDepublish(*A);

1034:   if ((*A)->ops->destroy) {
1035:     (*(*A)->ops->destroy)(*A);
1036:   }

1038:   MatNullSpaceDestroy(&(*A)->nullsp);
1039:   PetscLayoutDestroy(&(*A)->rmap);
1040:   PetscLayoutDestroy(&(*A)->cmap);
1041:   PetscHeaderDestroy(A);
1042:   return(0);
1043: }

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

1052:    Not Collective

1054:    Input Parameters:
1055: +  mat - the matrix
1056: .  v - a logically two-dimensional array of values
1057: .  m, idxm - the number of rows and their global indices 
1058: .  n, idxn - the number of columns and their global indices
1059: -  addv - either ADD_VALUES or INSERT_VALUES, where
1060:    ADD_VALUES adds values to any existing entries, and
1061:    INSERT_VALUES replaces existing entries with new values

1063:    Notes:
1064:    By default the values, v, are row-oriented. See MatSetOption() for other options.

1066:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 
1067:    options cannot be mixed without intervening calls to the assembly
1068:    routines.

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

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

1078:    Efficiency Alert:
1079:    The routine MatSetValuesBlocked() may offer much better efficiency
1080:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1082:    Level: beginner

1084:    Concepts: matrices^putting entries in

1086: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1087:           InsertMode, INSERT_VALUES, ADD_VALUES
1088: @*/
1089: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1090: {

1096:   if (!m || !n) return(0); /* no values to insert */
1100:   MatPreallocated(mat);
1101:   if (mat->insertmode == NOT_SET_VALUES) {
1102:     mat->insertmode = addv;
1103:   }
1104: #if defined(PETSC_USE_DEBUG)
1105:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1106:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1107:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1108: #endif

1110:   if (mat->assembled) {
1111:     mat->was_assembled = PETSC_TRUE;
1112:     mat->assembled     = PETSC_FALSE;
1113:   }
1114:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1115:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1116:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1117: #if defined(PETSC_HAVE_CUSP)
1118:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1119:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1120:   }
1121: #endif
1122:   return(0);
1123: }


1128: /*@ 
1129:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1130:         values into a matrix

1132:    Not Collective

1134:    Input Parameters:
1135: +  mat - the matrix
1136: .  row - the (block) row to set
1137: -  v - a logically two-dimensional array of values

1139:    Notes:
1140:    By the values, v, are column-oriented (for the block version) and sorted

1142:    All the nonzeros in the row must be provided

1144:    The matrix must have previously had its column indices set

1146:    The row must belong to this process

1148:    Level: intermediate

1150:    Concepts: matrices^putting entries in

1152: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1153:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1154: @*/
1155: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1156: {

1163:   MatSetValuesRow(mat, mat->rmap->mapping->indices[row],v);
1164: #if defined(PETSC_HAVE_CUSP)
1165:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1166:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1167:   }
1168: #endif
1169:   return(0);
1170: }

1174: /*@ 
1175:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1176:         values into a matrix

1178:    Not Collective

1180:    Input Parameters:
1181: +  mat - the matrix
1182: .  row - the (block) row to set
1183: -  v - a logically two-dimensional array of values

1185:    Notes:
1186:    The values, v, are column-oriented for the block version.

1188:    All the nonzeros in the row must be provided

1190:    THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.

1192:    The row must belong to this process

1194:    Level: advanced

1196:    Concepts: matrices^putting entries in

1198: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1199:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1200: @*/
1201: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1202: {

1209: #if defined(PETSC_USE_DEBUG)
1210:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1211:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1212: #endif
1213:   mat->insertmode = INSERT_VALUES;

1215:   if (mat->assembled) {
1216:     mat->was_assembled = PETSC_TRUE;
1217:     mat->assembled     = PETSC_FALSE;
1218:   }
1219:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1220:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1221:   (*mat->ops->setvaluesrow)(mat,row,v);
1222:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1223: #if defined(PETSC_HAVE_CUSP)
1224:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1225:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1226:   }
1227: #endif
1228:   return(0);
1229: }

1233: /*@
1234:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1235:      Using structured grid indexing

1237:    Not Collective

1239:    Input Parameters:
1240: +  mat - the matrix
1241: .  m - number of rows being entered
1242: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1243: .  n - number of columns being entered
1244: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 
1245: .  v - a logically two-dimensional array of values
1246: -  addv - either ADD_VALUES or INSERT_VALUES, where
1247:    ADD_VALUES adds values to any existing entries, and
1248:    INSERT_VALUES replaces existing entries with new values

1250:    Notes:
1251:    By default the values, v, are row-oriented.  See MatSetOption() for other options.

1253:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 
1254:    options cannot be mixed without intervening calls to the assembly
1255:    routines.

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

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

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

1264:    In order to use this routine you must either obtain the matrix with DMGetMatrix()
1265:    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.

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

1273:    In Fortran idxm and idxn should be declared as
1274: $     MatStencil idxm(4,m),idxn(4,n)
1275:    and the values inserted using
1276: $    idxm(MatStencil_i,1) = i
1277: $    idxm(MatStencil_j,1) = j
1278: $    idxm(MatStencil_k,1) = k
1279: $    idxm(MatStencil_c,1) = c
1280:    etc
1281:  
1282:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 
1283:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1284:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1285:    DMDA_BOUNDARY_PERIODIC boundary type.

1287:    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
1288:    a single value per point) you can skip filling those indices.

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

1293:    Efficiency Alert:
1294:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1295:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1297:    Level: beginner

1299:    Concepts: matrices^putting entries in

1301: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1302:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMGetMatrix(), DMDAVecGetArray(), MatStencil
1303: @*/
1304: PetscErrorCode  MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1305: {
1307:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1308:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1309:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1319:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1320:     jdxm = buf; jdxn = buf+m;
1321:   } else {
1322:     PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1323:     jdxm = bufm; jdxn = bufn;
1324:   }
1325:   for (i=0; i<m; i++) {
1326:     for (j=0; j<3-sdim; j++) dxm++;
1327:     tmp = *dxm++ - starts[0];
1328:     for (j=0; j<dim-1; j++) {
1329:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1330:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1331:     }
1332:     if (mat->stencil.noc) dxm++;
1333:     jdxm[i] = tmp;
1334:   }
1335:   for (i=0; i<n; i++) {
1336:     for (j=0; j<3-sdim; j++) dxn++;
1337:     tmp = *dxn++ - starts[0];
1338:     for (j=0; j<dim-1; j++) {
1339:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1340:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1341:     }
1342:     if (mat->stencil.noc) dxn++;
1343:     jdxn[i] = tmp;
1344:   }
1345:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1346:   PetscFree2(bufm,bufn);
1347:   return(0);
1348: }

1352: /*@C 
1353:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1354:      Using structured grid indexing

1356:    Not Collective

1358:    Input Parameters:
1359: +  mat - the matrix
1360: .  m - number of rows being entered
1361: .  idxm - grid coordinates for matrix rows being entered
1362: .  n - number of columns being entered
1363: .  idxn - grid coordinates for matrix columns being entered 
1364: .  v - a logically two-dimensional array of values
1365: -  addv - either ADD_VALUES or INSERT_VALUES, where
1366:    ADD_VALUES adds values to any existing entries, and
1367:    INSERT_VALUES replaces existing entries with new values

1369:    Notes:
1370:    By default the values, v, are row-oriented and unsorted.
1371:    See MatSetOption() for other options.

1373:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 
1374:    options cannot be mixed without intervening calls to the assembly
1375:    routines.

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

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

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

1384:    In order to use this routine you must either obtain the matrix with DMGetMatrix()
1385:    or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.

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

1393:    In Fortran idxm and idxn should be declared as
1394: $     MatStencil idxm(4,m),idxn(4,n)
1395:    and the values inserted using
1396: $    idxm(MatStencil_i,1) = i
1397: $    idxm(MatStencil_j,1) = j
1398: $    idxm(MatStencil_k,1) = k
1399:    etc

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

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

1409:    Level: beginner

1411:    Concepts: matrices^putting entries in

1413: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1414:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMGetMatrix(), DMDAVecGetArray(), MatStencil,
1415:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1416: @*/
1417: PetscErrorCode  MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1418: {
1420:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1421:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1422:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1432:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1433:     jdxm = buf; jdxn = buf+m;
1434:   } else {
1435:     PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1436:     jdxm = bufm; jdxn = bufn;
1437:   }
1438:   for (i=0; i<m; i++) {
1439:     for (j=0; j<3-sdim; j++) dxm++;
1440:     tmp = *dxm++ - starts[0];
1441:     for (j=0; j<sdim-1; j++) {
1442:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1443:       else                                      tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1444:     }
1445:     dxm++;
1446:     jdxm[i] = tmp;
1447:   }
1448:   for (i=0; i<n; i++) {
1449:     for (j=0; j<3-sdim; j++) dxn++;
1450:     tmp = *dxn++ - starts[0];
1451:     for (j=0; j<sdim-1; j++) {
1452:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1453:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1454:     }
1455:     dxn++;
1456:     jdxn[i] = tmp;
1457:   }
1458:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1459:   PetscFree2(bufm,bufn);
1460: #if defined(PETSC_HAVE_CUSP)
1461:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1462:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1463:   }
1464: #endif
1465:   return(0);
1466: }

1470: /*@ 
1471:    MatSetStencil - Sets the grid information for setting values into a matrix via
1472:         MatSetValuesStencil()

1474:    Not Collective

1476:    Input Parameters:
1477: +  mat - the matrix
1478: .  dim - dimension of the grid 1, 2, or 3
1479: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1480: .  starts - starting point of ghost nodes on your processor in x, y, and z direction 
1481: -  dof - number of degrees of freedom per node


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

1487:    For matrices generated with DMGetMatrix() this routine is automatically called and so not needed by the
1488:    user.
1489:    
1490:    Level: beginner

1492:    Concepts: matrices^putting entries in

1494: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1495:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1496: @*/
1497: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1498: {
1499:   PetscInt i;


1506:   mat->stencil.dim = dim + (dof > 1);
1507:   for (i=0; i<dim; i++) {
1508:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1509:     mat->stencil.starts[i] = starts[dim-i-1];
1510:   }
1511:   mat->stencil.dims[dim]   = dof;
1512:   mat->stencil.starts[dim] = 0;
1513:   mat->stencil.noc         = (PetscBool)(dof == 1);
1514:   return(0);
1515: }

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

1522:    Not Collective

1524:    Input Parameters:
1525: +  mat - the matrix
1526: .  v - a logically two-dimensional array of values
1527: .  m, idxm - the number of block rows and their global block indices 
1528: .  n, idxn - the number of block columns and their global block indices
1529: -  addv - either ADD_VALUES or INSERT_VALUES, where
1530:    ADD_VALUES adds values to any existing entries, and
1531:    INSERT_VALUES replaces existing entries with new values

1533:    Notes:
1534:    The m and n count the NUMBER of blocks in the row direction and column direction,
1535:    NOT the total number of rows/columns; for example, if the block size is 2 and 
1536:    you are passing in values for rows 2,3,4,5  then m would be 2 (not 4).
1537:    The values in idxm would be 1 2; that is the first index for each block divided by 
1538:    the block size.

1540:    Note that you must call MatSetBlockSize() when constructing this matrix (after
1541:    preallocating it).

1543:    By default the values, v, are row-oriented, so the layout of 
1544:    v is the same as for MatSetValues(). See MatSetOption() for other options.

1546:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
1547:    options cannot be mixed without intervening calls to the assembly
1548:    routines.

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

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

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

1564:    Example:
1565: $   Suppose m=n=2 and block size(bs) = 2 The array is 
1566: $
1567: $   1  2  | 3  4
1568: $   5  6  | 7  8
1569: $   - - - | - - -
1570: $   9  10 | 11 12
1571: $   13 14 | 15 16
1572: $
1573: $   v[] should be passed in like
1574: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1575: $
1576: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1577: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1579:    Level: intermediate

1581:    Concepts: matrices^putting entries in blocked

1583: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1584: @*/
1585: PetscErrorCode  MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1586: {

1592:   if (!m || !n) return(0); /* no values to insert */
1596:   MatPreallocated(mat);
1597:   if (mat->insertmode == NOT_SET_VALUES) {
1598:     mat->insertmode = addv;
1599:   }
1600: #if defined(PETSC_USE_DEBUG)
1601:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1602:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1603:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1604: #endif

1606:   if (mat->assembled) {
1607:     mat->was_assembled = PETSC_TRUE;
1608:     mat->assembled     = PETSC_FALSE;
1609:   }
1610:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1611:   if (mat->ops->setvaluesblocked) {
1612:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1613:   } else {
1614:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1615:     PetscInt i,j,bs=mat->rmap->bs;
1616:     if ((m+n)*bs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1617:       iidxm = buf; iidxn = buf + m*bs;
1618:     } else {
1619:       PetscMalloc2(m*bs,PetscInt,&bufr,n*bs,PetscInt,&bufc);
1620:       iidxm = bufr; iidxn = bufc;
1621:     }
1622:     for (i=0; i<m; i++)
1623:       for (j=0; j<bs; j++)
1624:         iidxm[i*bs+j] = bs*idxm[i] + j;
1625:     for (i=0; i<n; i++)
1626:       for (j=0; j<bs; j++)
1627:         iidxn[i*bs+j] = bs*idxn[i] + j;
1628:     MatSetValues(mat,m*bs,iidxm,n*bs,iidxn,v,addv);
1629:     PetscFree2(bufr,bufc);
1630:   }
1631:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1632: #if defined(PETSC_HAVE_CUSP)
1633:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1634:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1635:   }
1636: #endif
1637:   return(0);
1638: }

1642: /*@ 
1643:    MatGetValues - Gets a block of values from a matrix.

1645:    Not Collective; currently only returns a local block

1647:    Input Parameters:
1648: +  mat - the matrix
1649: .  v - a logically two-dimensional array for storing the values
1650: .  m, idxm - the number of rows and their global indices 
1651: -  n, idxn - the number of columns and their global indices

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

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

1661:    MatGetValues() requires that the matrix has been assembled
1662:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1663:    MatSetValues() and MatGetValues() CANNOT be made in succession
1664:    without intermediate matrix assembly.

1666:    Negative row or column indices will be ignored and those locations in v[] will be 
1667:    left unchanged.

1669:    Level: advanced

1671:    Concepts: matrices^accessing values

1673: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1674: @*/
1675: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1676: {

1682:   if (!m || !n) return(0);
1686:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1687:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1688:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1689:   MatPreallocated(mat);

1691:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1692:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1693:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1694:   return(0);
1695: }

1699: /*@
1700:   MatSetValuesBatch - Inserts many blocks of values into a matrix at once. The blocks must all be square and the same size.

1702:   Not Collective

1704:   Input Parameters:
1705: + mat - the matrix
1706: . nb - the number of blocks
1707: . bs - the number of rows (and columns) in each block
1708: . rows - a concatenation of the rows for each block
1709: - v - a concatenation of logically two-dimensional arrays of values

1711:   Notes:
1712:   In the future, we may extend this routine to handle rectangular blocks, and additive mode.

1714:   Level: advanced

1716:   Concepts: matrices^putting entries in

1718: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1719:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1720: @*/
1721: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1722: {

1730: #if defined(PETSC_USE_DEBUG)
1731:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1732: #endif

1734:   if (mat->ops->setvaluesbatch) {
1735:     PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1736:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1737:     PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1738:   } else {
1739:     PetscInt b;
1740:     for(b = 0; b < nb; ++b) {
1741:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1742:     }
1743:   }
1744:   return(0);
1745: }

1749: /*@
1750:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1751:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1752:    using a local (per-processor) numbering.

1754:    Not Collective

1756:    Input Parameters:
1757: +  x - the matrix
1758: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1759:              or ISLocalToGlobalMappingCreateIS()
1760: - cmapping - column mapping

1762:    Level: intermediate

1764:    Concepts: matrices^local to global mapping
1765:    Concepts: local to global mapping^for matrices

1767: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1768: @*/
1769: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1770: {
1777:   MatPreallocated(x);

1779:   if (x->ops->setlocaltoglobalmapping) {
1780:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1781:   } else {
1782:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1783:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1784:   }
1785:   return(0);
1786: }

1790: /*@
1791:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1792:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1793:    entries using a local (per-processor) numbering.

1795:    Not Collective

1797:    Input Parameters:
1798: +  x - the matrix
1799: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1800:              ISLocalToGlobalMappingCreateIS()
1801: - cmapping - column mapping

1803:    Level: intermediate

1805:    Concepts: matrices^local to global mapping blocked
1806:    Concepts: local to global mapping^for matrices, blocked

1808: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1809:            MatSetValuesBlocked(), MatSetValuesLocal()
1810: @*/
1811: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1812: {
1819:   MatPreallocated(x);

1821:   PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1822:   PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1823:   return(0);
1824: }

1828: /*@
1829:    MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()

1831:    Not Collective

1833:    Input Parameters:
1834: .  A - the matrix

1836:    Output Parameters:
1837: + rmapping - row mapping
1838: - cmapping - column mapping

1840:    Level: advanced

1842:    Concepts: matrices^local to global mapping
1843:    Concepts: local to global mapping^for matrices

1845: .seealso:  MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1846: @*/
1847: PetscErrorCode  MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1848: {
1854:   if (rmapping) *rmapping = A->rmap->mapping;
1855:   if (cmapping) *cmapping = A->cmap->mapping;
1856:   return(0);
1857: }

1861: /*@
1862:    MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()

1864:    Not Collective

1866:    Input Parameters:
1867: .  A - the matrix

1869:    Output Parameters:
1870: + rmapping - row mapping
1871: - cmapping - column mapping

1873:    Level: advanced

1875:    Concepts: matrices^local to global mapping blocked
1876:    Concepts: local to global mapping^for matrices, blocked

1878: .seealso:  MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1879: @*/
1880: PetscErrorCode  MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1881: {
1887:   if (rmapping) *rmapping = A->rmap->bmapping;
1888:   if (cmapping) *cmapping = A->cmap->bmapping;
1889:   return(0);
1890: }

1894: /*@
1895:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1896:    using a local ordering of the nodes. 

1898:    Not Collective

1900:    Input Parameters:
1901: +  x - the matrix
1902: .  nrow, irow - number of rows and their local indices
1903: .  ncol, icol - number of columns and their local indices
1904: .  y -  a logically two-dimensional array of values
1905: -  addv - either INSERT_VALUES or ADD_VALUES, where
1906:    ADD_VALUES adds values to any existing entries, and
1907:    INSERT_VALUES replaces existing entries with new values

1909:    Notes:
1910:    Before calling MatSetValuesLocal(), the user must first set the
1911:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

1913:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
1914:    options cannot be mixed without intervening calls to the assembly
1915:    routines.

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

1920:    Level: intermediate

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

1924: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1925:            MatSetValueLocal()
1926: @*/
1927: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1928: {

1934:   if (!nrow || !ncol) return(0); /* no values to insert */
1938:   MatPreallocated(mat);
1939:   if (mat->insertmode == NOT_SET_VALUES) {
1940:     mat->insertmode = addv;
1941:   }
1942: #if defined(PETSC_USE_DEBUG)
1943:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1944:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1945:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1946: #endif

1948:   if (mat->assembled) {
1949:     mat->was_assembled = PETSC_TRUE;
1950:     mat->assembled     = PETSC_FALSE;
1951:   }
1952:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1953:   if (mat->ops->setvalueslocal) {
1954:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1955:   } else {
1956:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1957:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1958:       irowm = buf; icolm = buf+nrow;
1959:     } else {
1960:       PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1961:       irowm = bufr; icolm = bufc;
1962:     }
1963:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1964:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1965:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1966:     PetscFree2(bufr,bufc);
1967:   }
1968:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1969: #if defined(PETSC_HAVE_CUSP)
1970:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1971:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1972:   }
1973: #endif
1974:   return(0);
1975: }

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

1983:    Not Collective

1985:    Input Parameters:
1986: +  x - the matrix
1987: .  nrow, irow - number of rows and their local indices
1988: .  ncol, icol - number of columns and their local indices
1989: .  y -  a logically two-dimensional array of values
1990: -  addv - either INSERT_VALUES or ADD_VALUES, where
1991:    ADD_VALUES adds values to any existing entries, and
1992:    INSERT_VALUES replaces existing entries with new values

1994:    Notes:
1995:    Before calling MatSetValuesBlockedLocal(), the user must first set the
1996:    block size using MatSetBlockSize(), and the local-to-global mapping by
1997:    calling MatSetLocalToGlobalMappingBlock(), where the mapping MUST be
1998:    set for matrix blocks, not for matrix elements.

2000:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
2001:    options cannot be mixed without intervening calls to the assembly
2002:    routines.

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

2007:    Level: intermediate

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

2011: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
2012:            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
2013: @*/
2014: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2015: {

2021:   if (!nrow || !ncol) return(0); /* no values to insert */
2025:   MatPreallocated(mat);
2026:   if (mat->insertmode == NOT_SET_VALUES) {
2027:     mat->insertmode = addv;
2028:   }
2029: #if defined(PETSC_USE_DEBUG)
2030:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2031:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2032:   if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2033: #endif

2035:   if (mat->assembled) {
2036:     mat->was_assembled = PETSC_TRUE;
2037:     mat->assembled     = PETSC_FALSE;
2038:   }
2039:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2040:   if (mat->ops->setvaluesblockedlocal) {
2041:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2042:   } else {
2043:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2044:     if (mat->rmap->bmapping && mat->cmap->bmapping) {
2045:       if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2046:         irowm = buf; icolm = buf + nrow;
2047:       } else {
2048:         PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
2049:         irowm = bufr; icolm = bufc;
2050:       }
2051:       ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
2052:       ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
2053:       MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2054:       PetscFree2(bufr,bufc);
2055:     } else {
2056:       PetscInt i,j,bs=mat->rmap->bs;
2057:       if ((nrow+ncol)*bs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2058:         irowm = buf; icolm = buf + nrow;
2059:       } else {
2060:         PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*bs,PetscInt,&bufc);
2061:         irowm = bufr; icolm = bufc;
2062:       }
2063:       for (i=0; i<nrow; i++)
2064:         for (j=0; j<bs; j++)
2065:           irowm[i*bs+j] = irow[i]*bs+j;
2066:       for (i=0; i<ncol; i++)
2067:         for (j=0; j<bs; j++)
2068:           icolm[i*bs+j] = icol[i]*bs+j;
2069:       MatSetValuesLocal(mat,nrow*bs,irowm,ncol*bs,icolm,y,addv);
2070:       PetscFree2(bufr,bufc);
2071:     }
2072:   }
2073:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2074: #if defined(PETSC_HAVE_CUSP)
2075:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2076:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2077:   }
2078: #endif
2079:   return(0);
2080: }

2084: /*@
2085:    MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal

2087:    Collective on Mat and Vec

2089:    Input Parameters:
2090: +  mat - the matrix
2091: -  x   - the vector to be multiplied

2093:    Output Parameters:
2094: .  y - the result

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

2100:    Level: developer

2102:    Concepts: matrix-vector product

2104: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2105: @*/
2106: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2107: {


2116:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2117:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2118:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2119:   MatPreallocated(mat);

2121:   if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2122:   (*mat->ops->multdiagonalblock)(mat,x,y);
2123:   PetscObjectStateIncrease((PetscObject)y);
2124:   return(0);
2125: }

2127: /* --------------------------------------------------------*/
2130: /*@
2131:    MatMult - Computes the matrix-vector product, y = Ax.

2133:    Neighbor-wise Collective on Mat and Vec

2135:    Input Parameters:
2136: +  mat - the matrix
2137: -  x   - the vector to be multiplied

2139:    Output Parameters:
2140: .  y - the result

2142:    Notes:
2143:    The vectors x and y cannot be the same.  I.e., one cannot
2144:    call MatMult(A,y,y).

2146:    Level: beginner

2148:    Concepts: matrix-vector product

2150: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2151: @*/
2152: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
2153: {

2161:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2162:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2163:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2164: #ifndef PETSC_HAVE_CONSTRAINTS
2165:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2166:   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2167:   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
2168: #endif
2169:   MatPreallocated(mat);

2171:   if (mat->nullsp) {
2172:     MatNullSpaceRemove(mat->nullsp,x,&x);
2173:   }

2175:   if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2176:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2177:   (*mat->ops->mult)(mat,x,y);
2178:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);

2180:   if (mat->nullsp) {
2181:     MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
2182:   }
2183:   PetscObjectStateIncrease((PetscObject)y);
2184:   return(0);
2185: }

2189: /*@
2190:    MatMultTranspose - Computes matrix transpose times a vector.

2192:    Neighbor-wise Collective on Mat and Vec

2194:    Input Parameters:
2195: +  mat - the matrix
2196: -  x   - the vector to be multilplied

2198:    Output Parameters:
2199: .  y - the result

2201:    Notes:
2202:    The vectors x and y cannot be the same.  I.e., one cannot
2203:    call MatMultTranspose(A,y,y).

2205:    For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 
2206:    use MatMultHermitianTranspose()

2208:    Level: beginner

2210:    Concepts: matrix vector product^transpose

2212: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2213: @*/
2214: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2215: {


2224:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2225:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2226:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2227: #ifndef PETSC_HAVE_CONSTRAINTS
2228:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2229:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2230: #endif
2231:   MatPreallocated(mat);

2233:   if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2234:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2235:   (*mat->ops->multtranspose)(mat,x,y);
2236:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2237:   PetscObjectStateIncrease((PetscObject)y);
2238:   return(0);
2239: }

2243: /*@
2244:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2246:    Neighbor-wise Collective on Mat and Vec

2248:    Input Parameters:
2249: +  mat - the matrix
2250: -  x   - the vector to be multilplied

2252:    Output Parameters:
2253: .  y - the result

2255:    Notes:
2256:    The vectors x and y cannot be the same.  I.e., one cannot
2257:    call MatMultHermitianTranspose(A,y,y).

2259:    Also called the conjugate transpose, complex conjugate transpose, or adjoint. 

2261:    For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.

2263:    Level: beginner

2265:    Concepts: matrix vector product^transpose

2267: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2268: @*/
2269: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2270: {


2279:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2280:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2281:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2282: #ifndef PETSC_HAVE_CONSTRAINTS
2283:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2284:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2285: #endif
2286:   MatPreallocated(mat);

2288:   if (!mat->ops->multhermitiantranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2289:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2290:   (*mat->ops->multhermitiantranspose)(mat,x,y);
2291:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2292:   PetscObjectStateIncrease((PetscObject)y);
2293:   return(0);
2294: }

2298: /*@
2299:     MatMultAdd -  Computes v3 = v2 + A * v1.

2301:     Neighbor-wise Collective on Mat and Vec

2303:     Input Parameters:
2304: +   mat - the matrix
2305: -   v1, v2 - the vectors

2307:     Output Parameters:
2308: .   v3 - the result

2310:     Notes:
2311:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2312:     call MatMultAdd(A,v1,v2,v1).

2314:     Level: beginner

2316:     Concepts: matrix vector product^addition

2318: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2319: @*/
2320: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2321: {


2331:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2332:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2333:   if (mat->cmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2334:   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2335:      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2336:   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2337:   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2338:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2339:   MatPreallocated(mat);

2341:   if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2342:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2343:   (*mat->ops->multadd)(mat,v1,v2,v3);
2344:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2345:   PetscObjectStateIncrease((PetscObject)v3);
2346:   return(0);
2347: }

2351: /*@
2352:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2354:    Neighbor-wise Collective on Mat and Vec

2356:    Input Parameters:
2357: +  mat - the matrix
2358: -  v1, v2 - the vectors

2360:    Output Parameters:
2361: .  v3 - the result

2363:    Notes:
2364:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2365:    call MatMultTransposeAdd(A,v1,v2,v1).

2367:    Level: beginner

2369:    Concepts: matrix vector product^transpose and addition

2371: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2372: @*/
2373: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2374: {


2384:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2385:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2386:   if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2387:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2388:   if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2389:   if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2390:   if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2391:   MatPreallocated(mat);

2393:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2394:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2395:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2396:   PetscObjectStateIncrease((PetscObject)v3);
2397:   return(0);
2398: }

2402: /*@
2403:    MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.

2405:    Neighbor-wise Collective on Mat and Vec

2407:    Input Parameters:
2408: +  mat - the matrix
2409: -  v1, v2 - the vectors

2411:    Output Parameters:
2412: .  v3 - the result

2414:    Notes:
2415:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2416:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2418:    Level: beginner

2420:    Concepts: matrix vector product^transpose and addition

2422: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2423: @*/
2424: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2425: {


2435:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2436:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2437:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2438:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2439:   if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2440:   if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2441:   if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2442:   MatPreallocated(mat);

2444:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2445:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2446:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2447:   PetscObjectStateIncrease((PetscObject)v3);
2448:   return(0);
2449: }

2453: /*@
2454:    MatMultConstrained - The inner multiplication routine for a
2455:    constrained matrix P^T A P.

2457:    Neighbor-wise Collective on Mat and Vec

2459:    Input Parameters:
2460: +  mat - the matrix
2461: -  x   - the vector to be multilplied

2463:    Output Parameters:
2464: .  y - the result

2466:    Notes:
2467:    The vectors x and y cannot be the same.  I.e., one cannot
2468:    call MatMult(A,y,y).

2470:    Level: beginner

2472: .keywords: matrix, multiply, matrix-vector product, constraint
2473: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2474: @*/
2475: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2476: {

2483:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2484:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2485:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2486:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2487:   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2488:   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);

2490:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2491:   (*mat->ops->multconstrained)(mat,x,y);
2492:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2493:   PetscObjectStateIncrease((PetscObject)y);

2495:   return(0);
2496: }

2500: /*@
2501:    MatMultTransposeConstrained - The inner multiplication routine for a
2502:    constrained matrix P^T A^T P.

2504:    Neighbor-wise Collective on Mat and Vec

2506:    Input Parameters:
2507: +  mat - the matrix
2508: -  x   - the vector to be multilplied

2510:    Output Parameters:
2511: .  y - the result

2513:    Notes:
2514:    The vectors x and y cannot be the same.  I.e., one cannot
2515:    call MatMult(A,y,y).

2517:    Level: beginner

2519: .keywords: matrix, multiply, matrix-vector product, constraint
2520: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2521: @*/
2522: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2523: {

2530:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2531:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2532:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2533:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2534:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);

2536:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2537:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2538:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2539:   PetscObjectStateIncrease((PetscObject)y);

2541:   return(0);
2542: }

2546: /*@C
2547:    MatGetFactorType - gets the type of factorization it is

2549:    Note Collective
2550:    as the flag

2552:    Input Parameters:
2553: .  mat - the matrix

2555:    Output Parameters:
2556: .  t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT

2558:     Level: intermediate

2560: .seealso:    MatFactorType, MatGetFactor()
2561: @*/
2562: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2563: {
2567:   *t = mat->factortype;
2568:   return(0);
2569: }

2571: /* ------------------------------------------------------------*/
2574: /*@C
2575:    MatGetInfo - Returns information about matrix storage (number of
2576:    nonzeros, memory, etc.).

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

2580:    Input Parameters:
2581: .  mat - the matrix

2583:    Output Parameters:
2584: +  flag - flag indicating the type of parameters to be returned
2585:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2586:    MAT_GLOBAL_SUM - sum over all processors)
2587: -  info - matrix information context

2589:    Notes:
2590:    The MatInfo context contains a variety of matrix data, including
2591:    number of nonzeros allocated and used, number of mallocs during
2592:    matrix assembly, etc.  Additional information for factored matrices
2593:    is provided (such as the fill ratio, number of mallocs during
2594:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2595:    when using the runtime options 
2596: $       -info -mat_view_info

2598:    Example for C/C++ Users:
2599:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2600:    data within the MatInfo context.  For example, 
2601: .vb
2602:       MatInfo info;
2603:       Mat     A;
2604:       double  mal, nz_a, nz_u;

2606:       MatGetInfo(A,MAT_LOCAL,&info);
2607:       mal  = info.mallocs;
2608:       nz_a = info.nz_allocated;
2609: .ve

2611:    Example for Fortran Users:
2612:    Fortran users should declare info as a double precision
2613:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2614:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2615:    a complete list of parameter names.
2616: .vb
2617:       double  precision info(MAT_INFO_SIZE)
2618:       double  precision mal, nz_a
2619:       Mat     A
2620:       integer ierr

2622:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2623:       mal = info(MAT_INFO_MALLOCS)
2624:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2625: .ve

2627:     Level: intermediate

2629:     Concepts: matrices^getting information on
2630:     
2631:     Developer Note: fortran interface is not autogenerated as the f90
2632:     interface defintion cannot be generated correctly [due to MatInfo]
2633:  
2634: @*/
2635: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2636: {

2643:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2644:   MatPreallocated(mat);
2645:   (*mat->ops->getinfo)(mat,flag,info);
2646:   return(0);
2647: }

2649: /* ----------------------------------------------------------*/

2653: /*@C
2654:    MatLUFactor - Performs in-place LU factorization of matrix.

2656:    Collective on Mat

2658:    Input Parameters:
2659: +  mat - the matrix
2660: .  row - row permutation
2661: .  col - column permutation
2662: -  info - options for factorization, includes 
2663: $          fill - expected fill as ratio of original fill.
2664: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2665: $                   Run with the option -info to determine an optimal value to use

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

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

2675:    Level: developer

2677:    Concepts: matrices^LU factorization

2679: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2680:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo

2682:     Developer Note: fortran interface is not autogenerated as the f90
2683:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2685: @*/
2686: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2687: {

2696:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2697:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2698:   if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2699:   MatPreallocated(mat);

2701:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2702:   (*mat->ops->lufactor)(mat,row,col,info);
2703:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2704:   PetscObjectStateIncrease((PetscObject)mat);
2705:   return(0);
2706: }

2710: /*@C
2711:    MatILUFactor - Performs in-place ILU factorization of matrix.

2713:    Collective on Mat

2715:    Input Parameters:
2716: +  mat - the matrix
2717: .  row - row permutation
2718: .  col - column permutation
2719: -  info - structure containing 
2720: $      levels - number of levels of fill.
2721: $      expected fill - as ratio of original fill.
2722: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2723:                 missing diagonal entries)

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

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

2733:    Level: developer

2735:    Concepts: matrices^ILU factorization

2737: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

2739:     Developer Note: fortran interface is not autogenerated as the f90
2740:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2742: @*/
2743: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2744: {

2753:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
2754:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2755:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2756:   if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2757:   MatPreallocated(mat);

2759:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2760:   (*mat->ops->ilufactor)(mat,row,col,info);
2761:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2762:   PetscObjectStateIncrease((PetscObject)mat);
2763:   return(0);
2764: }

2768: /*@C
2769:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2770:    Call this routine before calling MatLUFactorNumeric().

2772:    Collective on Mat

2774:    Input Parameters:
2775: +  fact - the factor matrix obtained with MatGetFactor()
2776: .  mat - the matrix
2777: .  row, col - row and column permutations
2778: -  info - options for factorization, includes 
2779: $          fill - expected fill as ratio of original fill.
2780: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2781: $                   Run with the option -info to determine an optimal value to use


2784:    Notes:
2785:    See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2786:    choosing the fill factor for better efficiency.

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

2792:    Level: developer

2794:    Concepts: matrices^LU symbolic factorization

2796: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

2798:     Developer Note: fortran interface is not autogenerated as the f90
2799:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2801: @*/
2802: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2803: {

2813:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2814:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2815:   if (!(fact)->ops->lufactorsymbolic) {
2816:     const MatSolverPackage spackage;
2817:     MatFactorGetSolverPackage(fact,&spackage);
2818:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2819:   }
2820:   MatPreallocated(mat);

2822:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2823:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2824:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2825:   PetscObjectStateIncrease((PetscObject)fact);
2826:   return(0);
2827: }

2831: /*@C
2832:    MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2833:    Call this routine after first calling MatLUFactorSymbolic().

2835:    Collective on Mat

2837:    Input Parameters:
2838: +  fact - the factor matrix obtained with MatGetFactor()
2839: .  mat - the matrix
2840: -  info - options for factorization

2842:    Notes:
2843:    See MatLUFactor() for in-place factorization.  See 
2844:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

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

2850:    Level: developer

2852:    Concepts: matrices^LU numeric factorization

2854: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()

2856:     Developer Note: fortran interface is not autogenerated as the f90
2857:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2859: @*/
2860: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2861: {

2869:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2870:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2871:     SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2872:   }
2873:   if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2874:   MatPreallocated(mat);
2875:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2876:   (fact->ops->lufactornumeric)(fact,mat,info);
2877:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

2879:   MatView_Private(fact);
2880:   PetscObjectStateIncrease((PetscObject)fact);
2881:   return(0);
2882: }

2886: /*@C
2887:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2888:    symmetric matrix. 

2890:    Collective on Mat

2892:    Input Parameters:
2893: +  mat - the matrix
2894: .  perm - row and column permutations
2895: -  f - expected fill as ratio of original fill

2897:    Notes:
2898:    See MatLUFactor() for the nonsymmetric case.  See also
2899:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2905:    Level: developer

2907:    Concepts: matrices^Cholesky factorization

2909: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2910:           MatGetOrdering()

2912:     Developer Note: fortran interface is not autogenerated as the f90
2913:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2915: @*/
2916: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2917: {

2925:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2926:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2927:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2928:   if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2929:   MatPreallocated(mat);

2931:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2932:   (*mat->ops->choleskyfactor)(mat,perm,info);
2933:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2934:   PetscObjectStateIncrease((PetscObject)mat);
2935:   return(0);
2936: }

2940: /*@C
2941:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2942:    of a symmetric matrix. 

2944:    Collective on Mat

2946:    Input Parameters:
2947: +  fact - the factor matrix obtained with MatGetFactor()
2948: .  mat - the matrix
2949: .  perm - row and column permutations
2950: -  info - options for factorization, includes 
2951: $          fill - expected fill as ratio of original fill.
2952: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2953: $                   Run with the option -info to determine an optimal value to use

2955:    Notes:
2956:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2957:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2963:    Level: developer

2965:    Concepts: matrices^Cholesky symbolic factorization

2967: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2968:           MatGetOrdering()

2970:     Developer Note: fortran interface is not autogenerated as the f90
2971:     interface defintion cannot be generated correctly [due to MatFactorInfo]

2973: @*/
2974: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2975: {

2984:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2985:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2986:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2987:   if (!(fact)->ops->choleskyfactorsymbolic) {
2988:     const MatSolverPackage spackage;
2989:     MatFactorGetSolverPackage(fact,&spackage);
2990:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
2991:   }
2992:   MatPreallocated(mat);

2994:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2995:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2996:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2997:   PetscObjectStateIncrease((PetscObject)fact);
2998:   return(0);
2999: }

3003: /*@C
3004:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3005:    of a symmetric matrix. Call this routine after first calling
3006:    MatCholeskyFactorSymbolic().

3008:    Collective on Mat

3010:    Input Parameters:
3011: +  fact - the factor matrix obtained with MatGetFactor()
3012: .  mat - the initial matrix
3013: .  info - options for factorization
3014: -  fact - the symbolic factor of mat


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

3022:    Level: developer

3024:    Concepts: matrices^Cholesky numeric factorization

3026: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()

3028:     Developer Note: fortran interface is not autogenerated as the f90
3029:     interface defintion cannot be generated correctly [due to MatFactorInfo]

3031: @*/
3032: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3033: {

3041:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3042:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3043:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
3044:     SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
3045:   }
3046:   MatPreallocated(mat);

3048:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3049:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
3050:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

3052:   MatView_Private(fact);
3053:   PetscObjectStateIncrease((PetscObject)fact);
3054:   return(0);
3055: }

3057: /* ----------------------------------------------------------------*/
3060: /*@
3061:    MatSolve - Solves A x = b, given a factored matrix.

3063:    Neighbor-wise Collective on Mat and Vec

3065:    Input Parameters:
3066: +  mat - the factored matrix
3067: -  b - the right-hand-side vector

3069:    Output Parameter:
3070: .  x - the result vector

3072:    Notes:
3073:    The vectors b and x cannot be the same.  I.e., one cannot
3074:    call MatSolve(A,x,x).

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

3081:    Level: developer

3083:    Concepts: matrices^triangular solves

3085: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3086: @*/
3087: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3088: {

3098:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3099:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3100:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3101:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3102:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3103:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3104:   if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3105:   MatPreallocated(mat);

3107:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3108:   (*mat->ops->solve)(mat,b,x);
3109:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3110:   PetscObjectStateIncrease((PetscObject)x);
3111:   return(0);
3112: }

3116: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3117: {
3119:   Vec            b,x;
3120:   PetscInt       m,N,i;
3121:   PetscScalar    *bb,*xx;
3122:   PetscBool      flg;

3125:   PetscTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3126:   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3127:   PetscTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3128:   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3130:   MatGetArray(B,&bb);
3131:   MatGetArray(X,&xx);
3132:   MatGetLocalSize(B,&m,PETSC_NULL);  /* number local rows */
3133:   MatGetSize(B,PETSC_NULL,&N);       /* total columns in dense matrix */
3134:   MatGetVecs(A,&x,&b);
3135:   for (i=0; i<N; i++) {
3136:     VecPlaceArray(b,bb + i*m);
3137:     VecPlaceArray(x,xx + i*m);
3138:     MatSolve(A,b,x);
3139:     VecResetArray(x);
3140:     VecResetArray(b);
3141:   }
3142:   VecDestroy(&b);
3143:   VecDestroy(&x);
3144:   MatRestoreArray(B,&bb);
3145:   MatRestoreArray(X,&xx);
3146:   return(0);
3147: }

3151: /*@
3152:    MatMatSolve - Solves A X = B, given a factored matrix.

3154:    Neighbor-wise Collective on Mat 

3156:    Input Parameters:
3157: +  mat - the factored matrix
3158: -  B - the right-hand-side matrix  (dense matrix)

3160:    Output Parameter:
3161: .  X - the result matrix (dense matrix)

3163:    Notes:
3164:    The matrices b and x cannot be the same.  I.e., one cannot
3165:    call MatMatSolve(A,x,x).

3167:    Notes:
3168:    Most users should usually employ the simplified KSP interface for linear solvers
3169:    instead of working directly with matrix algebra routines such as this.
3170:    See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3171:    at a time.

3173:    Level: developer

3175:    Concepts: matrices^triangular solves

3177: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3178: @*/
3179: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3180: {

3190:   if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3191:   if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3192:   if (A->cmap->N != X->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3193:   if (A->rmap->N != B->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3194:   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
3195:   if (!A->rmap->N && !A->cmap->N) return(0);
3196:   MatPreallocated(A);

3198:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3199:   if (!A->ops->matsolve) {
3200:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3201:     MatMatSolve_Basic(A,B,X);
3202:   } else {
3203:     (*A->ops->matsolve)(A,B,X);
3204:   }
3205:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3206:   PetscObjectStateIncrease((PetscObject)X);
3207:   return(0);
3208: }


3213: /*@
3214:    MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3215:                             U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,

3217:    Neighbor-wise Collective on Mat and Vec

3219:    Input Parameters:
3220: +  mat - the factored matrix
3221: -  b - the right-hand-side vector

3223:    Output Parameter:
3224: .  x - the result vector

3226:    Notes:
3227:    MatSolve() should be used for most applications, as it performs
3228:    a forward solve followed by a backward solve.

3230:    The vectors b and x cannot be the same,  i.e., one cannot
3231:    call MatForwardSolve(A,x,x).

3233:    For matrix in seqsbaij format with block size larger than 1,
3234:    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3235:    MatForwardSolve() solves U^T*D y = b, and
3236:    MatBackwardSolve() solves U x = y.
3237:    Thus they do not provide a symmetric preconditioner.

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

3243:    Level: developer

3245:    Concepts: matrices^forward solves

3247: .seealso: MatSolve(), MatBackwardSolve()
3248: @*/
3249: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3250: {

3260:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3261:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3262:   if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3263:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3264:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3265:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3266:   MatPreallocated(mat);
3267:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3268:   (*mat->ops->forwardsolve)(mat,b,x);
3269:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3270:   PetscObjectStateIncrease((PetscObject)x);
3271:   return(0);
3272: }

3276: /*@
3277:    MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3278:                              D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,

3280:    Neighbor-wise Collective on Mat and Vec

3282:    Input Parameters:
3283: +  mat - the factored matrix
3284: -  b - the right-hand-side vector

3286:    Output Parameter:
3287: .  x - the result vector

3289:    Notes:
3290:    MatSolve() should be used for most applications, as it performs
3291:    a forward solve followed by a backward solve.

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

3296:    For matrix in seqsbaij format with block size larger than 1,
3297:    the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3298:    MatForwardSolve() solves U^T*D y = b, and
3299:    MatBackwardSolve() solves U x = y.
3300:    Thus they do not provide a symmetric preconditioner.

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

3306:    Level: developer

3308:    Concepts: matrices^backward solves

3310: .seealso: MatSolve(), MatForwardSolve()
3311: @*/
3312: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3313: {

3323:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3324:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3325:   if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3326:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3327:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3328:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3329:   MatPreallocated(mat);

3331:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3332:   (*mat->ops->backwardsolve)(mat,b,x);
3333:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3334:   PetscObjectStateIncrease((PetscObject)x);
3335:   return(0);
3336: }

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

3343:    Neighbor-wise Collective on Mat and Vec

3345:    Input Parameters:
3346: +  mat - the factored matrix
3347: .  b - the right-hand-side vector
3348: -  y - the vector to be added to 

3350:    Output Parameter:
3351: .  x - the result vector

3353:    Notes:
3354:    The vectors b and x cannot be the same.  I.e., one cannot
3355:    call MatSolveAdd(A,x,y,x).

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

3361:    Level: developer

3363:    Concepts: matrices^triangular solves

3365: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3366: @*/
3367: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3368: {
3369:   PetscScalar    one = 1.0;
3370:   Vec            tmp;

3382:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3383:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3384:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3385:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3386:   if (mat->rmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3387:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3388:   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3389:   MatPreallocated(mat);

3391:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3392:   if (mat->ops->solveadd)  {
3393:     (*mat->ops->solveadd)(mat,b,y,x);
3394:   } else {
3395:     /* do the solve then the add manually */
3396:     if (x != y) {
3397:       MatSolve(mat,b,x);
3398:       VecAXPY(x,one,y);
3399:     } else {
3400:       VecDuplicate(x,&tmp);
3401:       PetscLogObjectParent(mat,tmp);
3402:       VecCopy(x,tmp);
3403:       MatSolve(mat,b,x);
3404:       VecAXPY(x,one,tmp);
3405:       VecDestroy(&tmp);
3406:     }
3407:   }
3408:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3409:   PetscObjectStateIncrease((PetscObject)x);
3410:   return(0);
3411: }

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

3418:    Neighbor-wise Collective on Mat and Vec

3420:    Input Parameters:
3421: +  mat - the factored matrix
3422: -  b - the right-hand-side vector

3424:    Output Parameter:
3425: .  x - the result vector

3427:    Notes:
3428:    The vectors b and x cannot be the same.  I.e., one cannot
3429:    call MatSolveTranspose(A,x,x).

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

3435:    Level: developer

3437:    Concepts: matrices^triangular solves

3439: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3440: @*/
3441: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3442: {

3452:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3453:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3454:   if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3455:   if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3456:   if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3457:   MatPreallocated(mat);
3458:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3459:   (*mat->ops->solvetranspose)(mat,b,x);
3460:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3461:   PetscObjectStateIncrease((PetscObject)x);
3462:   return(0);
3463: }

3467: /*@
3468:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
3469:                       factored matrix. 

3471:    Neighbor-wise Collective on Mat and Vec

3473:    Input Parameters:
3474: +  mat - the factored matrix
3475: .  b - the right-hand-side vector
3476: -  y - the vector to be added to 

3478:    Output Parameter:
3479: .  x - the result vector

3481:    Notes:
3482:    The vectors b and x cannot be the same.  I.e., one cannot
3483:    call MatSolveTransposeAdd(A,x,y,x).

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

3489:    Level: developer

3491:    Concepts: matrices^triangular solves

3493: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3494: @*/
3495: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3496: {
3497:   PetscScalar    one = 1.0;
3499:   Vec            tmp;

3510:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3511:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3512:   if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3513:   if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3514:   if (mat->cmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3515:   if (x->map->n != y->map->n)   SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3516:   MatPreallocated(mat);

3518:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3519:   if (mat->ops->solvetransposeadd) {
3520:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3521:   } else {
3522:     /* do the solve then the add manually */
3523:     if (x != y) {
3524:       MatSolveTranspose(mat,b,x);
3525:       VecAXPY(x,one,y);
3526:     } else {
3527:       VecDuplicate(x,&tmp);
3528:       PetscLogObjectParent(mat,tmp);
3529:       VecCopy(x,tmp);
3530:       MatSolveTranspose(mat,b,x);
3531:       VecAXPY(x,one,tmp);
3532:       VecDestroy(&tmp);
3533:     }
3534:   }
3535:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3536:   PetscObjectStateIncrease((PetscObject)x);
3537:   return(0);
3538: }
3539: /* ----------------------------------------------------------------*/

3543: /*@
3544:    MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.

3546:    Neighbor-wise Collective on Mat and Vec

3548:    Input Parameters:
3549: +  mat - the matrix
3550: .  b - the right hand side
3551: .  omega - the relaxation factor
3552: .  flag - flag indicating the type of SOR (see below)
3553: .  shift -  diagonal shift
3554: .  its - the number of iterations
3555: -  lits - the number of local iterations 

3557:    Output Parameters:
3558: .  x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)

3560:    SOR Flags:
3561: .     SOR_FORWARD_SWEEP - forward SOR
3562: .     SOR_BACKWARD_SWEEP - backward SOR
3563: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3564: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
3565: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
3566: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3567: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
3568:          upper/lower triangular part of matrix to
3569:          vector (with omega)
3570: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3572:    Notes:
3573:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3574:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3575:    on each processor. 

3577:    Application programmers will not generally use MatSOR() directly,
3578:    but instead will employ the KSP/PC interface.

3580:    Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing

3582:    Notes for Advanced Users:
3583:    The flags are implemented as bitwise inclusive or operations.
3584:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3585:    to specify a zero initial guess for SSOR.

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

3591:    Vectors x and b CANNOT be the same

3593:    Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes

3595:    Level: developer

3597:    Concepts: matrices^relaxation
3598:    Concepts: matrices^SOR
3599:    Concepts: matrices^Gauss-Seidel

3601: @*/
3602: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3603: {

3613:   if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3614:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3615:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3616:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3617:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3618:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3619:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3620:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3621:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3623:   MatPreallocated(mat);
3624:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3625:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3626:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3627:   PetscObjectStateIncrease((PetscObject)x);
3628:   return(0);
3629: }

3633: /*
3634:       Default matrix copy routine.
3635: */
3636: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3637: {
3638:   PetscErrorCode    ierr;
3639:   PetscInt          i,rstart = 0,rend = 0,nz;
3640:   const PetscInt    *cwork;
3641:   const PetscScalar *vwork;

3644:   if (B->assembled) {
3645:     MatZeroEntries(B);
3646:   }
3647:   MatGetOwnershipRange(A,&rstart,&rend);
3648:   for (i=rstart; i<rend; i++) {
3649:     MatGetRow(A,i,&nz,&cwork,&vwork);
3650:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3651:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3652:   }
3653:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3654:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3655:   PetscObjectStateIncrease((PetscObject)B);
3656:   return(0);
3657: }

3661: /*@
3662:    MatCopy - Copys a matrix to another matrix.

3664:    Collective on Mat

3666:    Input Parameters:
3667: +  A - the matrix
3668: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3670:    Output Parameter:
3671: .  B - where the copy is put

3673:    Notes:
3674:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
3675:    same nonzero pattern or the routine will crash.

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

3681:    Level: intermediate
3682:    
3683:    Concepts: matrices^copying

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

3687: @*/
3688: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3689: {
3691:   PetscInt       i;

3699:   MatPreallocated(B);
3700:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3701:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3702:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3703:   MatPreallocated(A);

3705:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3706:   if (A->ops->copy) {
3707:     (*A->ops->copy)(A,B,str);
3708:   } else { /* generic conversion */
3709:     MatCopy_Basic(A,B,str);
3710:   }

3712:   B->stencil.dim = A->stencil.dim;
3713:   B->stencil.noc = A->stencil.noc;
3714:   for (i=0; i<=A->stencil.dim; i++) {
3715:     B->stencil.dims[i]   = A->stencil.dims[i];
3716:     B->stencil.starts[i] = A->stencil.starts[i];
3717:   }

3719:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3720:   PetscObjectStateIncrease((PetscObject)B);
3721:   return(0);
3722: }

3726: /*@C  
3727:    MatConvert - Converts a matrix to another matrix, either of the same
3728:    or different type.

3730:    Collective on Mat

3732:    Input Parameters:
3733: +  mat - the matrix
3734: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3735:    same type as the original matrix.
3736: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3737:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3738:    MAT_INITIAL_MATRIX.

3740:    Output Parameter:
3741: .  M - pointer to place new matrix

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

3748:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3749:    the MPI communicator of the generated matrix is always the same as the communicator
3750:    of the input matrix.

3752:    Level: intermediate

3754:    Concepts: matrices^converting between storage formats

3756: .seealso: MatCopy(), MatDuplicate()
3757: @*/
3758: PetscErrorCode  MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3759: {
3760:   PetscErrorCode         ierr;
3761:   PetscBool              sametype,issame,flg;
3762:   char                   convname[256],mtype[256];
3763:   Mat                    B;

3769:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3770:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3771:   MatPreallocated(mat);

3773:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3774:   if (flg) {
3775:     newtype = mtype;
3776:   }
3777:   PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3778:   PetscStrcmp(newtype,"same",&issame);
3779:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3780:     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3781:   }

3783:   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3784: 
3785:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3786:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3787:   } else {
3788:     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3789:     const char     *prefix[3] = {"seq","mpi",""};
3790:     PetscInt       i;
3791:     /* 
3792:        Order of precedence:
3793:        1) See if a specialized converter is known to the current matrix.
3794:        2) See if a specialized converter is known to the desired matrix class.
3795:        3) See if a good general converter is registered for the desired class
3796:           (as of 6/27/03 only MATMPIADJ falls into this category).
3797:        4) See if a good general converter is known for the current matrix.
3798:        5) Use a really basic converter.
3799:     */
3800: 
3801:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3802:     for (i=0; i<3; i++) {
3803:       PetscStrcpy(convname,"MatConvert_");
3804:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3805:       PetscStrcat(convname,"_");
3806:       PetscStrcat(convname,prefix[i]);
3807:       PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);
3808:       PetscStrcat(convname,"_C");
3809:       PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3810:       if (conv) goto foundconv;
3811:     }

3813:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3814:     MatCreate(((PetscObject)mat)->comm,&B);
3815:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3816:     MatSetType(B,newtype);
3817:     for (i=0; i<3; i++) {
3818:       PetscStrcpy(convname,"MatConvert_");
3819:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3820:       PetscStrcat(convname,"_");
3821:       PetscStrcat(convname,prefix[i]);
3822:       PetscStrcat(convname,newtype);
3823:       PetscStrcat(convname,"_C");
3824:       PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3825:       if (conv) {
3826:         MatDestroy(&B);
3827:         goto foundconv;
3828:       }
3829:     }

3831:     /* 3) See if a good general converter is registered for the desired class */
3832:     conv = B->ops->convertfrom;
3833:     MatDestroy(&B);
3834:     if (conv) goto foundconv;

3836:     /* 4) See if a good general converter is known for the current matrix */
3837:     if (mat->ops->convert) {
3838:       conv = mat->ops->convert;
3839:     }
3840:     if (conv) goto foundconv;

3842:     /* 5) Use a really basic converter. */
3843:     conv = MatConvert_Basic;

3845:     foundconv:
3846:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3847:     (*conv)(mat,newtype,reuse,M);
3848:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3849:   }
3850:   PetscObjectStateIncrease((PetscObject)*M);

3852:   /* Copy Mat options */
3853:   if (mat->symmetric){MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3854:   if (mat->hermitian){MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3855:   return(0);
3856: }

3860: /*@C  
3861:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3863:    Not Collective

3865:    Input Parameter:
3866: .  mat - the matrix, must be a factored matrix

3868:    Output Parameter:
3869: .   type - the string name of the package (do not free this string)

3871:    Notes:
3872:       In Fortran you pass in a empty string and the package name will be copied into it. 
3873:     (Make sure the string is long enough)

3875:    Level: intermediate

3877: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3878: @*/
3879: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3880: {
3881:   PetscErrorCode         ierr;
3882:   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);

3887:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3888:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3889:   if (!conv) {
3890:     *type = MATSOLVERPETSC;
3891:   } else {
3892:     (*conv)(mat,type);
3893:   }
3894:   return(0);
3895: }

3899: /*@C  
3900:    MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()

3902:    Collective on Mat

3904:    Input Parameters:
3905: +  mat - the matrix
3906: .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3907: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 

3909:    Output Parameters:
3910: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

3912:    Notes:
3913:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3914:      such as pastix, superlu, mumps, spooles etc. 

3916:       PETSc must have been ./configure to use the external solver, using the option --download-package

3918:    Level: intermediate

3920: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3921: @*/
3922: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3923: {
3924:   PetscErrorCode  ierr,(*conv)(Mat,MatFactorType,Mat*);
3925:   char            convname[256];


3931:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3932:   MatPreallocated(mat);

3934:   PetscStrcpy(convname,"MatGetFactor_");
3935:   PetscStrcat(convname,type);
3936:   PetscStrcat(convname,"_C");
3937:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3938:   if (!conv) {
3939:     PetscBool  flag;
3940:     MPI_Comm   comm;

3942:     PetscObjectGetComm((PetscObject)mat,&comm);
3943:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3944:     if (flag) {
3945:       SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3946:     } else {
3947:       SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type);
3948:     }
3949:   }
3950:   (*conv)(mat,ftype,f);
3951:   return(0);
3952: }

3956: /*@C  
3957:    MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type

3959:    Not Collective

3961:    Input Parameters:
3962: +  mat - the matrix
3963: .  type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default)
3964: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 

3966:    Output Parameter:
3967: .    flg - PETSC_TRUE if the factorization is available

3969:    Notes:
3970:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3971:      such as pastix, superlu, mumps, spooles etc. 

3973:       PETSc must have been ./configure to use the external solver, using the option --download-package

3975:    Level: intermediate

3977: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3978: @*/
3979: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
3980: {
3981:   PetscErrorCode         ierr;
3982:   char                   convname[256];
3983:   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscBool *);


3989:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3990:   MatPreallocated(mat);

3992:   PetscStrcpy(convname,"MatGetFactorAvailable_");
3993:   PetscStrcat(convname,type);
3994:   PetscStrcat(convname,"_C");
3995:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3996:   if (!conv) {
3997:     *flg = PETSC_FALSE;
3998:   } else {
3999:     (*conv)(mat,ftype,flg);
4000:   }
4001:   return(0);
4002: }


4007: /*@
4008:    MatDuplicate - Duplicates a matrix including the non-zero structure.

4010:    Collective on Mat

4012:    Input Parameters:
4013: +  mat - the matrix
4014: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4015:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

4017:    Output Parameter:
4018: .  M - pointer to place new matrix

4020:    Level: intermediate

4022:    Concepts: matrices^duplicating

4024:     Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.

4026: .seealso: MatCopy(), MatConvert()
4027: @*/
4028: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4029: {
4031:   Mat            B;
4032:   PetscInt       i;

4038:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4039:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4040:   MatPreallocated(mat);

4042:   *M  = 0;
4043:   if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
4044:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4045:   (*mat->ops->duplicate)(mat,op,M);
4046:   B = *M;
4047: 
4048:   B->stencil.dim = mat->stencil.dim;
4049:   B->stencil.noc = mat->stencil.noc;
4050:   for (i=0; i<=mat->stencil.dim; i++) {
4051:     B->stencil.dims[i]   = mat->stencil.dims[i];
4052:     B->stencil.starts[i] = mat->stencil.starts[i];
4053:   }

4055:   B->nooffproczerorows = mat->nooffproczerorows;
4056:   B->nooffprocentries  = mat->nooffprocentries;
4057:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4058:   PetscObjectStateIncrease((PetscObject)B);
4059:   return(0);
4060: }

4064: /*@ 
4065:    MatGetDiagonal - Gets the diagonal of a matrix.

4067:    Logically Collective on Mat and Vec

4069:    Input Parameters:
4070: +  mat - the matrix
4071: -  v - the vector for storing the diagonal

4073:    Output Parameter:
4074: .  v - the diagonal of the matrix

4076:    Level: intermediate

4078:    Concepts: matrices^accessing diagonals

4080: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4081: @*/
4082: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4083: {

4090:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4091:   if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4092:   MatPreallocated(mat);

4094:   (*mat->ops->getdiagonal)(mat,v);
4095:   PetscObjectStateIncrease((PetscObject)v);
4096:   return(0);
4097: }

4101: /*@ 
4102:    MatGetRowMin - Gets the minimum value (of the real part) of each
4103:         row of the matrix

4105:    Logically Collective on Mat and Vec

4107:    Input Parameters:
4108: .  mat - the matrix

4110:    Output Parameter:
4111: +  v - the vector for storing the maximums
4112: -  idx - the indices of the column found for each row (optional)

4114:    Level: intermediate

4116:    Notes: The result of this call are the same as if one converted the matrix to dense format
4117:       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).

4119:     This code is only implemented for a couple of matrix formats.

4121:    Concepts: matrices^getting row maximums

4123: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4124:           MatGetRowMax()
4125: @*/
4126: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4127: {

4134:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4135:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4136:   MatPreallocated(mat);

4138:   (*mat->ops->getrowmin)(mat,v,idx);
4139:   PetscObjectStateIncrease((PetscObject)v);
4140:   return(0);
4141: }

4145: /*@ 
4146:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4147:         row of the matrix

4149:    Logically Collective on Mat and Vec

4151:    Input Parameters:
4152: .  mat - the matrix

4154:    Output Parameter:
4155: +  v - the vector for storing the minimums
4156: -  idx - the indices of the column found for each row (optional)

4158:    Level: intermediate

4160:    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4161:     row is 0 (the first column).

4163:     This code is only implemented for a couple of matrix formats.

4165:    Concepts: matrices^getting row maximums

4167: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4168: @*/
4169: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4170: {

4177:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4178:   if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4179:   MatPreallocated(mat);
4180:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

4182:   (*mat->ops->getrowminabs)(mat,v,idx);
4183:   PetscObjectStateIncrease((PetscObject)v);
4184:   return(0);
4185: }

4189: /*@ 
4190:    MatGetRowMax - Gets the maximum value (of the real part) of each
4191:         row of the matrix

4193:    Logically Collective on Mat and Vec

4195:    Input Parameters:
4196: .  mat - the matrix

4198:    Output Parameter:
4199: +  v - the vector for storing the maximums
4200: -  idx - the indices of the column found for each row (optional)

4202:    Level: intermediate

4204:    Notes: The result of this call are the same as if one converted the matrix to dense format
4205:       and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).

4207:     This code is only implemented for a couple of matrix formats.

4209:    Concepts: matrices^getting row maximums

4211: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4212: @*/
4213: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4214: {

4221:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4222:   if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4223:   MatPreallocated(mat);

4225:   (*mat->ops->getrowmax)(mat,v,idx);
4226:   PetscObjectStateIncrease((PetscObject)v);
4227:   return(0);
4228: }

4232: /*@ 
4233:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4234:         row of the matrix

4236:    Logically Collective on Mat and Vec

4238:    Input Parameters:
4239: .  mat - the matrix

4241:    Output Parameter:
4242: +  v - the vector for storing the maximums
4243: -  idx - the indices of the column found for each row (optional)

4245:    Level: intermediate

4247:    Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4248:     row is 0 (the first column).

4250:     This code is only implemented for a couple of matrix formats.

4252:    Concepts: matrices^getting row maximums

4254: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4255: @*/
4256: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4257: {

4264:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4265:   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4266:   MatPreallocated(mat);
4267:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

4269:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4270:   PetscObjectStateIncrease((PetscObject)v);
4271:   return(0);
4272: }

4276: /*@ 
4277:    MatGetRowSum - Gets the sum of each row of the matrix

4279:    Logically Collective on Mat and Vec

4281:    Input Parameters:
4282: .  mat - the matrix

4284:    Output Parameter:
4285: .  v - the vector for storing the sum of rows

4287:    Level: intermediate

4289:    Notes: This code is slow since it is not currently specialized for different formats

4291:    Concepts: matrices^getting row sums

4293: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4294: @*/
4295: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4296: {
4297:   PetscInt       start = 0, end = 0, row;
4298:   PetscScalar   *array;

4305:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4306:   MatPreallocated(mat);
4307:   MatGetOwnershipRange(mat, &start, &end);
4308:   VecGetArray(v, &array);
4309:   for(row = start; row < end; ++row) {
4310:     PetscInt           ncols, col;
4311:     const PetscInt    *cols;
4312:     const PetscScalar *vals;

4314:     array[row - start] = 0.0;
4315:     MatGetRow(mat, row, &ncols, &cols, &vals);
4316:     for(col = 0; col < ncols; col++) {
4317:       array[row - start] += vals[col];
4318:     }
4319:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4320:   }
4321:   VecRestoreArray(v, &array);
4322:   PetscObjectStateIncrease((PetscObject) v);
4323:   return(0);
4324: }

4328: /*@
4329:    MatTranspose - Computes an in-place or out-of-place transpose of a matrix.

4331:    Collective on Mat

4333:    Input Parameter:
4334: +  mat - the matrix to transpose
4335: -  reuse - store the transpose matrix in the provided B

4337:    Output Parameters:
4338: .  B - the transpose 

4340:    Notes:
4341:      If you  pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);

4343:    Level: intermediate

4345:    Concepts: matrices^transposing

4347: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4348: @*/
4349: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4350: {

4356:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4357:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4358:   if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4359:   MatPreallocated(mat);

4361:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4362:   (*mat->ops->transpose)(mat,reuse,B);
4363:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4364:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4365:   return(0);
4366: }

4370: /*@
4371:    MatIsTranspose - Test whether a matrix is another one's transpose, 
4372:         or its own, in which case it tests symmetry.

4374:    Collective on Mat

4376:    Input Parameter:
4377: +  A - the matrix to test
4378: -  B - the matrix to test against, this can equal the first parameter

4380:    Output Parameters:
4381: .  flg - the result

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

4388:    Level: intermediate

4390:    Concepts: matrices^transposing, matrix^symmetry

4392: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4393: @*/
4394: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4395: {
4396:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);

4402:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4403:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4404:   *flg = PETSC_FALSE;
4405:   if (f && g) {
4406:     if (f == g) {
4407:       (*f)(A,B,tol,flg);
4408:     } else {
4409:       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4410:     }
4411:   } else {
4412:     const MatType mattype;
4413:     if (!f) {MatGetType(A,&mattype);}
4414:     else    {MatGetType(B,&mattype);}
4415:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4416:   }
4417:   return(0);
4418: }

4422: /*@ 
4423:    MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.

4425:    Collective on Mat

4427:    Input Parameter:
4428: +  mat - the matrix to transpose and complex conjugate
4429: -  reuse - store the transpose matrix in the provided B

4431:    Output Parameters:
4432: .  B - the Hermitian

4434:    Notes:
4435:      If you  pass in &mat for B the Hermitian will be done in place

4437:    Level: intermediate

4439:    Concepts: matrices^transposing, complex conjugatex

4441: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4442: @*/
4443: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4444: {

4448:   MatTranspose(mat,reuse,B);
4449: #if defined(PETSC_USE_COMPLEX)
4450:   MatConjugate(*B);
4451: #endif
4452:   return(0);
4453: }

4457: /*@
4458:    MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 

4460:    Collective on Mat

4462:    Input Parameter:
4463: +  A - the matrix to test
4464: -  B - the matrix to test against, this can equal the first parameter

4466:    Output Parameters:
4467: .  flg - the result

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

4474:    Level: intermediate

4476:    Concepts: matrices^transposing, matrix^symmetry

4478: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4479: @*/
4480: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4481: {
4482:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);

4488:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4489:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4490:   if (f && g) {
4491:     if (f==g) {
4492:       (*f)(A,B,tol,flg);
4493:     } else {
4494:       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4495:     }
4496:   }
4497:   return(0);
4498: }

4502: /*@
4503:    MatPermute - Creates a new matrix with rows and columns permuted from the 
4504:    original.

4506:    Collective on Mat

4508:    Input Parameters:
4509: +  mat - the matrix to permute
4510: .  row - row permutation, each processor supplies only the permutation for its rows
4511: -  col - column permutation, each processor needs the entire column permutation, that is
4512:          this is the same size as the total number of columns in the matrix. It can often
4513:          be obtained with ISAllGather() on the row permutation

4515:    Output Parameters:
4516: .  B - the permuted matrix

4518:    Level: advanced

4520:    Concepts: matrices^permuting

4522: .seealso: MatGetOrdering(), ISAllGather()

4524: @*/
4525: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4526: {

4535:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4536:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4537:   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4538:   MatPreallocated(mat);

4540:   (*mat->ops->permute)(mat,row,col,B);
4541:   PetscObjectStateIncrease((PetscObject)*B);
4542:   return(0);
4543: }

4547: /*@
4548:    MatEqual - Compares two matrices.

4550:    Collective on Mat

4552:    Input Parameters:
4553: +  A - the first matrix
4554: -  B - the second matrix

4556:    Output Parameter:
4557: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4559:    Level: intermediate

4561:    Concepts: matrices^equality between
4562: @*/
4563: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4564: {

4574:   MatPreallocated(B);
4575:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4576:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4577:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4578:   if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4579:   if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4580:   if (A->ops->equal != B->ops->equal) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4581:   MatPreallocated(A);

4583:   (*A->ops->equal)(A,B,flg);
4584:   return(0);
4585: }

4589: /*@
4590:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4591:    matrices that are stored as vectors.  Either of the two scaling
4592:    matrices can be PETSC_NULL.

4594:    Collective on Mat

4596:    Input Parameters:
4597: +  mat - the matrix to be scaled
4598: .  l - the left scaling vector (or PETSC_NULL)
4599: -  r - the right scaling vector (or PETSC_NULL)

4601:    Notes:
4602:    MatDiagonalScale() computes A = LAR, where
4603:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4604:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4606:    Level: intermediate

4608:    Concepts: matrices^diagonal scaling
4609:    Concepts: diagonal scaling of matrices

4611: .seealso: MatScale()
4612: @*/
4613: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4614: {

4620:   if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4623:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4624:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4625:   MatPreallocated(mat);

4627:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4628:   (*mat->ops->diagonalscale)(mat,l,r);
4629:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4630:   PetscObjectStateIncrease((PetscObject)mat);
4631: #if defined(PETSC_HAVE_CUSP)
4632:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4633:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4634:   }
4635: #endif
4636:   return(0);
4637: }

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

4644:     Logically Collective on Mat

4646:     Input Parameters:
4647: +   mat - the matrix to be scaled
4648: -   a  - the scaling value

4650:     Output Parameter:
4651: .   mat - the scaled matrix

4653:     Level: intermediate

4655:     Concepts: matrices^scaling all entries

4657: .seealso: MatDiagonalScale()
4658: @*/
4659: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4660: {

4666:   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4667:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4668:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4670:   MatPreallocated(mat);

4672:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4673:   if (a != (PetscScalar)1.0) {
4674:     (*mat->ops->scale)(mat,a);
4675:     PetscObjectStateIncrease((PetscObject)mat);
4676:   }
4677:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4678: #if defined(PETSC_HAVE_CUSP)
4679:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4680:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4681:   }
4682: #endif
4683:   return(0);
4684: }

4688: /*@ 
4689:    MatNorm - Calculates various norms of a matrix.

4691:    Collective on Mat

4693:    Input Parameters:
4694: +  mat - the matrix
4695: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4697:    Output Parameters:
4698: .  nrm - the resulting norm 

4700:    Level: intermediate

4702:    Concepts: matrices^norm
4703:    Concepts: norm^of matrix
4704: @*/
4705: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4706: {


4714:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4715:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4716:   if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4717:   MatPreallocated(mat);

4719:   (*mat->ops->norm)(mat,type,nrm);
4720:   return(0);
4721: }

4723: /* 
4724:      This variable is used to prevent counting of MatAssemblyBegin() that
4725:    are called from within a MatAssemblyEnd().
4726: */
4727: static PetscInt MatAssemblyEnd_InUse = 0;
4730: /*@
4731:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4732:    be called after completing all calls to MatSetValues().

4734:    Collective on Mat

4736:    Input Parameters:
4737: +  mat - the matrix 
4738: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4739:  
4740:    Notes: 
4741:    MatSetValues() generally caches the values.  The matrix is ready to
4742:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4743:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4744:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4745:    using the matrix.

4747:    Level: beginner

4749:    Concepts: matrices^assembling

4751: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4752: @*/
4753: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4754: {

4760:   MatPreallocated(mat);
4761:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4762:   if (mat->assembled) {
4763:     mat->was_assembled = PETSC_TRUE;
4764:     mat->assembled     = PETSC_FALSE;
4765:   }
4766:   if (!MatAssemblyEnd_InUse) {
4767:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4768:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4769:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4770:   } else {
4771:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4772:   }
4773:   return(0);
4774: }

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

4782:    Not Collective

4784:    Input Parameter:
4785: .  mat - the matrix 

4787:    Output Parameter:
4788: .  assembled - PETSC_TRUE or PETSC_FALSE

4790:    Level: advanced

4792:    Concepts: matrices^assembled?

4794: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4795: @*/
4796: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4797: {
4802:   *assembled = mat->assembled;
4803:   return(0);
4804: }

4808: /*
4809:     Processes command line options to determine if/how a matrix
4810:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4811: */
4812: PetscErrorCode MatView_Private(Mat mat)
4813: {
4814:   PetscErrorCode    ierr;
4815:   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4816:   static PetscBool  incall = PETSC_FALSE;
4817: #if defined(PETSC_USE_SOCKET_VIEWER)
4818:   PetscBool         flg5 = PETSC_FALSE;
4819: #endif

4822:   if (incall) return(0);
4823:   incall = PETSC_TRUE;
4824:   PetscObjectOptionsBegin((PetscObject)mat);
4825:     PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4826:     PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4827:     PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4828:     PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4829: #if defined(PETSC_USE_SOCKET_VIEWER)
4830:     PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4831: #endif
4832:     PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4833:     PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4834:   PetscOptionsEnd();

4836:   if (flg1) {
4837:     PetscViewer viewer;

4839:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4840:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4841:     MatView(mat,viewer);
4842:     PetscViewerPopFormat(viewer);
4843:   }
4844:   if (flg2) {
4845:     PetscViewer viewer;

4847:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4848:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4849:     MatView(mat,viewer);
4850:     PetscViewerPopFormat(viewer);
4851:   }
4852:   if (flg3) {
4853:     PetscViewer viewer;

4855:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4856:     MatView(mat,viewer);
4857:   }
4858:   if (flg4) {
4859:     PetscViewer viewer;

4861:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4862:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4863:     MatView(mat,viewer);
4864:     PetscViewerPopFormat(viewer);
4865:   }
4866: #if defined(PETSC_USE_SOCKET_VIEWER)
4867:   if (flg5) {
4868:     MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4869:     PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4870:   }
4871: #endif
4872:   if (flg6) {
4873:     MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4874:     PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4875:   }
4876:   if (flg7) {
4877:     PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4878:     if (flg8) {
4879:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4880:     }
4881:     MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4882:     PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4883:     if (flg8) {
4884:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4885:     }
4886:   }
4887:   incall = PETSC_FALSE;
4888:   return(0);
4889: }

4893: /*@
4894:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4895:    be called after MatAssemblyBegin().

4897:    Collective on Mat

4899:    Input Parameters:
4900: +  mat - the matrix 
4901: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4903:    Options Database Keys:
4904: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4905: .  -mat_view_info_detailed - Prints more detailed info
4906: .  -mat_view - Prints matrix in ASCII format
4907: .  -mat_view_matlab - Prints matrix in Matlab format
4908: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4909: .  -display <name> - Sets display name (default is host)
4910: .  -draw_pause <sec> - Sets number of seconds to pause after display
4911: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4912: .  -viewer_socket_machine <machine>
4913: .  -viewer_socket_port <port>
4914: .  -mat_view_binary - save matrix to file in binary format
4915: -  -viewer_binary_filename <name>

4917:    Notes: 
4918:    MatSetValues() generally caches the values.  The matrix is ready to
4919:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4920:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4921:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4922:    using the matrix.

4924:    Level: beginner

4926: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4927: @*/
4928: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4929: {
4930:   PetscErrorCode  ierr;
4931:   static PetscInt inassm = 0;
4932:   PetscBool       flg = PETSC_FALSE;


4938:   inassm++;
4939:   MatAssemblyEnd_InUse++;
4940:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4941:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4942:     if (mat->ops->assemblyend) {
4943:       (*mat->ops->assemblyend)(mat,type);
4944:     }
4945:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4946:   } else {
4947:     if (mat->ops->assemblyend) {
4948:       (*mat->ops->assemblyend)(mat,type);
4949:     }
4950:   }

4952:   /* Flush assembly is not a true assembly */
4953:   if (type != MAT_FLUSH_ASSEMBLY) {
4954:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4955:   }
4956:   mat->insertmode = NOT_SET_VALUES;
4957:   MatAssemblyEnd_InUse--;
4958:   PetscObjectStateIncrease((PetscObject)mat);
4959:   if (!mat->symmetric_eternal) {
4960:     mat->symmetric_set              = PETSC_FALSE;
4961:     mat->hermitian_set              = PETSC_FALSE;
4962:     mat->structurally_symmetric_set = PETSC_FALSE;
4963:   }
4964:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4965:     MatView_Private(mat);
4966:     PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);
4967:     if (flg) {
4968:       PetscReal tol = 0.0;
4969:       PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4970:       MatIsSymmetric(mat,tol,&flg);
4971:       if (flg) {
4972:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4973:       } else {
4974:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4975:       }
4976:     }
4977:   }
4978:   inassm--;
4979: #if defined(PETSC_HAVE_CUSP)
4980:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4981:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4982:   }
4983: #endif
4984:   return(0);
4985: }

4989: /*@
4990:    MatSetOption - Sets a parameter option for a matrix. Some options
4991:    may be specific to certain storage formats.  Some options
4992:    determine how values will be inserted (or added). Sorted, 
4993:    row-oriented input will generally assemble the fastest. The default
4994:    is row-oriented, nonsorted input. 

4996:    Logically Collective on Mat

4998:    Input Parameters:
4999: +  mat - the matrix 
5000: .  option - the option, one of those listed below (and possibly others),
5001: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

5003:   Options Describing Matrix Structure:
5004: +    MAT_SPD - symmetric positive definite
5005: -    MAT_SYMMETRIC - symmetric in terms of both structure and value
5006: .    MAT_HERMITIAN - transpose is the complex conjugation
5007: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5008: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5009:                             you set to be kept with all future use of the matrix
5010:                             including after MatAssemblyBegin/End() which could
5011:                             potentially change the symmetry structure, i.e. you 
5012:                             KNOW the matrix will ALWAYS have the property you set.


5015:    Options For Use with MatSetValues():
5016:    Insert a logically dense subblock, which can be
5017: .    MAT_ROW_ORIENTED - row-oriented (default)

5019:    Note these options reflect the data you pass in with MatSetValues(); it has 
5020:    nothing to do with how the data is stored internally in the matrix 
5021:    data structure.

5023:    When (re)assembling a matrix, we can restrict the input for
5024:    efficiency/debugging purposes.  These options include
5025: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5026:         allowed if they generate a new nonzero
5027: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5028: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5029: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5030: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5031: +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5032:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5033:         performance for very large process counts.

5035:    Notes:
5036:    Some options are relevant only for particular matrix types and
5037:    are thus ignored by others.  Other options are not supported by
5038:    certain matrix types and will generate an error message if set.

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

5044:    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 
5045:    that would generate a new entry in the nonzero structure is instead
5046:    ignored.  Thus, if memory has not alredy been allocated for this particular 
5047:    data, then the insertion is ignored. For dense matrices, in which
5048:    the entire array is allocated, no entries are ever ignored. 
5049:    Set after the first MatAssemblyEnd()

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

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

5063:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
5064:    other processors should be dropped, rather than stashed.
5065:    This is useful if you know that the "owning" processor is also 
5066:    always generating the correct matrix entries, so that PETSc need
5067:    not transfer duplicate entries generated on another processor.
5068:    
5069:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5070:    searches during matrix assembly. When this flag is set, the hash table
5071:    is created during the first Matrix Assembly. This hash table is
5072:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5073:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 
5074:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5075:    supported by MATMPIBAIJ format only.

5077:    MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5078:    are kept in the nonzero structure

5080:    MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5081:    a zero location in the matrix

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

5086:    MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5087:         zero row routines and thus improves performance for very large process counts.

5089:    MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 
5090:         part of the matrix (since they should match the upper triangular part).

5092:    Level: intermediate

5094:    Concepts: matrices^setting options

5096: @*/
5097: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5098: {


5107:   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
5108:   if (!((PetscObject)mat)->type_name) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");
5109:   MatPreallocated(mat);
5110:   switch (op) {
5111:   case MAT_NO_OFF_PROC_ENTRIES:
5112:     mat->nooffprocentries                = flg;
5113:     return(0);
5114:     break;
5115:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5116:     mat->nooffproczerorows               = flg;
5117:     return(0);
5118:     break;
5119:   case MAT_SPD:
5120:     mat->spd_set                         = PETSC_TRUE;
5121:     mat->spd                             = flg;
5122:     if (flg) {
5123:       mat->symmetric                     = PETSC_TRUE;
5124:       mat->structurally_symmetric        = PETSC_TRUE;
5125:       mat->symmetric_set                 = PETSC_TRUE;
5126:       mat->structurally_symmetric_set    = PETSC_TRUE;
5127:     }
5128:     break;
5129:   case MAT_SYMMETRIC:
5130:     mat->symmetric                       = flg;
5131:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5132:     mat->symmetric_set                   = PETSC_TRUE;
5133:     mat->structurally_symmetric_set      = flg;
5134:     break;
5135:   case MAT_HERMITIAN:
5136:     mat->hermitian                       = flg;
5137:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5138:     mat->hermitian_set                   = PETSC_TRUE;
5139:     mat->structurally_symmetric_set      = flg;
5140:     break;
5141:   case MAT_STRUCTURALLY_SYMMETRIC:
5142:     mat->structurally_symmetric          = flg;
5143:     mat->structurally_symmetric_set      = PETSC_TRUE;
5144:     break;
5145:   case MAT_SYMMETRY_ETERNAL:
5146:     mat->symmetric_eternal               = flg;
5147:     break;
5148:   default:
5149:     break;
5150:   }
5151:   if (mat->ops->setoption) {
5152:     (*mat->ops->setoption)(mat,op,flg);
5153:   }
5154:   return(0);
5155: }

5159: /*@
5160:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5161:    this routine retains the old nonzero structure.

5163:    Logically Collective on Mat

5165:    Input Parameters:
5166: .  mat - the matrix 

5168:    Level: intermediate

5170:    Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase. 
5171:    See the Performance chapter of the users manual for information on preallocating matrices.

5173:    Concepts: matrices^zeroing

5175: .seealso: MatZeroRows()
5176: @*/
5177: PetscErrorCode  MatZeroEntries(Mat mat)
5178: {

5184:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5185:   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
5186:   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5187:   MatPreallocated(mat);

5189:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5190:   (*mat->ops->zeroentries)(mat);
5191:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5192:   PetscObjectStateIncrease((PetscObject)mat);
5193: #if defined(PETSC_HAVE_CUSP)
5194:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5195:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5196:   }
5197: #endif
5198:   return(0);
5199: }

5203: /*@C
5204:    MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5205:    of a set of rows and columns of a matrix.

5207:    Collective on Mat

5209:    Input Parameters:
5210: +  mat - the matrix
5211: .  numRows - the number of rows to remove
5212: .  rows - the global row indices
5213: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5214: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5215: -  b - optional vector of right hand side, that will be adjusted by provided solution

5217:    Notes:
5218:    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.

5220:    The user can set a value in the diagonal entry (or for the AIJ and
5221:    row formats can optionally remove the main diagonal entry from the
5222:    nonzero structure as well, by passing 0.0 as the final argument).

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

5229:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5230:    list only rows local to itself).

5232:    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.

5234:    Level: intermediate

5236:    Concepts: matrices^zeroing rows

5238: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5239: @*/
5240: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5241: {

5248:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5249:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5250:   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5251:   MatPreallocated(mat);

5253:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5254:   MatView_Private(mat);
5255:   PetscObjectStateIncrease((PetscObject)mat);
5256: #if defined(PETSC_HAVE_CUSP)
5257:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5258:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5259:   }
5260: #endif
5261:   return(0);
5262: }

5266: /*@C
5267:    MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5268:    of a set of rows and columns of a matrix.

5270:    Collective on Mat

5272:    Input Parameters:
5273: +  mat - the matrix
5274: .  is - the rows to zero
5275: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5276: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5277: -  b - optional vector of right hand side, that will be adjusted by provided solution

5279:    Notes:
5280:    This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.

5282:    The user can set a value in the diagonal entry (or for the AIJ and
5283:    row formats can optionally remove the main diagonal entry from the
5284:    nonzero structure as well, by passing 0.0 as the final argument).

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

5291:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5292:    list only rows local to itself).

5294:    The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.

5296:    Level: intermediate

5298:    Concepts: matrices^zeroing rows

5300: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5301: @*/
5302: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5303: {
5305:   PetscInt       numRows;
5306:   const PetscInt *rows;

5313:   ISGetLocalSize(is,&numRows);
5314:   ISGetIndices(is,&rows);
5315:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5316:   ISRestoreIndices(is,&rows);
5317:   return(0);
5318: }

5322: /*@C
5323:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5324:    of a set of rows of a matrix.

5326:    Collective on Mat

5328:    Input Parameters:
5329: +  mat - the matrix
5330: .  numRows - the number of rows to remove
5331: .  rows - the global row indices
5332: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5333: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5334: -  b - optional vector of right hand side, that will be adjusted by provided solution

5336:    Notes:
5337:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5338:    but does not release memory.  For the dense and block diagonal
5339:    formats this does not alter the nonzero structure.

5341:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5342:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5343:    merely zeroed.

5345:    The user can set a value in the diagonal entry (or for the AIJ and
5346:    row formats can optionally remove the main diagonal entry from the
5347:    nonzero structure as well, by passing 0.0 as the final argument).

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

5354:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5355:    list only rows local to itself).

5357:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5358:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5360:    Level: intermediate

5362:    Concepts: matrices^zeroing rows

5364: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5365: @*/
5366: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5367: {

5374:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5375:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5376:   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5377:   MatPreallocated(mat);

5379:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5380:   MatView_Private(mat);
5381:   PetscObjectStateIncrease((PetscObject)mat);
5382: #if defined(PETSC_HAVE_CUSP)
5383:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5384:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5385:   }
5386: #endif
5387:   return(0);
5388: }

5392: /*@C
5393:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5394:    of a set of rows of a matrix.

5396:    Collective on Mat

5398:    Input Parameters:
5399: +  mat - the matrix
5400: .  is - index set of rows to remove
5401: .  diag - value put in all diagonals of eliminated rows
5402: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5403: -  b - optional vector of right hand side, that will be adjusted by provided solution

5405:    Notes:
5406:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5407:    but does not release memory.  For the dense and block diagonal
5408:    formats this does not alter the nonzero structure.

5410:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5411:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5412:    merely zeroed.

5414:    The user can set a value in the diagonal entry (or for the AIJ and
5415:    row formats can optionally remove the main diagonal entry from the
5416:    nonzero structure as well, by passing 0.0 as the final argument).

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

5423:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5424:    list only rows local to itself).

5426:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5427:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5429:    Level: intermediate

5431:    Concepts: matrices^zeroing rows

5433: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5434: @*/
5435: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5436: {
5437:   PetscInt       numRows;
5438:   const PetscInt *rows;

5445:   ISGetLocalSize(is,&numRows);
5446:   ISGetIndices(is,&rows);
5447:   MatZeroRows(mat,numRows,rows,diag,x,b);
5448:   ISRestoreIndices(is,&rows);
5449:   return(0);
5450: }

5454: /*@C
5455:    MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5456:    of a set of rows of a matrix. These rows must be local to the process.

5458:    Collective on Mat

5460:    Input Parameters:
5461: +  mat - the matrix
5462: .  numRows - the number of rows to remove
5463: .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5464: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5465: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5466: -  b - optional vector of right hand side, that will be adjusted by provided solution

5468:    Notes:
5469:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5470:    but does not release memory.  For the dense and block diagonal
5471:    formats this does not alter the nonzero structure.

5473:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5474:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5475:    merely zeroed.

5477:    The user can set a value in the diagonal entry (or for the AIJ and
5478:    row formats can optionally remove the main diagonal entry from the
5479:    nonzero structure as well, by passing 0.0 as the final argument).

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

5486:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5487:    list only rows local to itself).

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

5491:    In Fortran idxm and idxn should be declared as
5492: $     MatStencil idxm(4,m)
5493:    and the values inserted using
5494: $    idxm(MatStencil_i,1) = i
5495: $    idxm(MatStencil_j,1) = j
5496: $    idxm(MatStencil_k,1) = k
5497: $    idxm(MatStencil_c,1) = c
5498:    etc

5500:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 
5501:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5502:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5503:    DMDA_BOUNDARY_PERIODIC boundary type.

5505:    For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have
5506:    a single value per point) you can skip filling those indices.

5508:    Level: intermediate

5510:    Concepts: matrices^zeroing rows

5512: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5513: @*/
5514: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5515: {
5516:   PetscInt       dim    = mat->stencil.dim;
5517:   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5518:   PetscInt      *dims   = mat->stencil.dims+1;
5519:   PetscInt      *starts = mat->stencil.starts;
5520:   PetscInt      *dxm    = (PetscInt *) rows;
5521:   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;


5529:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5530:   for(i = 0; i < numRows; ++i) {
5531:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5532:     for(j = 0; j < 3-sdim; ++j) dxm++;
5533:     /* Local index in X dir */
5534:     tmp = *dxm++ - starts[0];
5535:     /* Loop over remaining dimensions */
5536:     for(j = 0; j < dim-1; ++j) {
5537:       /* If nonlocal, set index to be negative */
5538:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5539:       /* Update local index */
5540:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5541:     }
5542:     /* Skip component slot if necessary */
5543:     if (mat->stencil.noc) dxm++;
5544:     /* Local row number */
5545:     if (tmp >= 0) {
5546:       jdxm[numNewRows++] = tmp;
5547:     }
5548:   }
5549:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5550:   PetscFree(jdxm);
5551:   return(0);
5552: }

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

5560:    Collective on Mat

5562:    Input Parameters:
5563: +  mat - the matrix
5564: .  numRows - the number of rows to remove
5565: .  rows - the global row indices
5566: .  diag - value put in all diagonals of eliminated rows
5567: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5568: -  b - optional vector of right hand side, that will be adjusted by provided solution

5570:    Notes:
5571:    Before calling MatZeroRowsLocal(), the user must first set the
5572:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5574:    For the AIJ matrix formats this removes the old nonzero structure,
5575:    but does not release memory.  For the dense and block diagonal
5576:    formats this does not alter the nonzero structure.

5578:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5579:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5580:    merely zeroed.

5582:    The user can set a value in the diagonal entry (or for the AIJ and
5583:    row formats can optionally remove the main diagonal entry from the
5584:    nonzero structure as well, by passing 0.0 as the final argument).

5586:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5587:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5589:    Level: intermediate

5591:    Concepts: matrices^zeroing

5593: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5594: @*/
5595: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5596: {
5598:   PetscMPIInt    size;

5604:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5605:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5606:   MatPreallocated(mat);

5608:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
5609:   if (mat->ops->zerorowslocal) {
5610:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5611:   } else if (size == 1) {
5612:     (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5613:   } else {
5614:     IS             is, newis;
5615:     const PetscInt *newRows;

5617:     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5618:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5619:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5620:     ISGetIndices(newis,&newRows);
5621:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5622:     ISRestoreIndices(newis,&newRows);
5623:     ISDestroy(&newis);
5624:     ISDestroy(&is);
5625:   }
5626:   PetscObjectStateIncrease((PetscObject)mat);
5627: #if defined(PETSC_HAVE_CUSP)
5628:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5629:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5630:   }
5631: #endif
5632:   return(0);
5633: }

5637: /*@C 
5638:    MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5639:    of a set of rows of a matrix; using local numbering of rows.

5641:    Collective on Mat

5643:    Input Parameters:
5644: +  mat - the matrix
5645: .  is - index set of rows to remove
5646: .  diag - value put in all diagonals of eliminated rows
5647: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5648: -  b - optional vector of right hand side, that will be adjusted by provided solution

5650:    Notes:
5651:    Before calling MatZeroRowsLocalIS(), the user must first set the
5652:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5654:    For the AIJ matrix formats this removes the old nonzero structure,
5655:    but does not release memory.  For the dense and block diagonal
5656:    formats this does not alter the nonzero structure.

5658:    If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5659:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5660:    merely zeroed.

5662:    The user can set a value in the diagonal entry (or for the AIJ and
5663:    row formats can optionally remove the main diagonal entry from the
5664:    nonzero structure as well, by passing 0.0 as the final argument).

5666:    You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5667:    owns that are to be zeroed. This saves a global synchronization in the implementation.

5669:    Level: intermediate

5671:    Concepts: matrices^zeroing

5673: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5674: @*/
5675: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5676: {
5678:   PetscInt       numRows;
5679:   const PetscInt *rows;

5685:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5686:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5687:   MatPreallocated(mat);

5689:   ISGetLocalSize(is,&numRows);
5690:   ISGetIndices(is,&rows);
5691:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5692:   ISRestoreIndices(is,&rows);
5693:   return(0);
5694: }

5698: /*@C 
5699:    MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5700:    of a set of rows and columns of a matrix; using local numbering of rows.

5702:    Collective on Mat

5704:    Input Parameters:
5705: +  mat - the matrix
5706: .  numRows - the number of rows to remove
5707: .  rows - the global row indices
5708: .  diag - value put in all diagonals of eliminated rows
5709: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5710: -  b - optional vector of right hand side, that will be adjusted by provided solution

5712:    Notes:
5713:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5714:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5716:    The user can set a value in the diagonal entry (or for the AIJ and
5717:    row formats can optionally remove the main diagonal entry from the
5718:    nonzero structure as well, by passing 0.0 as the final argument).

5720:    Level: intermediate

5722:    Concepts: matrices^zeroing

5724: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5725: @*/
5726: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5727: {
5729:   PetscMPIInt    size;

5735:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5736:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5737:   MatPreallocated(mat);

5739:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
5740:   if (size == 1) {
5741:     (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5742:   } else {
5743:     IS             is, newis;
5744:     const PetscInt *newRows;

5746:     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5747:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5748:     ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5749:     ISGetIndices(newis,&newRows);
5750:     (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5751:     ISRestoreIndices(newis,&newRows);
5752:     ISDestroy(&newis);
5753:     ISDestroy(&is);
5754:   }
5755:   PetscObjectStateIncrease((PetscObject)mat);
5756: #if defined(PETSC_HAVE_CUSP)
5757:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5758:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5759:   }
5760: #endif
5761:   return(0);
5762: }

5766: /*@C 
5767:    MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5768:    of a set of rows and columns of a matrix; using local numbering of rows.

5770:    Collective on Mat

5772:    Input Parameters:
5773: +  mat - the matrix
5774: .  is - index set of rows to remove
5775: .  diag - value put in all diagonals of eliminated rows
5776: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5777: -  b - optional vector of right hand side, that will be adjusted by provided solution

5779:    Notes:
5780:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5781:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5783:    The user can set a value in the diagonal entry (or for the AIJ and
5784:    row formats can optionally remove the main diagonal entry from the
5785:    nonzero structure as well, by passing 0.0 as the final argument).

5787:    Level: intermediate

5789:    Concepts: matrices^zeroing

5791: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5792: @*/
5793: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5794: {
5796:   PetscInt       numRows;
5797:   const PetscInt *rows;

5803:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5804:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5805:   MatPreallocated(mat);

5807:   ISGetLocalSize(is,&numRows);
5808:   ISGetIndices(is,&rows);
5809:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5810:   ISRestoreIndices(is,&rows);
5811:   return(0);
5812: }

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

5819:    Not Collective

5821:    Input Parameter:
5822: .  mat - the matrix

5824:    Output Parameters:
5825: +  m - the number of global rows
5826: -  n - the number of global columns

5828:    Note: both output parameters can be PETSC_NULL on input.

5830:    Level: beginner

5832:    Concepts: matrices^size

5834: .seealso: MatGetLocalSize()
5835: @*/
5836: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5837: {
5840:   if (m) *m = mat->rmap->N;
5841:   if (n) *n = mat->cmap->N;
5842:   return(0);
5843: }

5847: /*@
5848:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5849:    stored locally.  This information may be implementation dependent, so
5850:    use with care.

5852:    Not Collective

5854:    Input Parameters:
5855: .  mat - the matrix

5857:    Output Parameters:
5858: +  m - the number of local rows
5859: -  n - the number of local columns

5861:    Note: both output parameters can be PETSC_NULL on input.

5863:    Level: beginner

5865:    Concepts: matrices^local size

5867: .seealso: MatGetSize()
5868: @*/
5869: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5870: {
5875:   if (m) *m = mat->rmap->n;
5876:   if (n) *n = mat->cmap->n;
5877:   return(0);
5878: }

5882: /*@
5883:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5884:    this processor. (The columns of the "diagonal block")

5886:    Not Collective, unless matrix has not been allocated, then collective on Mat

5888:    Input Parameters:
5889: .  mat - the matrix

5891:    Output Parameters:
5892: +  m - the global index of the first local column
5893: -  n - one more than the global index of the last local column

5895:    Notes: both output parameters can be PETSC_NULL on input.

5897:    Level: developer

5899:    Concepts: matrices^column ownership

5901: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

5903: @*/
5904: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5905: {

5913:   MatPreallocated(mat);
5914:   if (m) *m = mat->cmap->rstart;
5915:   if (n) *n = mat->cmap->rend;
5916:   return(0);
5917: }

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

5927:    Not Collective, unless matrix has not been allocated, then collective on Mat

5929:    Input Parameters:
5930: .  mat - the matrix

5932:    Output Parameters:
5933: +  m - the global index of the first local row
5934: -  n - one more than the global index of the last local row

5936:    Note: both output parameters can be PETSC_NULL on input.

5938:    Level: beginner

5940:    Concepts: matrices^row ownership

5942: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

5944: @*/
5945: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5946: {

5954:   MatPreallocated(mat);
5955:   if (m) *m = mat->rmap->rstart;
5956:   if (n) *n = mat->rmap->rend;
5957:   return(0);
5958: }

5962: /*@C
5963:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5964:    each process

5966:    Not Collective, unless matrix has not been allocated, then collective on Mat

5968:    Input Parameters:
5969: .  mat - the matrix

5971:    Output Parameters:
5972: .  ranges - start of each processors portion plus one more then the total length at the end

5974:    Level: beginner

5976:    Concepts: matrices^row ownership

5978: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

5980: @*/
5981: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5982: {

5988:   MatPreallocated(mat);
5989:   PetscLayoutGetRanges(mat->rmap,ranges);
5990:   return(0);
5991: }

5995: /*@C
5996:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5997:    this processor. (The columns of the "diagonal blocks" for each process)

5999:    Not Collective, unless matrix has not been allocated, then collective on Mat

6001:    Input Parameters:
6002: .  mat - the matrix

6004:    Output Parameters:
6005: .  ranges - start of each processors portion plus one more then the total length at the end

6007:    Level: beginner

6009:    Concepts: matrices^column ownership

6011: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6013: @*/
6014: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6015: {

6021:   MatPreallocated(mat);
6022:   PetscLayoutGetRanges(mat->cmap,ranges);
6023:   return(0);
6024: }

6028: /*@C
6029:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6030:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
6031:    to complete the factorization.

6033:    Collective on Mat

6035:    Input Parameters:
6036: +  mat - the matrix
6037: .  row - row permutation
6038: .  column - column permutation
6039: -  info - structure containing 
6040: $      levels - number of levels of fill.
6041: $      expected fill - as ratio of original fill.
6042: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6043:                 missing diagonal entries)

6045:    Output Parameters:
6046: .  fact - new matrix that has been symbolically factored

6048:    Notes:
6049:    See the <a href="../../docs/manual.pdf">users manual</a>  for additional information about
6050:    choosing the fill factor for better efficiency.

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

6056:    Level: developer

6058:   Concepts: matrices^symbolic LU factorization
6059:   Concepts: matrices^factorization
6060:   Concepts: LU^symbolic factorization

6062: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6063:           MatGetOrdering(), MatFactorInfo

6065:     Developer Note: fortran interface is not autogenerated as the f90
6066:     interface defintion cannot be generated correctly [due to MatFactorInfo]

6068: @*/
6069: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6070: {

6080:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6081:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6082:   if (!(fact)->ops->ilufactorsymbolic) {
6083:     const MatSolverPackage spackage;
6084:     MatFactorGetSolverPackage(fact,&spackage);
6085:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6086:   }
6087:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6088:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6089:   MatPreallocated(mat);

6091:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6092:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6093:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6094:   return(0);
6095: }

6099: /*@C
6100:    MatICCFactorSymbolic - Performs symbolic incomplete
6101:    Cholesky factorization for a symmetric matrix.  Use 
6102:    MatCholeskyFactorNumeric() to complete the factorization.

6104:    Collective on Mat

6106:    Input Parameters:
6107: +  mat - the matrix
6108: .  perm - row and column permutation
6109: -  info - structure containing 
6110: $      levels - number of levels of fill.
6111: $      expected fill - as ratio of original fill.

6113:    Output Parameter:
6114: .  fact - the factored matrix

6116:    Notes:
6117:    Most users should employ the KSP interface for linear solvers
6118:    instead of working directly with matrix algebra routines such as this.
6119:    See, e.g., KSPCreate().

6121:    Level: developer

6123:   Concepts: matrices^symbolic incomplete Cholesky factorization
6124:   Concepts: matrices^factorization
6125:   Concepts: Cholsky^symbolic factorization

6127: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

6129:     Developer Note: fortran interface is not autogenerated as the f90
6130:     interface defintion cannot be generated correctly [due to MatFactorInfo]

6132: @*/
6133: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6134: {

6143:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6144:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6145:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6146:   if (!(fact)->ops->iccfactorsymbolic) {
6147:     const MatSolverPackage spackage;
6148:     MatFactorGetSolverPackage(fact,&spackage);
6149:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6150:   }
6151:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6152:   MatPreallocated(mat);

6154:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6155:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6156:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6157:   return(0);
6158: }

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

6168:    Not Collective

6170:    Input Parameter:
6171: .  mat - the matrix

6173:    Output Parameter:
6174: .  v - the location of the values


6177:    Fortran Note:
6178:    This routine is used differently from Fortran, e.g.,
6179: .vb
6180:         Mat         mat
6181:         PetscScalar mat_array(1)
6182:         PetscOffset i_mat
6183:         PetscErrorCode ierr
6184:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

6190:         [... other code ...]
6191:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6192: .ve

6194:    See the <a href="../../docs/manual.pdf#Chapter 10 PETSc for Fortran Users">Fortran chapter of the users manual</a> and 
6195:    src/mat/examples/tests for details.

6197:    Level: advanced

6199:    Concepts: matrices^access array

6201: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6202: @*/
6203: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6204: {

6211:   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6212:   MatPreallocated(mat);
6213:   (*mat->ops->getarray)(mat,v);
6214:   CHKMEMQ;
6215:   return(0);
6216: }

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

6223:    Not Collective

6225:    Input Parameter:
6226: +  mat - the matrix
6227: -  v - the location of the values

6229:    Fortran Note:
6230:    This routine is used differently from Fortran, e.g.,
6231: .vb
6232:         Mat         mat
6233:         PetscScalar mat_array(1)
6234:         PetscOffset i_mat
6235:         PetscErrorCode ierr
6236:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

6242:         [... other code ...]
6243:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6244: .ve

6246:    See the <a href="../../docs/manual.pdf#Chapter 10 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6247:    src/mat/examples/tests for details

6249:    Level: advanced

6251: .seealso: MatGetArray(), MatRestoreArrayF90()
6252: @*/
6253: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6254: {

6261:   CHKMEMQ;
6262:   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6263:   (*mat->ops->restorearray)(mat,v);
6264:   PetscObjectStateIncrease((PetscObject)mat);
6265: #if defined(PETSC_HAVE_CUSP)
6266:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6267:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6268:   }
6269: #endif
6270:   return(0);
6271: }

6275: /*@C
6276:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6277:    points to an array of valid matrices, they may be reused to store the new
6278:    submatrices.

6280:    Collective on Mat

6282:    Input Parameters:
6283: +  mat - the matrix
6284: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6285: .  irow, icol - index sets of rows and columns to extract
6286: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6288:    Output Parameter:
6289: .  submat - the array of submatrices

6291:    Notes:
6292:    MatGetSubMatrices() can extract ONLY sequential submatrices
6293:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6294:    to extract a parallel submatrix.

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

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

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

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

6309:    For BAIJ matrices the index sets must respect the block structure, that is if they
6310:    request one row/column in a block, they must request all rows/columns that are in
6311:    that block. For example, if the block size is 2 you cannot request just row 0 and 
6312:    column 0.

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

6318:    Level: advanced

6320:    Concepts: matrices^accessing submatrices
6321:    Concepts: submatrices

6323: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6324: @*/
6325: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6326: {
6328:   PetscInt        i;
6329:   PetscBool       eq;

6334:   if (n) {
6339:   }
6341:   if (n && scall == MAT_REUSE_MATRIX) {
6344:   }
6345:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6346:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6347:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6348:   MatPreallocated(mat);

6350:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6351:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6352:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6353:   for (i=0; i<n; i++) {
6354:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6355:       ISEqual(irow[i],icol[i],&eq);
6356:       if (eq) {
6357:         if (mat->symmetric){
6358:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6359:         } else if (mat->hermitian) {
6360:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6361:         } else if (mat->structurally_symmetric) {
6362:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6363:         }
6364:       }
6365:     }
6366:   }
6367:   return(0);
6368: }

6372: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6373: {
6375:   PetscInt        i;
6376:   PetscBool       eq;

6381:   if (n) {
6386:   }
6388:   if (n && scall == MAT_REUSE_MATRIX) {
6391:   }
6392:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6393:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6394:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6395:   MatPreallocated(mat);

6397:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6398:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6399:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6400:   for (i=0; i<n; i++) {
6401:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6402:       ISEqual(irow[i],icol[i],&eq);
6403:       if (eq) {
6404:         if (mat->symmetric){
6405:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6406:         } else if (mat->hermitian) {
6407:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6408:         } else if (mat->structurally_symmetric) {
6409:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6410:         }
6411:       }
6412:     }
6413:   }
6414:   return(0);
6415: }

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

6422:    Collective on Mat

6424:    Input Parameters:
6425: +  n - the number of local matrices
6426: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6427:                        sequence of MatGetSubMatrices())

6429:    Level: advanced

6431:     Notes: Frees not only the matrices, but also the array that contains the matrices
6432:            In Fortran will not free the array.

6434: .seealso: MatGetSubMatrices()
6435: @*/
6436: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6437: {
6439:   PetscInt       i;

6442:   if (!*mat) return(0);
6443:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6445:   for (i=0; i<n; i++) {
6446:     MatDestroy(&(*mat)[i]);
6447:   }
6448:   /* memory is allocated even if n = 0 */
6449:   PetscFree(*mat);
6450:   *mat = PETSC_NULL;
6451:   return(0);
6452: }

6456: /*@C
6457:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 

6459:    Collective on Mat

6461:    Input Parameters:
6462: .  mat - the matrix

6464:    Output Parameter:
6465: .  matstruct - the sequential matrix with the nonzero structure of mat

6467:   Level: intermediate

6469: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6470: @*/
6471: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6472: {

6478: 
6480:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6481:   MatPreallocated(mat);

6483:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6484:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6485:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6486:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6487:   return(0);
6488: }

6492: /*@C
6493:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6495:    Collective on Mat

6497:    Input Parameters:
6498: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6499:                        sequence of MatGetSequentialNonzeroStructure())

6501:    Level: advanced

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

6505: .seealso: MatGetSeqNonzeroStructure()
6506: @*/
6507: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6508: {

6513:   MatDestroy(mat);
6514:   return(0);
6515: }

6519: /*@
6520:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6521:    replaces the index sets by larger ones that represent submatrices with
6522:    additional overlap.

6524:    Collective on Mat

6526:    Input Parameters:
6527: +  mat - the matrix
6528: .  n   - the number of index sets
6529: .  is  - the array of index sets (these index sets will changed during the call)
6530: -  ov  - the additional overlap requested

6532:    Level: developer

6534:    Concepts: overlap
6535:    Concepts: ASM^computing overlap

6537: .seealso: MatGetSubMatrices()
6538: @*/
6539: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6540: {

6546:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6547:   if (n) {
6550:   }
6551:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6552:   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6553:   MatPreallocated(mat);

6555:   if (!ov) return(0);
6556:   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6557:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6558:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6559:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6560:   return(0);
6561: }

6565: /*@
6566:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6567:    block row and block diagonal formats.
6568:    
6569:    Not Collective

6571:    Input Parameter:
6572: .  mat - the matrix

6574:    Output Parameter:
6575: .  bs - block size

6577:    Notes:
6578:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6580:    Level: intermediate

6582:    Concepts: matrices^block size

6584: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
6585: @*/
6586: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6587: {

6594:   MatPreallocated(mat);
6595:   *bs = mat->rmap->bs;
6596:   return(0);
6597: }

6601: /*@
6602:    MatSetBlockSize - Sets the matrix block size; for many matrix types you 
6603:      cannot use this and MUST set the blocksize when you preallocate the matrix
6604:    
6605:    Logically Collective on Mat

6607:    Input Parameters:
6608: +  mat - the matrix
6609: -  bs - block size

6611:    Notes:
6612:      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
6613:      it is not possible to change BAIJ block sizes after preallocation.

6615:    Level: intermediate

6617:    Concepts: matrices^block size

6619: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
6620: @*/
6621: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6622: {

6629:   MatPreallocated(mat);
6630:   if (bs < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
6631:   if (mat->ops->setblocksize) {
6632:     (*mat->ops->setblocksize)(mat,bs);
6633:   } else {
6634:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
6635:   }
6636:   return(0);
6637: }

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

6644:    Collective on Mat

6646:     Input Parameters:
6647: +   mat - the matrix
6648: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6649: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6650: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6651:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6652:                  always used.

6654:     Output Parameters:
6655: +   n - number of rows in the (possibly compressed) matrix
6656: .   ia - the row pointers [of length n+1]
6657: .   ja - the column indices
6658: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6659:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6661:     Level: developer

6663:     Notes: You CANNOT change any of the ia[] or ja[] values.

6665:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6667:     Fortran Node

6669:            In Fortran use
6670: $           PetscInt ia(1), ja(1)
6671: $           PetscOffset iia, jja
6672: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6673: $
6674: $          or 
6675: $
6676: $           PetscScalar, pointer :: xx_v(:)
6677: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6678:   
6679:  
6680:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6682: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6683: @*/
6684: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6685: {

6695:   MatPreallocated(mat);
6696:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6697:   else {
6698:     *done = PETSC_TRUE;
6699:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6700:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6701:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6702:   }
6703:   return(0);
6704: }

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

6711:     Collective on Mat

6713:     Input Parameters:
6714: +   mat - the matrix
6715: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6716: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6717:                 symmetrized
6718: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6719:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6720:                  always used.

6722:     Output Parameters:
6723: +   n - number of columns in the (possibly compressed) matrix
6724: .   ia - the column pointers
6725: .   ja - the row indices
6726: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6728:     Level: developer

6730: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6731: @*/
6732: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6733: {

6743:   MatPreallocated(mat);
6744:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6745:   else {
6746:     *done = PETSC_TRUE;
6747:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6748:   }
6749:   return(0);
6750: }

6754: /*@C
6755:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6756:     MatGetRowIJ().

6758:     Collective on Mat

6760:     Input Parameters:
6761: +   mat - the matrix
6762: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6763: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6764:                 symmetrized
6765: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6766:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6767:                  always used.

6769:     Output Parameters:
6770: +   n - size of (possibly compressed) matrix
6771: .   ia - the row pointers
6772: .   ja - the column indices
6773: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6775:     Level: developer

6777: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6778: @*/
6779: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6780: {

6789:   MatPreallocated(mat);

6791:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6792:   else {
6793:     *done = PETSC_TRUE;
6794:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6795:   }
6796:   return(0);
6797: }

6801: /*@C
6802:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6803:     MatGetColumnIJ().

6805:     Collective on Mat

6807:     Input Parameters:
6808: +   mat - the matrix
6809: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6810: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6811:                 symmetrized
6812: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6813:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6814:                  always used.

6816:     Output Parameters:
6817: +   n - size of (possibly compressed) matrix
6818: .   ia - the column pointers
6819: .   ja - the row indices
6820: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6822:     Level: developer

6824: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6825: @*/
6826: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6827: {

6836:   MatPreallocated(mat);

6838:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6839:   else {
6840:     *done = PETSC_TRUE;
6841:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6842:   }
6843:   return(0);
6844: }

6848: /*@C
6849:     MatColoringPatch -Used inside matrix coloring routines that 
6850:     use MatGetRowIJ() and/or MatGetColumnIJ().

6852:     Collective on Mat

6854:     Input Parameters:
6855: +   mat - the matrix
6856: .   ncolors - max color value
6857: .   n   - number of entries in colorarray
6858: -   colorarray - array indicating color for each column

6860:     Output Parameters:
6861: .   iscoloring - coloring generated using colorarray information

6863:     Level: developer

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

6867: @*/
6868: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6869: {

6877:   MatPreallocated(mat);

6879:   if (!mat->ops->coloringpatch){
6880:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6881:   } else {
6882:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6883:   }
6884:   return(0);
6885: }


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

6893:    Logically Collective on Mat

6895:    Input Parameter:
6896: .  mat - the factored matrix to be reset

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

6905:    Note that one can specify in-place ILU(0) factorization by calling 
6906: .vb
6907:      PCType(pc,PCILU);
6908:      PCFactorSeUseInPlace(pc);
6909: .ve
6910:    or by using the options -pc_type ilu -pc_factor_in_place

6912:    In-place factorization ILU(0) can also be used as a local
6913:    solver for the blocks within the block Jacobi or additive Schwarz
6914:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion 
6915:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
6916:    local solver options.

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

6922:    Level: developer

6924: .seealso: PCFactorSetUseInPlace()

6926:    Concepts: matrices^unfactored

6928: @*/
6929: PetscErrorCode  MatSetUnfactored(Mat mat)
6930: {

6936:   MatPreallocated(mat);
6937:   mat->factortype = MAT_FACTOR_NONE;
6938:   if (!mat->ops->setunfactored) return(0);
6939:   (*mat->ops->setunfactored)(mat);
6940:   return(0);
6941: }

6943: /*MC
6944:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

6946:     Synopsis:
6947:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

6949:     Not collective

6951:     Input Parameter:
6952: .   x - matrix

6954:     Output Parameters:
6955: +   xx_v - the Fortran90 pointer to the array
6956: -   ierr - error code

6958:     Example of Usage: 
6959: .vb
6960:       PetscScalar, pointer xx_v(:,:)
6961:       ....
6962:       call MatGetArrayF90(x,xx_v,ierr)
6963:       a = xx_v(3)
6964:       call MatRestoreArrayF90(x,xx_v,ierr)
6965: .ve

6967:     Notes:
6968:     Not yet supported for all F90 compilers

6970:     Level: advanced

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

6974:     Concepts: matrices^accessing array

6976: M*/

6978: /*MC
6979:     MatRestoreArrayF90 - Restores a matrix array that has been
6980:     accessed with MatGetArrayF90().

6982:     Synopsis:
6983:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6985:     Not collective

6987:     Input Parameters:
6988: +   x - matrix
6989: -   xx_v - the Fortran90 pointer to the array

6991:     Output Parameter:
6992: .   ierr - error code

6994:     Example of Usage: 
6995: .vb
6996:        PetscScalar, pointer xx_v(:)
6997:        ....
6998:        call MatGetArrayF90(x,xx_v,ierr)
6999:        a = xx_v(3)
7000:        call MatRestoreArrayF90(x,xx_v,ierr)
7001: .ve
7002:    
7003:     Notes:
7004:     Not yet supported for all F90 compilers

7006:     Level: advanced

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

7010: M*/


7015: /*@
7016:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7017:                       as the original matrix.

7019:     Collective on Mat

7021:     Input Parameters:
7022: +   mat - the original matrix
7023: .   isrow - parallel IS containing the rows this processor should obtain
7024: .   iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix.
7025: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7027:     Output Parameter:
7028: .   newmat - the new submatrix, of the same type as the old

7030:     Level: advanced

7032:     Notes:
7033:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7035:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7037:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7038:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7039:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX  
7040:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when 
7041:    you are finished using it.

7043:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7044:     the input matrix.

7046:     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).

7048:    Example usage:
7049:    Consider the following 8x8 matrix with 34 non-zero values, that is
7050:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7051:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7052:    as follows:

7054: .vb
7055:             1  2  0  |  0  3  0  |  0  4
7056:     Proc0   0  5  6  |  7  0  0  |  8  0
7057:             9  0 10  | 11  0  0  | 12  0
7058:     -------------------------------------
7059:            13  0 14  | 15 16 17  |  0  0
7060:     Proc1   0 18  0  | 19 20 21  |  0  0
7061:             0  0  0  | 22 23  0  | 24  0
7062:     -------------------------------------
7063:     Proc2  25 26 27  |  0  0 28  | 29  0
7064:            30  0  0  | 31 32 33  |  0 34
7065: .ve

7067:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7069: .vb
7070:             2  0  |  0  3  0  |  0
7071:     Proc0   5  6  |  7  0  0  |  8
7072:     -------------------------------
7073:     Proc1  18  0  | 19 20 21  |  0
7074:     -------------------------------
7075:     Proc2  26 27  |  0  0 28  | 29
7076:             0  0  | 31 32 33  |  0
7077: .ve


7080:     Concepts: matrices^submatrices

7082: .seealso: MatGetSubMatrices()
7083: @*/
7084: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7085: {
7087:   PetscMPIInt    size;
7088:   Mat            *local;
7089:   IS             iscoltmp;

7098:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7099:   MatPreallocated(mat);
7100:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

7102:   if (!iscol) {
7103:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7104:   } else {
7105:     iscoltmp = iscol;
7106:   }

7108:   /* if original matrix is on just one processor then use submatrix generated */
7109:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7110:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7111:     if (!iscol) {ISDestroy(&iscoltmp);}
7112:     return(0);
7113:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7114:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7115:     *newmat = *local;
7116:     PetscFree(local);
7117:     if (!iscol) {ISDestroy(&iscoltmp);}
7118:     return(0);
7119:   } else if (!mat->ops->getsubmatrix) {
7120:     /* Create a new matrix type that implements the operation using the full matrix */
7121:     switch (cll) {
7122:       case MAT_INITIAL_MATRIX:
7123:         MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7124:         break;
7125:       case MAT_REUSE_MATRIX:
7126:         MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7127:         break;
7128:       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7129:     }
7130:     if (!iscol) {ISDestroy(&iscoltmp);}
7131:     return(0);
7132:   }

7134:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7135:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7136:   if (!iscol) {ISDestroy(&iscoltmp);}
7137:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7138:   return(0);
7139: }

7143: /*@
7144:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7145:    used during the assembly process to store values that belong to 
7146:    other processors.

7148:    Not Collective

7150:    Input Parameters:
7151: +  mat   - the matrix
7152: .  size  - the initial size of the stash.
7153: -  bsize - the initial size of the block-stash(if used).

7155:    Options Database Keys:
7156: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7157: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7159:    Level: intermediate

7161:    Notes: 
7162:      The block-stash is used for values set with MatSetValuesBlocked() while
7163:      the stash is used for values set with MatSetValues()

7165:      Run with the option -info and look for output of the form
7166:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7167:      to determine the appropriate value, MM, to use for size and 
7168:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7169:      to determine the value, BMM to use for bsize

7171:    Concepts: stash^setting matrix size
7172:    Concepts: matrices^stash

7174: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7176: @*/
7177: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7178: {

7184:   MatStashSetInitialSize_Private(&mat->stash,size);
7185:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7186:   return(0);
7187: }

7191: /*@
7192:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
7193:      the matrix

7195:    Neighbor-wise Collective on Mat

7197:    Input Parameters:
7198: +  mat   - the matrix
7199: .  x,y - the vectors
7200: -  w - where the result is stored

7202:    Level: intermediate

7204:    Notes: 
7205:     w may be the same vector as y. 

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

7210:     Concepts: interpolation

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

7214: @*/
7215: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7216: {
7218:   PetscInt       M,N,Ny;

7226:   MatPreallocated(A);
7227:   MatGetSize(A,&M,&N);
7228:   VecGetSize(y,&Ny);
7229:   if (M == Ny) {
7230:     MatMultAdd(A,x,y,w);
7231:   } else {
7232:     MatMultTransposeAdd(A,x,y,w);
7233:   }
7234:   return(0);
7235: }

7239: /*@
7240:    MatInterpolate - y = A*x or A'*x depending on the shape of 
7241:      the matrix

7243:    Neighbor-wise Collective on Mat

7245:    Input Parameters:
7246: +  mat   - the matrix
7247: -  x,y - the vectors

7249:    Level: intermediate

7251:    Notes: 
7252:     This allows one to use either the restriction or interpolation (its transpose)
7253:     matrix to do the interpolation

7255:    Concepts: matrices^interpolation

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

7259: @*/
7260: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7261: {
7263:   PetscInt       M,N,Ny;

7270:   MatPreallocated(A);
7271:   MatGetSize(A,&M,&N);
7272:   VecGetSize(y,&Ny);
7273:   if (M == Ny) {
7274:     MatMult(A,x,y);
7275:   } else {
7276:     MatMultTranspose(A,x,y);
7277:   }
7278:   return(0);
7279: }

7283: /*@
7284:    MatRestrict - y = A*x or A'*x

7286:    Neighbor-wise Collective on Mat

7288:    Input Parameters:
7289: +  mat   - the matrix
7290: -  x,y - the vectors

7292:    Level: intermediate

7294:    Notes: 
7295:     This allows one to use either the restriction or interpolation (its transpose)
7296:     matrix to do the restriction

7298:    Concepts: matrices^restriction

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

7302: @*/
7303: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7304: {
7306:   PetscInt       M,N,Ny;

7313:   MatPreallocated(A);

7315:   MatGetSize(A,&M,&N);
7316:   VecGetSize(y,&Ny);
7317:   if (M == Ny) {
7318:     MatMult(A,x,y);
7319:   } else {
7320:     MatMultTranspose(A,x,y);
7321:   }
7322:   return(0);
7323: }

7327: /*@
7328:    MatNullSpaceAttach - attaches a null space to a matrix.
7329:         This null space will be removed from the resulting vector whenever
7330:         MatMult() is called

7332:    Logically Collective on Mat and MatNullSpace

7334:    Input Parameters:
7335: +  mat - the matrix
7336: -  nullsp - the null space object

7338:    Level: developer

7340:    Notes:
7341:       Overwrites any previous null space that may have been attached

7343:    Concepts: null space^attaching to matrix

7345: .seealso: MatCreate(), MatNullSpaceCreate()
7346: @*/
7347: PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
7348: {

7355:   MatPreallocated(mat);
7356:   PetscObjectReference((PetscObject)nullsp);
7357:   if (mat->nullsp) { MatNullSpaceDestroy(&mat->nullsp); }
7358:   mat->nullsp = nullsp;
7359:   return(0);
7360: }

7364: /*@C
7365:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7367:    Collective on Mat

7369:    Input Parameters:
7370: +  mat - the matrix
7371: .  row - row/column permutation
7372: .  fill - expected fill factor >= 1.0
7373: -  level - level of fill, for ICC(k)

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

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

7383:    Level: developer

7385:    Concepts: matrices^incomplete Cholesky factorization
7386:    Concepts: Cholesky factorization

7388: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

7390:     Developer Note: fortran interface is not autogenerated as the f90
7391:     interface defintion cannot be generated correctly [due to MatFactorInfo]

7393: @*/
7394: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7395: {

7403:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7404:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7405:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7406:   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7407:   MatPreallocated(mat);
7408:   (*mat->ops->iccfactor)(mat,row,info);
7409:   PetscObjectStateIncrease((PetscObject)mat);
7410:   return(0);
7411: }

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

7418:    Not Collective

7420:    Input Parameters:
7421: +  mat - the matrix
7422: -  v - the values compute with ADIC

7424:    Level: developer

7426:    Notes:
7427:      Must call MatSetColoring() before using this routine. Also this matrix must already
7428:      have its nonzero pattern determined.

7430: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7431:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7432: @*/
7433: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7434: {


7442:   if (!mat->assembled) {
7443:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7444:   }
7445:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7446:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7447:   (*mat->ops->setvaluesadic)(mat,v);
7448:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7449:   MatView_Private(mat);
7450:   PetscObjectStateIncrease((PetscObject)mat);
7451:   return(0);
7452: }


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

7460:    Not Collective

7462:    Input Parameters:
7463: +  mat - the matrix
7464: -  coloring - the coloring

7466:    Level: developer

7468: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7469:           MatSetValues(), MatSetValuesAdic()
7470: @*/
7471: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7472: {


7480:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7481:   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7482:   (*mat->ops->setcoloring)(mat,coloring);
7483:   return(0);
7484: }

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

7491:    Not Collective

7493:    Input Parameters:
7494: +  mat - the matrix
7495: .  nl - leading dimension of v
7496: -  v - the values compute with ADIFOR

7498:    Level: developer

7500:    Notes:
7501:      Must call MatSetColoring() before using this routine. Also this matrix must already
7502:      have its nonzero pattern determined.

7504: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7505:           MatSetValues(), MatSetColoring()
7506: @*/
7507: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7508: {


7516:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7517:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7518:   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7519:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7520:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7521:   PetscObjectStateIncrease((PetscObject)mat);
7522:   return(0);
7523: }

7527: /*@ 
7528:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
7529:          ghosted ones.

7531:    Not Collective

7533:    Input Parameters:
7534: +  mat - the matrix
7535: -  diag = the diagonal values, including ghost ones

7537:    Level: developer

7539:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7540:       
7541: .seealso: MatDiagonalScale()
7542: @*/
7543: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7544: {
7546:   PetscMPIInt    size;


7553:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7554:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7555:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
7556:   if (size == 1) {
7557:     PetscInt n,m;
7558:     VecGetSize(diag,&n);
7559:     MatGetSize(mat,0,&m);
7560:     if (m == n) {
7561:       MatDiagonalScale(mat,0,diag);
7562:     } else {
7563:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7564:     }
7565:   } else {
7566:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7567:   }
7568:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7569:   PetscObjectStateIncrease((PetscObject)mat);
7570:   return(0);
7571: }

7575: /*@ 
7576:    MatGetInertia - Gets the inertia from a factored matrix

7578:    Collective on Mat

7580:    Input Parameter:
7581: .  mat - the matrix

7583:    Output Parameters:
7584: +   nneg - number of negative eigenvalues
7585: .   nzero - number of zero eigenvalues
7586: -   npos - number of positive eigenvalues

7588:    Level: advanced

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


7593: @*/
7594: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7595: {

7601:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7602:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7603:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7604:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7605:   return(0);
7606: }

7608: /* ----------------------------------------------------------------*/
7611: /*@C
7612:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7614:    Neighbor-wise Collective on Mat and Vecs

7616:    Input Parameters:
7617: +  mat - the factored matrix
7618: -  b - the right-hand-side vectors

7620:    Output Parameter:
7621: .  x - the result vectors

7623:    Notes:
7624:    The vectors b and x cannot be the same.  I.e., one cannot
7625:    call MatSolves(A,x,x).

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

7632:    Level: developer

7634:    Concepts: matrices^triangular solves

7636: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7637: @*/
7638: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7639: {

7645:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7646:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7647:   if (!mat->rmap->N && !mat->cmap->N) return(0);

7649:   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7650:   MatPreallocated(mat);
7651:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7652:   (*mat->ops->solves)(mat,b,x);
7653:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7654:   return(0);
7655: }

7659: /*@
7660:    MatIsSymmetric - Test whether a matrix is symmetric

7662:    Collective on Mat

7664:    Input Parameter:
7665: +  A - the matrix to test
7666: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

7668:    Output Parameters:
7669: .  flg - the result

7671:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

7673:    Level: intermediate

7675:    Concepts: matrix^symmetry

7677: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7678: @*/
7679: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7680: {


7687:   if (!A->symmetric_set) {
7688:     if (!A->ops->issymmetric) {
7689:       const MatType mattype;
7690:       MatGetType(A,&mattype);
7691:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7692:     }
7693:     (*A->ops->issymmetric)(A,tol,flg);
7694:     if (!tol) {
7695:       A->symmetric_set = PETSC_TRUE;
7696:       A->symmetric = *flg;
7697:       if (A->symmetric) {
7698:         A->structurally_symmetric_set = PETSC_TRUE;
7699:         A->structurally_symmetric     = PETSC_TRUE;
7700:       }
7701:     }
7702:   } else if (A->symmetric) {
7703:     *flg = PETSC_TRUE;
7704:   } else if (!tol) {
7705:     *flg = PETSC_FALSE;
7706:   } else {
7707:     if (!A->ops->issymmetric) {
7708:       const MatType mattype;
7709:       MatGetType(A,&mattype);
7710:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7711:     }
7712:     (*A->ops->issymmetric)(A,tol,flg);
7713:   }
7714:   return(0);
7715: }

7719: /*@
7720:    MatIsHermitian - Test whether a matrix is Hermitian

7722:    Collective on Mat

7724:    Input Parameter:
7725: +  A - the matrix to test
7726: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

7728:    Output Parameters:
7729: .  flg - the result

7731:    Level: intermediate

7733:    Concepts: matrix^symmetry

7735: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7736:           MatIsSymmetricKnown(), MatIsSymmetric()
7737: @*/
7738: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7739: {


7746:   if (!A->hermitian_set) {
7747:     if (!A->ops->ishermitian) {
7748:       const MatType mattype;
7749:       MatGetType(A,&mattype);
7750:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7751:     }
7752:     (*A->ops->ishermitian)(A,tol,flg);
7753:     if (!tol) {
7754:       A->hermitian_set = PETSC_TRUE;
7755:       A->hermitian = *flg;
7756:       if (A->hermitian) {
7757:         A->structurally_symmetric_set = PETSC_TRUE;
7758:         A->structurally_symmetric     = PETSC_TRUE;
7759:       }
7760:     }
7761:   } else if (A->hermitian) {
7762:     *flg = PETSC_TRUE;
7763:   } else if (!tol) {
7764:     *flg = PETSC_FALSE;
7765:   } else {
7766:     if (!A->ops->ishermitian) {
7767:       const MatType mattype;
7768:       MatGetType(A,&mattype);
7769:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7770:     }
7771:     (*A->ops->ishermitian)(A,tol,flg);
7772:   }
7773:   return(0);
7774: }

7778: /*@
7779:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

7781:    Not Collective

7783:    Input Parameter:
7784: .  A - the matrix to check

7786:    Output Parameters:
7787: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7788: -  flg - the result

7790:    Level: advanced

7792:    Concepts: matrix^symmetry

7794:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7795:          if you want it explicitly checked

7797: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7798: @*/
7799: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7800: {
7805:   if (A->symmetric_set) {
7806:     *set = PETSC_TRUE;
7807:     *flg = A->symmetric;
7808:   } else {
7809:     *set = PETSC_FALSE;
7810:   }
7811:   return(0);
7812: }

7816: /*@
7817:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

7819:    Not Collective

7821:    Input Parameter:
7822: .  A - the matrix to check

7824:    Output Parameters:
7825: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7826: -  flg - the result

7828:    Level: advanced

7830:    Concepts: matrix^symmetry

7832:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
7833:          if you want it explicitly checked

7835: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7836: @*/
7837: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7838: {
7843:   if (A->hermitian_set) {
7844:     *set = PETSC_TRUE;
7845:     *flg = A->hermitian;
7846:   } else {
7847:     *set = PETSC_FALSE;
7848:   }
7849:   return(0);
7850: }

7854: /*@
7855:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

7857:    Collective on Mat

7859:    Input Parameter:
7860: .  A - the matrix to test

7862:    Output Parameters:
7863: .  flg - the result

7865:    Level: intermediate

7867:    Concepts: matrix^symmetry

7869: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7870: @*/
7871: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
7872: {

7878:   if (!A->structurally_symmetric_set) {
7879:     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7880:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7881:     A->structurally_symmetric_set = PETSC_TRUE;
7882:   }
7883:   *flg = A->structurally_symmetric;
7884:   return(0);
7885: }

7890: /*@ 
7891:    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7892:        to be communicated to other processors during the MatAssemblyBegin/End() process

7894:     Not collective

7896:    Input Parameter:
7897: .   vec - the vector

7899:    Output Parameters:
7900: +   nstash   - the size of the stash
7901: .   reallocs - the number of additional mallocs incurred.
7902: .   bnstash   - the size of the block stash
7903: -   breallocs - the number of additional mallocs incurred.in the block stash
7904:  
7905:    Level: advanced

7907: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7908:   
7909: @*/
7910: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7911: {
7914:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7915:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7916:   return(0);
7917: }

7921: /*@C
7922:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
7923:      parallel layout
7924:    
7925:    Collective on Mat

7927:    Input Parameter:
7928: .  mat - the matrix

7930:    Output Parameter:
7931: +   right - (optional) vector that the matrix can be multiplied against
7932: -   left - (optional) vector that the matrix vector product can be stored in

7934:   Level: advanced

7936: .seealso: MatCreate()
7937: @*/
7938: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7939: {

7945:   MatPreallocated(mat);
7946:   if (mat->ops->getvecs) {
7947:     (*mat->ops->getvecs)(mat,right,left);
7948:   } else {
7949:     PetscMPIInt size;
7950:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
7951:     if (right) {
7952:       VecCreate(((PetscObject)mat)->comm,right);
7953:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7954:       VecSetBlockSize(*right,mat->rmap->bs);
7955:       VecSetType(*right,VECSTANDARD);
7956:       PetscLayoutReference(mat->cmap,&(*right)->map);
7957:     }
7958:     if (left) {
7959:       VecCreate(((PetscObject)mat)->comm,left);
7960:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7961:       VecSetBlockSize(*left,mat->rmap->bs);
7962:       VecSetType(*left,VECSTANDARD);
7963:       PetscLayoutReference(mat->rmap,&(*left)->map);
7964:     }
7965:   }
7966:   return(0);
7967: }

7971: /*@C
7972:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7973:      with default values.

7975:    Not Collective

7977:    Input Parameters:
7978: .    info - the MatFactorInfo data structure


7981:    Notes: The solvers are generally used through the KSP and PC objects, for example
7982:           PCLU, PCILU, PCCHOLESKY, PCICC

7984:    Level: developer

7986: .seealso: MatFactorInfo

7988:     Developer Note: fortran interface is not autogenerated as the f90
7989:     interface defintion cannot be generated correctly [due to MatFactorInfo]

7991: @*/

7993: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7994: {

7998:   PetscMemzero(info,sizeof(MatFactorInfo));
7999:   return(0);
8000: }

8004: /*@
8005:    MatPtAP - Creates the matrix product C = P^T * A * P

8007:    Neighbor-wise Collective on Mat

8009:    Input Parameters:
8010: +  A - the matrix
8011: .  P - the projection matrix
8012: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8013: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

8015:    Output Parameters:
8016: .  C - the product matrix

8018:    Notes:
8019:    C will be created and must be destroyed by the user with MatDestroy().

8021:    This routine is currently only implemented for pairs of AIJ matrices and classes
8022:    which inherit from AIJ.  

8024:    Level: intermediate

8026: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
8027: @*/
8028: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8029: {

8035:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8036:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8039:   MatPreallocated(P);
8040:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8041:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8043:   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8044:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8045:   MatPreallocated(A);

8047:   if (!A->ops->ptap) {
8048:     const MatType mattype;
8049:     MatGetType(A,&mattype);
8050:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8051:   }
8052:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8053:   (*A->ops->ptap)(A,P,scall,fill,C);
8054:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);

8056:   return(0);
8057: }

8061: /*@
8062:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8064:    Neighbor-wise Collective on Mat

8066:    Input Parameters:
8067: +  A - the matrix
8068: -  P - the projection matrix

8070:    Output Parameters:
8071: .  C - the product matrix

8073:    Notes:
8074:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8075:    the user using MatDeatroy().

8077:    This routine is currently only implemented for pairs of AIJ matrices and classes
8078:    which inherit from AIJ.  C will be of type MATAIJ.

8080:    Level: intermediate

8082: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8083: @*/
8084: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8085: {

8091:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8092:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8095:   MatPreallocated(P);
8096:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8097:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8100:   MatPreallocated(C);
8101:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8102:   if (P->cmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
8103:   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8104:   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8105:   if (P->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
8106:   MatPreallocated(A);

8108:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8109:   (*A->ops->ptapnumeric)(A,P,C);
8110:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8111:   return(0);
8112: }

8116: /*@
8117:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8119:    Neighbor-wise Collective on Mat

8121:    Input Parameters:
8122: +  A - the matrix
8123: -  P - the projection matrix

8125:    Output Parameters:
8126: .  C - the (i,j) structure of the product matrix

8128:    Notes:
8129:    C will be created and must be destroyed by the user with MatDestroy().

8131:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8132:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8133:    this (i,j) structure by calling MatPtAPNumeric().

8135:    Level: intermediate

8137: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8138: @*/
8139: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8140: {

8146:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8147:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8148:   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8151:   MatPreallocated(P);
8152:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8153:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8156:   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8157:   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8158:   MatPreallocated(A);
8159:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8160:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8161:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8163:   MatSetBlockSize(*C,A->rmap->bs);

8165:   return(0);
8166: }

8170: /*@
8171:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8173:    Neighbor-wise Collective on Mat

8175:    Input Parameters:
8176: +  A - the left matrix
8177: .  B - the right matrix
8178: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8179: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8180:           if the result is a dense matrix this is irrelevent

8182:    Output Parameters:
8183: .  C - the product matrix

8185:    Notes:
8186:    Unless scall is MAT_REUSE_MATRIX C will be created.

8188:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8189:    
8190:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8191:    actually needed.

8193:    If you have many matrices with the same non-zero structure to multiply, you 
8194:    should either 
8195: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8196: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8198:    Level: intermediate

8200: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
8201: @*/
8202: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8203: {
8205:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8206:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8207:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

8212:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8213:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8216:   MatPreallocated(B);
8217:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8218:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8220:   if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8221:   if (scall == MAT_REUSE_MATRIX){
8224:   }
8225:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8226:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8227:   MatPreallocated(A);

8229:   fA = A->ops->matmult;
8230:   fB = B->ops->matmult;
8231:   if (fB == fA) {
8232:     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8233:     mult = fB;
8234:   } else {
8235:     /* dispatch based on the type of A and B */
8236:     char  multname[256];
8237:     PetscStrcpy(multname,"MatMatMult_");
8238:     PetscStrcat(multname,((PetscObject)A)->type_name);
8239:     PetscStrcat(multname,"_");
8240:     PetscStrcat(multname,((PetscObject)B)->type_name);
8241:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8242:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8243:     if (!mult) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8244:   }
8245:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8246:   (*mult)(A,B,scall,fill,C);
8247:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8248:   return(0);
8249: }

8253: /*@
8254:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8255:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8257:    Neighbor-wise Collective on Mat

8259:    Input Parameters:
8260: +  A - the left matrix
8261: .  B - the right matrix
8262: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8263:       if C is a dense matrix this is irrelevent
8264:  
8265:    Output Parameters:
8266: .  C - the product matrix

8268:    Notes:
8269:    Unless scall is MAT_REUSE_MATRIX C will be created.

8271:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8272:    actually needed.

8274:    This routine is currently implemented for 
8275:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8276:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8277:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8279:    Level: intermediate

8281:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8282:      We should incorporate them into PETSc.

8284: .seealso: MatMatMult(), MatMatMultNumeric()
8285: @*/
8286: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8287: {
8289:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8290:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8291:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

8296:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8297:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8301:   MatPreallocated(B);
8302:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8303:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8306:   if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8307:   if (fill == PETSC_DEFAULT) fill = 2.0;
8308:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8309:   MatPreallocated(A);
8310: 
8311:   Asymbolic = A->ops->matmultsymbolic;
8312:   Bsymbolic = B->ops->matmultsymbolic;
8313:   if (Asymbolic == Bsymbolic){
8314:     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8315:     symbolic = Bsymbolic;
8316:   } else { /* dispatch based on the type of A and B */
8317:     char  symbolicname[256];
8318:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8319:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8320:     PetscStrcat(symbolicname,"_");
8321:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8322:     PetscStrcat(symbolicname,"_C");
8323:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8324:     if (!symbolic) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8325:   }
8326:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8327:   (*symbolic)(A,B,fill,C);
8328:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8329:   return(0);
8330: }

8334: /*@
8335:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8336:    Call this routine after first calling MatMatMultSymbolic().

8338:    Neighbor-wise Collective on Mat

8340:    Input Parameters:
8341: +  A - the left matrix
8342: -  B - the right matrix

8344:    Output Parameters:
8345: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8347:    Notes:
8348:    C must have been created with MatMatMultSymbolic().

8350:    This routine is currently implemented for 
8351:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8352:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8353:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8355:    Level: intermediate

8357: .seealso: MatMatMult(), MatMatMultSymbolic()
8358: @*/
8359: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8360: {
8362:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8363:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8364:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

8369:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8370:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8374:   MatPreallocated(B);
8375:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8376:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8380:   MatPreallocated(C);
8381:   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8382:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8384:   if (B->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
8385:   if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8386:   if (A->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
8387:   MatPreallocated(A);

8389:   Anumeric = A->ops->matmultnumeric;
8390:   Bnumeric = B->ops->matmultnumeric;
8391:   if (Anumeric == Bnumeric){
8392:     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8393:     numeric = Bnumeric;
8394:   } else {
8395:     char  numericname[256];
8396:     PetscStrcpy(numericname,"MatMatMultNumeric_");
8397:     PetscStrcat(numericname,((PetscObject)A)->type_name);
8398:     PetscStrcat(numericname,"_");
8399:     PetscStrcat(numericname,((PetscObject)B)->type_name);
8400:     PetscStrcat(numericname,"_C");
8401:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8402:     if (!numeric)
8403:       SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8404:   }
8405:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8406:   (*numeric)(A,B,C);
8407:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8408:   return(0);
8409: }

8413: /*@
8414:    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.

8416:    Neighbor-wise Collective on Mat

8418:    Input Parameters:
8419: +  A - the left matrix
8420: .  B - the right matrix
8421: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8422: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8424:    Output Parameters:
8425: .  C - the product matrix

8427:    Notes:
8428:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8430:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8432:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8433:    actually needed.

8435:    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8436:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.

8438:    Level: intermediate

8440: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
8441: @*/
8442: PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8443: {
8445:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8446:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8451:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8452:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8455:   MatPreallocated(B);
8456:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8457:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8459:   if (B->rmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
8460:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8461:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8462:   MatPreallocated(A);

8464:   fA = A->ops->matmulttranspose;
8465:   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
8466:   fB = B->ops->matmulttranspose;
8467:   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
8468:   if (fB!=fA) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

8470:   PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
8471:   (*A->ops->matmulttranspose)(A,B,scall,fill,C);
8472:   PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
8473: 
8474:   return(0);
8475: }

8479: /*@C
8480:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 

8482:    Collective on Mat

8484:    Input Parameters:
8485: +  mat - the matrix
8486: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8487: .  subcomm - MPI communicator split from the communicator where mat resides in
8488: .  mlocal_red - number of local rows of the redundant matrix
8489: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

8491:    Output Parameter:
8492: .  matredundant - redundant matrix

8494:    Notes:
8495:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the 
8496:    original matrix has not changed from that last call to MatGetRedundantMatrix().

8498:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8499:    calling it. 

8501:    Only MPIAIJ matrix is supported. 
8502:    
8503:    Level: advanced

8505:    Concepts: subcommunicator
8506:    Concepts: duplicate matrix

8508: .seealso: MatDestroy()
8509: @*/
8510: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8511: {

8516:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8519:   }
8520:   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8521:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8522:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8523:   MatPreallocated(mat);

8525:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8526:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8527:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8528:   return(0);
8529: }

8533: /*@C
8534:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8535:    a given 'mat' object. Each submatrix can span multiple procs.

8537:    Collective on Mat

8539:    Input Parameters:
8540: +  mat - the matrix
8541: -  subcomm - the subcommunicator obtained by com_split(comm)

8543:    Output Parameter:
8544: .  subMat - 'parallel submatrices each spans a given subcomm

8546:   Notes:
8547:   The submatrix partition across processors is dicated by 'subComm' a
8548:   communicator obtained by com_split(comm). The comm_split
8549:   is not restriced to be grouped with consequitive original ranks.

8551:   Due the comm_split() usage, the parallel layout of the submatrices
8552:   map directly to the layout of the original matrix [wrt the local
8553:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8554:   into the 'DiagonalMat' of the subMat, hence it is used directly from
8555:   the subMat. However the offDiagMat looses some columns - and this is
8556:   reconstructed with MatSetValues()

8558:   Level: advanced

8560:   Concepts: subcommunicator
8561:   Concepts: submatrices

8563: .seealso: MatGetSubMatrices()
8564: @*/
8565: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, Mat* subMat)
8566: {
8568:   PetscMPIInt    commsize,subCommSize;

8571:   MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
8572:   MPI_Comm_size(subComm,&subCommSize);
8573:   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
8574: 
8575:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
8576:   (*mat->ops->getmultiprocblock)(mat,subComm,subMat);
8577:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
8578:   return(0);
8579: }

8583: /*@
8584:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

8586:    Not Collective

8588:    Input Arguments:
8589:    mat - matrix to extract local submatrix from
8590:    isrow - local row indices for submatrix
8591:    iscol - local column indices for submatrix

8593:    Output Arguments:
8594:    submat - the submatrix

8596:    Level: intermediate

8598:    Notes:
8599:    The submat should be returned with MatRestoreLocalSubMatrix().

8601:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
8602:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

8604:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
8605:    MatSetValuesBlockedLocal() will also be implemented.

8607: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
8608: @*/
8609: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8610: {


8620:   if (mat->ops->getlocalsubmatrix) {
8621:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
8622:   } else {
8623:     MatCreateLocalRef(mat,isrow,iscol,submat);
8624:   }
8625:   return(0);
8626: }

8630: /*@
8631:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

8633:    Not Collective

8635:    Input Arguments:
8636:    mat - matrix to extract local submatrix from
8637:    isrow - local row indices for submatrix
8638:    iscol - local column indices for submatrix
8639:    submat - the submatrix

8641:    Level: intermediate

8643: .seealso: MatGetLocalSubMatrix()
8644: @*/
8645: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
8646: {


8657:   if (mat->ops->restorelocalsubmatrix) {
8658:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
8659:   } else {
8660:     MatDestroy(submat);
8661:   }
8662:   *submat = PETSC_NULL;
8663:   return(0);
8664: }

8666: /* --------------------------------------------------------*/
8669: /*@
8670:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

8672:    Collective on Mat

8674:    Input Parameter:
8675: .  mat - the matrix

8677:    Output Parameter:
8678: .  is - if any rows have zero diagonals this contains the list of them

8680:    Level: developer

8682:    Concepts: matrix-vector product

8684: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
8685: @*/
8686: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
8687: {

8693:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8694:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8696:   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
8697:   (*mat->ops->findzerodiagonals)(mat,is);
8698:   return(0);
8699: }

8703: /*@
8704:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

8706:   Collective on Mat

8708:   Input Parameters:
8709: . mat - the matrix

8711:   Output Parameters:
8712: . values - the block inverses in column major order (FORTRAN-like)

8714:   Level: advanced
8715: @*/
8716: PetscErrorCode  MatInvertBlockDiagonal(Mat mat,PetscScalar **values)
8717: {

8722:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8723:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8724:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
8725:   (*mat->ops->invertblockdiagonal)(mat,values);
8726:   return(0);
8727: }