Actual source code: matrix.c

petsc-3.3-p2 2012-07-13
  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

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

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

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

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

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

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

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

 48:   Level: intermediate

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

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

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

 69:    Not Collective

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

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

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

 79:    Level: advanced

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

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

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

113:    Collective on Mat

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

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

121:    Level: advanced

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

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

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

142:    Logically Collective on Mat

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

147:    Level: advanced


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

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

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

177:    Collective on Mat

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

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

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

188:    Level: advanced

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

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


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

215:    Logically Collective on Mat

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

220:    Level: advanced


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

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

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

250:    Collective on Mat

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

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

259:    Level: advanced


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

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

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

285:    Not Collective

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

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

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

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

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

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

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

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


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

335:    Level: advanced

337:    Concepts: matrices^row access

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

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

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

365:    Logically Collective on Mat

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

370:    Level: advanced

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

380:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
381:   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");
382:   (*mat->ops->conjugate)(mat);
383: #if defined(PETSC_HAVE_CUSP)
384:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
385:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
386:   }
387: #endif
388:   return(0);
389: }

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

396:    Not Collective

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

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

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

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

422:    Level: advanced

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

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

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

445:    Not Collective

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

450:    Notes:
451:    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.

453:    Level: advanced

455:    Concepts: matrices^row access

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

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

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

479:    Not Collective

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

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


488:    Level: advanced

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

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

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

510:    Logically Collective on Mat

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

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

520:    Level: advanced

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

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

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

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

542:    Logically Collective on Mat

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

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

552:    Level: advanced

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

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

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

574:    Not Collective

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

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

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

585:    Level: advanced

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

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

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

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

606:    Collective on Mat

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

611:    Notes:
612:    If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.

614:    If a suitable preallocation routine is used, this function does not need to be called.

616:    See the Performance chapter of the PETSc users manual for how to preallocate matrices

618:    Level: beginner

620: .keywords: Mat, setup

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

631:   if (!((PetscObject)A)->type_name) {
632:     MPI_Comm_size(((PetscObject)A)->comm, &size);
633:     if (size == 1) {
634:       MatSetType(A, MATSEQAIJ);
635:     } else {
636:       MatSetType(A, MATMPIAIJ);
637:     }
638:   }
639:   if (!A->preallocated && A->ops->setup) {
640:     PetscInfo(A,"Warning not preallocating matrix storage\n");
641:     (*A->ops->setup)(A);
642:   }
643:   A->preallocated = PETSC_TRUE;
644:   return(0);
645: }


650: /*@C
651:    MatView - Visualizes a matrix object.

653:    Collective on Mat

655:    Input Parameters:
656: +  mat - the matrix
657: -  viewer - visualization context

659:   Notes:
660:   The available visualization contexts include
661: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
662: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
663:         output where only the first processor opens
664:         the file.  All other processors send their 
665:         data to the first processor to print. 
666: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

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

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

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

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

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

714:    Concepts: matrices^viewing
715:    Concepts: matrices^plotting
716:    Concepts: matrices^printing

718: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 
719:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
720: @*/
721: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
722: {
723:   PetscErrorCode    ierr;
724:   PetscInt          rows,cols,bs;
725:   PetscBool         iascii;
726:   PetscViewerFormat format;

731:   if (!viewer) {
732:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
733:   }
736:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
737:   MatCheckPreallocated(mat,1);

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

783: #if defined(PETSC_USE_DEBUG)
784: #include <../src/sys/totalview/tv_data_display.h>
785: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
786: {
787:   TV_add_row("Local rows", "int", &mat->rmap->n);
788:   TV_add_row("Local columns", "int", &mat->cmap->n);
789:   TV_add_row("Global rows", "int", &mat->rmap->N);
790:   TV_add_row("Global columns", "int", &mat->cmap->N);
791:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
792:   return TV_format_OK;
793: }
794: #endif

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

804:    Collective on PetscViewer

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

811:    Options Database Keys:
812:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
813:    block size
814: .    -matload_block_size <bs>

816:    Level: beginner

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

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

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

831:    In parallel, each processor can load a subset of rows (or the
832:    entire matrix).  This routine is especially useful when a large
833:    matrix is stored on disk and only part of it is desired on each
834:    processor.  For example, a parallel solver may access only some of
835:    the rows from each processor.  The algorithm used here reads
836:    relatively small blocks of data rather than reading the entire
837:    matrix and then subsetting it.

839:    Notes for advanced users:
840:    Most users should not need to know the details of the binary storage
841:    format, since MatLoad() and MatView() completely hide these details.
842:    But for anyone who's interested, the standard binary matrix storage
843:    format is

845: $    int    MAT_FILE_CLASSID
846: $    int    number of rows
847: $    int    number of columns
848: $    int    total number of nonzeros
849: $    int    *number nonzeros in each row
850: $    int    *column indices of all nonzeros (starting index is zero)
851: $    PetscScalar *values of all nonzeros

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

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

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

863:  @*/
864: PetscErrorCode  MatLoad(Mat newmat,PetscViewer viewer)
865: {
867:   PetscBool      isbinary,flg;

872:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
873:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");

875:   if (!((PetscObject)newmat)->type_name) {
876:     MatSetType(newmat,MATAIJ);
877:   }

879:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
880:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
881:   (*newmat->ops->load)(newmat,viewer);
882:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

884:   flg  = PETSC_FALSE;
885:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,PETSC_NULL);
886:   if (flg) {
887:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
888:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
889:   }
890:   flg  = PETSC_FALSE;
891:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,PETSC_NULL);
892:   if (flg) {
893:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
894:   }
895:   return(0);
896: }

900: /*@
901:    MatDestroy - Frees space taken by a matrix.

903:    Collective on Mat

905:    Input Parameter:
906: .  A - the matrix

908:    Level: beginner

910: @*/
911: PetscErrorCode  MatDestroy(Mat *A)
912: {

916:   if (!*A) return(0);
918:   if (--((PetscObject)(*A))->refct > 0) {*A = PETSC_NULL; return(0);}
919:   /* if memory was published with AMS then destroy it */
920:   PetscObjectDepublish(*A);
921:   if ((*A)->ops->destroy) {
922:     (*(*A)->ops->destroy)(*A);
923:   }
924:   MatNullSpaceDestroy(&(*A)->nullsp);
925:   MatNullSpaceDestroy(&(*A)->nearnullsp);
926:   PetscLayoutDestroy(&(*A)->rmap);
927:   PetscLayoutDestroy(&(*A)->cmap);
928:   PetscHeaderDestroy(A);
929:   return(0);
930: }

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

939:    Not Collective

941:    Input Parameters:
942: +  mat - the matrix
943: .  v - a logically two-dimensional array of values
944: .  m, idxm - the number of rows and their global indices 
945: .  n, idxn - the number of columns and their global indices
946: -  addv - either ADD_VALUES or INSERT_VALUES, where
947:    ADD_VALUES adds values to any existing entries, and
948:    INSERT_VALUES replaces existing entries with new values

950:    Notes:
951:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 
952:       MatSetUp() before using this routine

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

956:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 
957:    options cannot be mixed without intervening calls to the assembly
958:    routines.

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

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

968:    Efficiency Alert:
969:    The routine MatSetValuesBlocked() may offer much better efficiency
970:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

972:    Level: beginner

974:    Concepts: matrices^putting entries in

976: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
977:           InsertMode, INSERT_VALUES, ADD_VALUES
978: @*/
979: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
980: {
982: #if defined(PETSC_USE_DEBUG)
983:   PetscInt i,j;
984: #endif

989:   if (!m || !n) return(0); /* no values to insert */
993:   MatCheckPreallocated(mat,1);
994:   if (mat->insertmode == NOT_SET_VALUES) {
995:     mat->insertmode = addv;
996:   }
997: #if defined(PETSC_USE_DEBUG)
998:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
999:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1000:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

1002:   if (v) {
1003:     for (i=0; i<m; i++) {
1004:       for (j=0; j<n; j++) {
1005:         if (PetscIsInfOrNanScalar(v[i*n+j]))
1006: #if defined(PETSC_USE_COMPLEX)
1007:           SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G+iG at matrix entry (%D,%D)",PetscRealPart(v[i*n+j]),PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1008: #else
1009:           SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G at matrix entry (%D,%D)",(PetscReal)v[i*n+j],idxm[i],idxn[j]);
1010: #endif
1011:       }
1012:     }
1013:   }
1014: #endif

1016:   if (mat->assembled) {
1017:     mat->was_assembled = PETSC_TRUE;
1018:     mat->assembled     = PETSC_FALSE;
1019:   }
1020:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1021:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1022:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1023: #if defined(PETSC_HAVE_CUSP)
1024:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1025:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1026:   }
1027: #endif
1028:   return(0);
1029: }


1034: /*@ 
1035:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1036:         values into a matrix

1038:    Not Collective

1040:    Input Parameters:
1041: +  mat - the matrix
1042: .  row - the (block) row to set
1043: -  v - a logically two-dimensional array of values

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

1048:    All the nonzeros in the row must be provided

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

1052:    The row must belong to this process

1054:    Level: intermediate

1056:    Concepts: matrices^putting entries in

1058: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1059:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1060: @*/
1061: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1062: {

1069:   MatSetValuesRow(mat, mat->rmap->mapping->indices[row],v);
1070: #if defined(PETSC_HAVE_CUSP)
1071:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1072:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1073:   }
1074: #endif
1075:   return(0);
1076: }

1080: /*@ 
1081:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1082:         values into a matrix

1084:    Not Collective

1086:    Input Parameters:
1087: +  mat - the matrix
1088: .  row - the (block) row to set
1089: -  v - a logically two-dimensional array of values

1091:    Notes:
1092:    The values, v, are column-oriented for the block version.

1094:    All the nonzeros in the row must be provided

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

1098:    The row must belong to this process

1100:    Level: advanced

1102:    Concepts: matrices^putting entries in

1104: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1105:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1106: @*/
1107: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1108: {

1114:   MatCheckPreallocated(mat,1);
1116: #if defined(PETSC_USE_DEBUG)
1117:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1118:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1119: #endif
1120:   mat->insertmode = INSERT_VALUES;

1122:   if (mat->assembled) {
1123:     mat->was_assembled = PETSC_TRUE;
1124:     mat->assembled     = PETSC_FALSE;
1125:   }
1126:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1127:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1128:   (*mat->ops->setvaluesrow)(mat,row,v);
1129:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1130: #if defined(PETSC_HAVE_CUSP)
1131:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1132:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1133:   }
1134: #endif
1135:   return(0);
1136: }

1140: /*@
1141:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1142:      Using structured grid indexing

1144:    Not Collective

1146:    Input Parameters:
1147: +  mat - the matrix
1148: .  m - number of rows being entered
1149: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1150: .  n - number of columns being entered
1151: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 
1152: .  v - a logically two-dimensional array of values
1153: -  addv - either ADD_VALUES or INSERT_VALUES, where
1154:    ADD_VALUES adds values to any existing entries, and
1155:    INSERT_VALUES replaces existing entries with new values

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

1160:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 
1161:    options cannot be mixed without intervening calls to the assembly
1162:    routines.

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

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

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

1171:    In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1172:    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.

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

1180:    In Fortran idxm and idxn should be declared as
1181: $     MatStencil idxm(4,m),idxn(4,n)
1182:    and the values inserted using
1183: $    idxm(MatStencil_i,1) = i
1184: $    idxm(MatStencil_j,1) = j
1185: $    idxm(MatStencil_k,1) = k
1186: $    idxm(MatStencil_c,1) = c
1187:    etc
1188:  
1189:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 
1190:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1191:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1192:    DMDA_BOUNDARY_PERIODIC boundary type.

1194:    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
1195:    a single value per point) you can skip filling those indices.

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

1200:    Efficiency Alert:
1201:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1202:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1204:    Level: beginner

1206:    Concepts: matrices^putting entries in

1208: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1209:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1210: @*/
1211: PetscErrorCode  MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1212: {
1214:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1215:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1216:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1226:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1227:     jdxm = buf; jdxn = buf+m;
1228:   } else {
1229:     PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1230:     jdxm = bufm; jdxn = bufn;
1231:   }
1232:   for (i=0; i<m; i++) {
1233:     for (j=0; j<3-sdim; j++) dxm++;
1234:     tmp = *dxm++ - starts[0];
1235:     for (j=0; j<dim-1; j++) {
1236:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1237:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1238:     }
1239:     if (mat->stencil.noc) dxm++;
1240:     jdxm[i] = tmp;
1241:   }
1242:   for (i=0; i<n; i++) {
1243:     for (j=0; j<3-sdim; j++) dxn++;
1244:     tmp = *dxn++ - starts[0];
1245:     for (j=0; j<dim-1; j++) {
1246:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1247:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1248:     }
1249:     if (mat->stencil.noc) dxn++;
1250:     jdxn[i] = tmp;
1251:   }
1252:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1253:   PetscFree2(bufm,bufn);
1254:   return(0);
1255: }

1259: /*@C 
1260:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1261:      Using structured grid indexing

1263:    Not Collective

1265:    Input Parameters:
1266: +  mat - the matrix
1267: .  m - number of rows being entered
1268: .  idxm - grid coordinates for matrix rows being entered
1269: .  n - number of columns being entered
1270: .  idxn - grid coordinates for matrix columns being entered 
1271: .  v - a logically two-dimensional array of values
1272: -  addv - either ADD_VALUES or INSERT_VALUES, where
1273:    ADD_VALUES adds values to any existing entries, and
1274:    INSERT_VALUES replaces existing entries with new values

1276:    Notes:
1277:    By default the values, v, are row-oriented and unsorted.
1278:    See MatSetOption() for other options.

1280:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 
1281:    options cannot be mixed without intervening calls to the assembly
1282:    routines.

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

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

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

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

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

1300:    In Fortran idxm and idxn should be declared as
1301: $     MatStencil idxm(4,m),idxn(4,n)
1302:    and the values inserted using
1303: $    idxm(MatStencil_i,1) = i
1304: $    idxm(MatStencil_j,1) = j
1305: $    idxm(MatStencil_k,1) = k
1306:    etc

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

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

1316:    Level: beginner

1318:    Concepts: matrices^putting entries in

1320: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1321:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1322:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1323: @*/
1324: PetscErrorCode  MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1325: {
1327:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1328:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1329:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1339:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1340:     jdxm = buf; jdxn = buf+m;
1341:   } else {
1342:     PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1343:     jdxm = bufm; jdxn = bufn;
1344:   }
1345:   for (i=0; i<m; i++) {
1346:     for (j=0; j<3-sdim; j++) dxm++;
1347:     tmp = *dxm++ - starts[0];
1348:     for (j=0; j<sdim-1; j++) {
1349:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1350:       else                                      tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1351:     }
1352:     dxm++;
1353:     jdxm[i] = tmp;
1354:   }
1355:   for (i=0; i<n; i++) {
1356:     for (j=0; j<3-sdim; j++) dxn++;
1357:     tmp = *dxn++ - starts[0];
1358:     for (j=0; j<sdim-1; j++) {
1359:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1360:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1361:     }
1362:     dxn++;
1363:     jdxn[i] = tmp;
1364:   }
1365:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1366:   PetscFree2(bufm,bufn);
1367: #if defined(PETSC_HAVE_CUSP)
1368:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1369:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1370:   }
1371: #endif
1372:   return(0);
1373: }

1377: /*@ 
1378:    MatSetStencil - Sets the grid information for setting values into a matrix via
1379:         MatSetValuesStencil()

1381:    Not Collective

1383:    Input Parameters:
1384: +  mat - the matrix
1385: .  dim - dimension of the grid 1, 2, or 3
1386: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1387: .  starts - starting point of ghost nodes on your processor in x, y, and z direction 
1388: -  dof - number of degrees of freedom per node


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

1394:    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1395:    user.
1396:    
1397:    Level: beginner

1399:    Concepts: matrices^putting entries in

1401: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1402:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1403: @*/
1404: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1405: {
1406:   PetscInt i;


1413:   mat->stencil.dim = dim + (dof > 1);
1414:   for (i=0; i<dim; i++) {
1415:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1416:     mat->stencil.starts[i] = starts[dim-i-1];
1417:   }
1418:   mat->stencil.dims[dim]   = dof;
1419:   mat->stencil.starts[dim] = 0;
1420:   mat->stencil.noc         = (PetscBool)(dof == 1);
1421:   return(0);
1422: }

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

1429:    Not Collective

1431:    Input Parameters:
1432: +  mat - the matrix
1433: .  v - a logically two-dimensional array of values
1434: .  m, idxm - the number of block rows and their global block indices 
1435: .  n, idxn - the number of block columns and their global block indices
1436: -  addv - either ADD_VALUES or INSERT_VALUES, where
1437:    ADD_VALUES adds values to any existing entries, and
1438:    INSERT_VALUES replaces existing entries with new values

1440:    Notes:
1441:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1442:    MatXXXXSetPreallocation() or MatSetUp() before using this routine.

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

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

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

1456:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
1457:    options cannot be mixed without intervening calls to the assembly
1458:    routines.

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

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

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

1474:    Example:
1475: $   Suppose m=n=2 and block size(bs) = 2 The array is 
1476: $
1477: $   1  2  | 3  4
1478: $   5  6  | 7  8
1479: $   - - - | - - -
1480: $   9  10 | 11 12
1481: $   13 14 | 15 16
1482: $
1483: $   v[] should be passed in like
1484: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1485: $
1486: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1487: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1489:    Level: intermediate

1491:    Concepts: matrices^putting entries in blocked

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

1502:   if (!m || !n) return(0); /* no values to insert */
1506:   MatCheckPreallocated(mat,1);
1507:   if (mat->insertmode == NOT_SET_VALUES) {
1508:     mat->insertmode = addv;
1509:   }
1510: #if defined(PETSC_USE_DEBUG)
1511:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1512:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1513:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1514: #endif

1516:   if (mat->assembled) {
1517:     mat->was_assembled = PETSC_TRUE;
1518:     mat->assembled     = PETSC_FALSE;
1519:   }
1520:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1521:   if (mat->ops->setvaluesblocked) {
1522:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1523:   } else {
1524:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1525:     PetscInt i,j,bs=mat->rmap->bs;
1526:     if ((m+n)*bs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1527:       iidxm = buf; iidxn = buf + m*bs;
1528:     } else {
1529:       PetscMalloc2(m*bs,PetscInt,&bufr,n*bs,PetscInt,&bufc);
1530:       iidxm = bufr; iidxn = bufc;
1531:     }
1532:     for (i=0; i<m; i++)
1533:       for (j=0; j<bs; j++)
1534:         iidxm[i*bs+j] = bs*idxm[i] + j;
1535:     for (i=0; i<n; i++)
1536:       for (j=0; j<bs; j++)
1537:         iidxn[i*bs+j] = bs*idxn[i] + j;
1538:     MatSetValues(mat,m*bs,iidxm,n*bs,iidxn,v,addv);
1539:     PetscFree2(bufr,bufc);
1540:   }
1541:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1542: #if defined(PETSC_HAVE_CUSP)
1543:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1544:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1545:   }
1546: #endif
1547:   return(0);
1548: }

1552: /*@ 
1553:    MatGetValues - Gets a block of values from a matrix.

1555:    Not Collective; currently only returns a local block

1557:    Input Parameters:
1558: +  mat - the matrix
1559: .  v - a logically two-dimensional array for storing the values
1560: .  m, idxm - the number of rows and their global indices 
1561: -  n, idxn - the number of columns and their global indices

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

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

1571:    MatGetValues() requires that the matrix has been assembled
1572:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1573:    MatSetValues() and MatGetValues() CANNOT be made in succession
1574:    without intermediate matrix assembly.

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

1579:    Level: advanced

1581:    Concepts: matrices^accessing values

1583: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1584: @*/
1585: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1586: {

1592:   if (!m || !n) return(0);
1596:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1597:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1598:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1599:   MatCheckPreallocated(mat,1);

1601:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1602:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1603:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1604:   return(0);
1605: }

1609: /*@
1610:   MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1611:   the same size. Currently, this can only be called once and creates the given matrix.

1613:   Not Collective

1615:   Input Parameters:
1616: + mat - the matrix
1617: . nb - the number of blocks
1618: . bs - the number of rows (and columns) in each block
1619: . rows - a concatenation of the rows for each block
1620: - v - a concatenation of logically two-dimensional arrays of values

1622:   Notes:
1623:   In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.

1625:   Level: advanced

1627:   Concepts: matrices^putting entries in

1629: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1630:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1631: @*/
1632: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1633: {

1641: #if defined(PETSC_USE_DEBUG)
1642:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1643: #endif

1645:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1646:   if (mat->ops->setvaluesbatch) {
1647:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1648:   } else {
1649:     PetscInt b;
1650:     for(b = 0; b < nb; ++b) {
1651:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1652:     }
1653:   }
1654:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1655:   return(0);
1656: }

1660: /*@
1661:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1662:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1663:    using a local (per-processor) numbering.

1665:    Not Collective

1667:    Input Parameters:
1668: +  x - the matrix
1669: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1670:              or ISLocalToGlobalMappingCreateIS()
1671: - cmapping - column mapping

1673:    Level: intermediate

1675:    Concepts: matrices^local to global mapping
1676:    Concepts: local to global mapping^for matrices

1678: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1679: @*/
1680: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1681: {

1689:   if (x->ops->setlocaltoglobalmapping) {
1690:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1691:   } else {
1692:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1693:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1694:   }
1695:   return(0);
1696: }

1700: /*@
1701:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1702:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1703:    entries using a local (per-processor) numbering.

1705:    Not Collective

1707:    Input Parameters:
1708: +  x - the matrix
1709: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1710:              ISLocalToGlobalMappingCreateIS()
1711: - cmapping - column mapping

1713:    Level: intermediate

1715:    Concepts: matrices^local to global mapping blocked
1716:    Concepts: local to global mapping^for matrices, blocked

1718: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1719:            MatSetValuesBlocked(), MatSetValuesLocal()
1720: @*/
1721: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1722: {

1730:   PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1731:   PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1732:   return(0);
1733: }

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

1740:    Not Collective

1742:    Input Parameters:
1743: .  A - the matrix

1745:    Output Parameters:
1746: + rmapping - row mapping
1747: - cmapping - column mapping

1749:    Level: advanced

1751:    Concepts: matrices^local to global mapping
1752:    Concepts: local to global mapping^for matrices

1754: .seealso:  MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1755: @*/
1756: PetscErrorCode  MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1757: {
1763:   if (rmapping) *rmapping = A->rmap->mapping;
1764:   if (cmapping) *cmapping = A->cmap->mapping;
1765:   return(0);
1766: }

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

1773:    Not Collective

1775:    Input Parameters:
1776: .  A - the matrix

1778:    Output Parameters:
1779: + rmapping - row mapping
1780: - cmapping - column mapping

1782:    Level: advanced

1784:    Concepts: matrices^local to global mapping blocked
1785:    Concepts: local to global mapping^for matrices, blocked

1787: .seealso:  MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1788: @*/
1789: PetscErrorCode  MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1790: {
1796:   if (rmapping) *rmapping = A->rmap->bmapping;
1797:   if (cmapping) *cmapping = A->cmap->bmapping;
1798:   return(0);
1799: }

1803: /*@
1804:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1805:    using a local ordering of the nodes. 

1807:    Not Collective

1809:    Input Parameters:
1810: +  x - the matrix
1811: .  nrow, irow - number of rows and their local indices
1812: .  ncol, icol - number of columns and their local indices
1813: .  y -  a logically two-dimensional array of values
1814: -  addv - either INSERT_VALUES or ADD_VALUES, where
1815:    ADD_VALUES adds values to any existing entries, and
1816:    INSERT_VALUES replaces existing entries with new values

1818:    Notes:
1819:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 
1820:       MatSetUp() before using this routine

1822:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine

1824:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
1825:    options cannot be mixed without intervening calls to the assembly
1826:    routines.

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

1831:    Level: intermediate

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

1835: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1836:            MatSetValueLocal()
1837: @*/
1838: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1839: {

1845:   MatCheckPreallocated(mat,1);
1846:   if (!nrow || !ncol) return(0); /* no values to insert */
1850:   if (mat->insertmode == NOT_SET_VALUES) {
1851:     mat->insertmode = addv;
1852:   }
1853: #if defined(PETSC_USE_DEBUG)
1854:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1855:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1856:   if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1857: #endif

1859:   if (mat->assembled) {
1860:     mat->was_assembled = PETSC_TRUE;
1861:     mat->assembled     = PETSC_FALSE;
1862:   }
1863:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1864:   if (mat->ops->setvalueslocal) {
1865:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1866:   } else {
1867:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1868:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1869:       irowm = buf; icolm = buf+nrow;
1870:     } else {
1871:       PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1872:       irowm = bufr; icolm = bufc;
1873:     }
1874:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1875:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1876:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1877:     PetscFree2(bufr,bufc);
1878:   }
1879:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1880: #if defined(PETSC_HAVE_CUSP)
1881:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1882:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1883:   }
1884: #endif
1885:   return(0);
1886: }

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

1894:    Not Collective

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

1905:    Notes:
1906:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 
1907:       MatSetUp() before using this routine

1909:    If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMappingBlock() 
1910:       before using this routineBefore calling MatSetValuesLocal(), the user must first set the

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

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

1919:    Level: intermediate

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

1923: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
1924:            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1925: @*/
1926: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1927: {

1933:   MatCheckPreallocated(mat,1);
1934:   if (!nrow || !ncol) return(0); /* no values to insert */
1938:   if (mat->insertmode == NOT_SET_VALUES) {
1939:     mat->insertmode = addv;
1940:   }
1941: #if defined(PETSC_USE_DEBUG)
1942:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1943:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1944:   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);
1945: #endif

1947:   if (mat->assembled) {
1948:     mat->was_assembled = PETSC_TRUE;
1949:     mat->assembled     = PETSC_FALSE;
1950:   }
1951:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1952:   if (mat->ops->setvaluesblockedlocal) {
1953:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
1954:   } else {
1955:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1956:     if (mat->rmap->bmapping && mat->cmap->bmapping) {
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->bmapping,nrow,irow,irowm);
1964:       ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
1965:       MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
1966:       PetscFree2(bufr,bufc);
1967:     } else {
1968:       PetscInt i,j,bs=mat->rmap->bs;
1969:       if ((nrow+ncol)*bs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1970:         irowm = buf; icolm = buf + nrow;
1971:       } else {
1972:         PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*bs,PetscInt,&bufc);
1973:         irowm = bufr; icolm = bufc;
1974:       }
1975:       for (i=0; i<nrow; i++)
1976:         for (j=0; j<bs; j++)
1977:           irowm[i*bs+j] = irow[i]*bs+j;
1978:       for (i=0; i<ncol; i++)
1979:         for (j=0; j<bs; j++)
1980:           icolm[i*bs+j] = icol[i]*bs+j;
1981:       MatSetValuesLocal(mat,nrow*bs,irowm,ncol*bs,icolm,y,addv);
1982:       PetscFree2(bufr,bufc);
1983:     }
1984:   }
1985:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1986: #if defined(PETSC_HAVE_CUSP)
1987:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1988:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1989:   }
1990: #endif
1991:   return(0);
1992: }

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

1999:    Collective on Mat and Vec

2001:    Input Parameters:
2002: +  mat - the matrix
2003: -  x   - the vector to be multiplied

2005:    Output Parameters:
2006: .  y - the result

2008:    Notes:
2009:    The vectors x and y cannot be the same.  I.e., one cannot
2010:    call MatMult(A,y,y).

2012:    Level: developer

2014:    Concepts: matrix-vector product

2016: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2017: @*/
2018: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2019: {


2028:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2029:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2030:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2031:   MatCheckPreallocated(mat,1);

2033:   if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2034:   (*mat->ops->multdiagonalblock)(mat,x,y);
2035:   PetscObjectStateIncrease((PetscObject)y);
2036:   return(0);
2037: }

2039: /* --------------------------------------------------------*/
2042: /*@
2043:    MatMult - Computes the matrix-vector product, y = Ax.

2045:    Neighbor-wise Collective on Mat and Vec

2047:    Input Parameters:
2048: +  mat - the matrix
2049: -  x   - the vector to be multiplied

2051:    Output Parameters:
2052: .  y - the result

2054:    Notes:
2055:    The vectors x and y cannot be the same.  I.e., one cannot
2056:    call MatMult(A,y,y).

2058:    Level: beginner

2060:    Concepts: matrix-vector product

2062: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2063: @*/
2064: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
2065: {

2073:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2074:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2075:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2076: #ifndef PETSC_HAVE_CONSTRAINTS
2077:   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);
2078:   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);
2079:   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);
2080: #endif
2081:   VecValidValues(x,2,PETSC_TRUE);
2082:   MatCheckPreallocated(mat,1);

2084:   if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2085:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2086:   (*mat->ops->mult)(mat,x,y);
2087:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2088:   VecValidValues(y,3,PETSC_FALSE);
2089:   return(0);
2090: }

2094: /*@
2095:    MatMultTranspose - Computes matrix transpose times a vector.

2097:    Neighbor-wise Collective on Mat and Vec

2099:    Input Parameters:
2100: +  mat - the matrix
2101: -  x   - the vector to be multilplied

2103:    Output Parameters:
2104: .  y - the result

2106:    Notes:
2107:    The vectors x and y cannot be the same.  I.e., one cannot
2108:    call MatMultTranspose(A,y,y).

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

2113:    Level: beginner

2115:    Concepts: matrix vector product^transpose

2117: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2118: @*/
2119: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2120: {


2129:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2130:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2131:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2132: #ifndef PETSC_HAVE_CONSTRAINTS
2133:   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);
2134:   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);
2135: #endif
2136:   VecValidValues(x,2,PETSC_TRUE);
2137:   MatCheckPreallocated(mat,1);

2139:   if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2140:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2141:   (*mat->ops->multtranspose)(mat,x,y);
2142:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2143:   PetscObjectStateIncrease((PetscObject)y);
2144:   VecValidValues(y,3,PETSC_FALSE);
2145:   return(0);
2146: }

2150: /*@
2151:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2153:    Neighbor-wise Collective on Mat and Vec

2155:    Input Parameters:
2156: +  mat - the matrix
2157: -  x   - the vector to be multilplied

2159:    Output Parameters:
2160: .  y - the result

2162:    Notes:
2163:    The vectors x and y cannot be the same.  I.e., one cannot
2164:    call MatMultHermitianTranspose(A,y,y).

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

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

2170:    Level: beginner

2172:    Concepts: matrix vector product^transpose

2174: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2175: @*/
2176: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2177: {


2186:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2187:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2188:   if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2189: #ifndef PETSC_HAVE_CONSTRAINTS
2190:   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);
2191:   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);
2192: #endif
2193:   MatCheckPreallocated(mat,1);

2195:   if (!mat->ops->multhermitiantranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2196:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2197:   (*mat->ops->multhermitiantranspose)(mat,x,y);
2198:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2199:   PetscObjectStateIncrease((PetscObject)y);
2200:   return(0);
2201: }

2205: /*@
2206:     MatMultAdd -  Computes v3 = v2 + A * v1.

2208:     Neighbor-wise Collective on Mat and Vec

2210:     Input Parameters:
2211: +   mat - the matrix
2212: -   v1, v2 - the vectors

2214:     Output Parameters:
2215: .   v3 - the result

2217:     Notes:
2218:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2219:     call MatMultAdd(A,v1,v2,v1).

2221:     Level: beginner

2223:     Concepts: matrix vector product^addition

2225: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2226: @*/
2227: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2228: {


2238:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2239:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2240:   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);
2241:   /* 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);
2242:      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); */
2243:   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);
2244:   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);
2245:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2246:   MatCheckPreallocated(mat,1);

2248:   if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2249:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2250:   (*mat->ops->multadd)(mat,v1,v2,v3);
2251:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2252:   PetscObjectStateIncrease((PetscObject)v3);
2253:   return(0);
2254: }

2258: /*@
2259:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2261:    Neighbor-wise Collective on Mat and Vec

2263:    Input Parameters:
2264: +  mat - the matrix
2265: -  v1, v2 - the vectors

2267:    Output Parameters:
2268: .  v3 - the result

2270:    Notes:
2271:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2272:    call MatMultTransposeAdd(A,v1,v2,v1).

2274:    Level: beginner

2276:    Concepts: matrix vector product^transpose and addition

2278: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2279: @*/
2280: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2281: {


2291:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2292:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2293:   if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2294:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2295:   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);
2296:   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);
2297:   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);
2298:   MatCheckPreallocated(mat,1);

2300:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2301:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2302:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2303:   PetscObjectStateIncrease((PetscObject)v3);
2304:   return(0);
2305: }

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

2312:    Neighbor-wise Collective on Mat and Vec

2314:    Input Parameters:
2315: +  mat - the matrix
2316: -  v1, v2 - the vectors

2318:    Output Parameters:
2319: .  v3 - the result

2321:    Notes:
2322:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2323:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2325:    Level: beginner

2327:    Concepts: matrix vector product^transpose and addition

2329: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2330: @*/
2331: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2332: {


2342:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2343:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2344:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2345:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2346:   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);
2347:   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);
2348:   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);
2349:   MatCheckPreallocated(mat,1);

2351:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2352:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2353:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2354:   PetscObjectStateIncrease((PetscObject)v3);
2355:   return(0);
2356: }

2360: /*@
2361:    MatMultConstrained - The inner multiplication routine for a
2362:    constrained matrix P^T A P.

2364:    Neighbor-wise Collective on Mat and Vec

2366:    Input Parameters:
2367: +  mat - the matrix
2368: -  x   - the vector to be multilplied

2370:    Output Parameters:
2371: .  y - the result

2373:    Notes:
2374:    The vectors x and y cannot be the same.  I.e., one cannot
2375:    call MatMult(A,y,y).

2377:    Level: beginner

2379: .keywords: matrix, multiply, matrix-vector product, constraint
2380: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2381: @*/
2382: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2383: {

2390:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2391:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2392:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2393:   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);
2394:   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);
2395:   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);

2397:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2398:   (*mat->ops->multconstrained)(mat,x,y);
2399:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2400:   PetscObjectStateIncrease((PetscObject)y);

2402:   return(0);
2403: }

2407: /*@
2408:    MatMultTransposeConstrained - The inner multiplication routine for a
2409:    constrained matrix P^T A^T P.

2411:    Neighbor-wise Collective on Mat and Vec

2413:    Input Parameters:
2414: +  mat - the matrix
2415: -  x   - the vector to be multilplied

2417:    Output Parameters:
2418: .  y - the result

2420:    Notes:
2421:    The vectors x and y cannot be the same.  I.e., one cannot
2422:    call MatMult(A,y,y).

2424:    Level: beginner

2426: .keywords: matrix, multiply, matrix-vector product, constraint
2427: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2428: @*/
2429: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2430: {

2437:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2438:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2439:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2440:   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);
2441:   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);

2443:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2444:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2445:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2446:   PetscObjectStateIncrease((PetscObject)y);

2448:   return(0);
2449: }

2453: /*@C
2454:    MatGetFactorType - gets the type of factorization it is

2456:    Note Collective
2457:    as the flag

2459:    Input Parameters:
2460: .  mat - the matrix

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

2465:     Level: intermediate

2467: .seealso:    MatFactorType, MatGetFactor()
2468: @*/
2469: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2470: {
2474:   *t = mat->factortype;
2475:   return(0);
2476: }

2478: /* ------------------------------------------------------------*/
2481: /*@C
2482:    MatGetInfo - Returns information about matrix storage (number of
2483:    nonzeros, memory, etc.).

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

2487:    Input Parameters:
2488: .  mat - the matrix

2490:    Output Parameters:
2491: +  flag - flag indicating the type of parameters to be returned
2492:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2493:    MAT_GLOBAL_SUM - sum over all processors)
2494: -  info - matrix information context

2496:    Notes:
2497:    The MatInfo context contains a variety of matrix data, including
2498:    number of nonzeros allocated and used, number of mallocs during
2499:    matrix assembly, etc.  Additional information for factored matrices
2500:    is provided (such as the fill ratio, number of mallocs during
2501:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2502:    when using the runtime options 
2503: $       -info -mat_view_info

2505:    Example for C/C++ Users:
2506:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2507:    data within the MatInfo context.  For example, 
2508: .vb
2509:       MatInfo info;
2510:       Mat     A;
2511:       double  mal, nz_a, nz_u;

2513:       MatGetInfo(A,MAT_LOCAL,&info);
2514:       mal  = info.mallocs;
2515:       nz_a = info.nz_allocated;
2516: .ve

2518:    Example for Fortran Users:
2519:    Fortran users should declare info as a double precision
2520:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2521:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2522:    a complete list of parameter names.
2523: .vb
2524:       double  precision info(MAT_INFO_SIZE)
2525:       double  precision mal, nz_a
2526:       Mat     A
2527:       integer ierr

2529:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2530:       mal = info(MAT_INFO_MALLOCS)
2531:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2532: .ve

2534:     Level: intermediate

2536:     Concepts: matrices^getting information on
2537:     
2538:     Developer Note: fortran interface is not autogenerated as the f90
2539:     interface defintion cannot be generated correctly [due to MatInfo]

2541: .seealso: MatStashGetInfo()
2542:  
2543: @*/
2544: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2545: {

2552:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2553:   MatCheckPreallocated(mat,1);
2554:   (*mat->ops->getinfo)(mat,flag,info);
2555:   return(0);
2556: }

2558: /* ----------------------------------------------------------*/

2562: /*@C
2563:    MatLUFactor - Performs in-place LU factorization of matrix.

2565:    Collective on Mat

2567:    Input Parameters:
2568: +  mat - the matrix
2569: .  row - row permutation
2570: .  col - column permutation
2571: -  info - options for factorization, includes 
2572: $          fill - expected fill as ratio of original fill.
2573: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2574: $                   Run with the option -info to determine an optimal value to use

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

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

2584:    Level: developer

2586:    Concepts: matrices^LU factorization

2588: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2589:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2594: @*/
2595: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2596: {
2598:   MatFactorInfo  tinfo;

2606:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2607:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2608:   if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2609:   MatCheckPreallocated(mat,1);
2610:   if (!info) {
2611:     MatFactorInfoInitialize(&tinfo);
2612:     info = &tinfo;
2613:   }

2615:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2616:   (*mat->ops->lufactor)(mat,row,col,info);
2617:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2618:   PetscObjectStateIncrease((PetscObject)mat);
2619:   return(0);
2620: }

2624: /*@C
2625:    MatILUFactor - Performs in-place ILU factorization of matrix.

2627:    Collective on Mat

2629:    Input Parameters:
2630: +  mat - the matrix
2631: .  row - row permutation
2632: .  col - column permutation
2633: -  info - structure containing 
2634: $      levels - number of levels of fill.
2635: $      expected fill - as ratio of original fill.
2636: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2637:                 missing diagonal entries)

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

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

2647:    Level: developer

2649:    Concepts: matrices^ILU factorization

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

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

2656: @*/
2657: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2658: {

2667:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
2668:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2669:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2670:   if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2671:   MatCheckPreallocated(mat,1);

2673:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2674:   (*mat->ops->ilufactor)(mat,row,col,info);
2675:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2676:   PetscObjectStateIncrease((PetscObject)mat);
2677:   return(0);
2678: }

2682: /*@C
2683:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2684:    Call this routine before calling MatLUFactorNumeric().

2686:    Collective on Mat

2688:    Input Parameters:
2689: +  fact - the factor matrix obtained with MatGetFactor()
2690: .  mat - the matrix
2691: .  row, col - row and column permutations
2692: -  info - options for factorization, includes 
2693: $          fill - expected fill as ratio of original fill.
2694: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2695: $                   Run with the option -info to determine an optimal value to use


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

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

2706:    Level: developer

2708:    Concepts: matrices^LU symbolic factorization

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

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

2715: @*/
2716: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2717: {

2727:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2728:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2729:   if (!(fact)->ops->lufactorsymbolic) {
2730:     const MatSolverPackage spackage;
2731:     MatFactorGetSolverPackage(fact,&spackage);
2732:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2733:   }
2734:   MatCheckPreallocated(mat,2);

2736:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2737:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2738:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2739:   PetscObjectStateIncrease((PetscObject)fact);
2740:   return(0);
2741: }

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

2749:    Collective on Mat

2751:    Input Parameters:
2752: +  fact - the factor matrix obtained with MatGetFactor()
2753: .  mat - the matrix
2754: -  info - options for factorization

2756:    Notes:
2757:    See MatLUFactor() for in-place factorization.  See 
2758:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

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

2764:    Level: developer

2766:    Concepts: matrices^LU numeric factorization

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

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

2773: @*/
2774: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2775: {

2783:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2784:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2785:     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);
2786:   }
2787:   if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2788:   MatCheckPreallocated(mat,2);
2789:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2790:   (fact->ops->lufactornumeric)(fact,mat,info);
2791:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

2793:   MatView_Private(fact);
2794:   PetscObjectStateIncrease((PetscObject)fact);
2795:   return(0);
2796: }

2800: /*@C
2801:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2802:    symmetric matrix. 

2804:    Collective on Mat

2806:    Input Parameters:
2807: +  mat - the matrix
2808: .  perm - row and column permutations
2809: -  f - expected fill as ratio of original fill

2811:    Notes:
2812:    See MatLUFactor() for the nonsymmetric case.  See also
2813:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2819:    Level: developer

2821:    Concepts: matrices^Cholesky factorization

2823: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2824:           MatGetOrdering()

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

2829: @*/
2830: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2831: {

2839:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2840:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2841:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2842:   if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2843:   MatCheckPreallocated(mat,1);

2845:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2846:   (*mat->ops->choleskyfactor)(mat,perm,info);
2847:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2848:   PetscObjectStateIncrease((PetscObject)mat);
2849:   return(0);
2850: }

2854: /*@C
2855:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2856:    of a symmetric matrix. 

2858:    Collective on Mat

2860:    Input Parameters:
2861: +  fact - the factor matrix obtained with MatGetFactor()
2862: .  mat - the matrix
2863: .  perm - row and column permutations
2864: -  info - options for factorization, includes 
2865: $          fill - expected fill as ratio of original fill.
2866: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2867: $                   Run with the option -info to determine an optimal value to use

2869:    Notes:
2870:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2871:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2877:    Level: developer

2879:    Concepts: matrices^Cholesky symbolic factorization

2881: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2882:           MatGetOrdering()

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

2887: @*/
2888: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2889: {

2898:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2899:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2900:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2901:   if (!(fact)->ops->choleskyfactorsymbolic) {
2902:     const MatSolverPackage spackage;
2903:     MatFactorGetSolverPackage(fact,&spackage);
2904:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
2905:   }
2906:   MatCheckPreallocated(mat,2);

2908:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2909:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2910:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2911:   PetscObjectStateIncrease((PetscObject)fact);
2912:   return(0);
2913: }

2917: /*@C
2918:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2919:    of a symmetric matrix. Call this routine after first calling
2920:    MatCholeskyFactorSymbolic().

2922:    Collective on Mat

2924:    Input Parameters:
2925: +  fact - the factor matrix obtained with MatGetFactor()
2926: .  mat - the initial matrix
2927: .  info - options for factorization
2928: -  fact - the symbolic factor of mat


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

2936:    Level: developer

2938:    Concepts: matrices^Cholesky numeric factorization

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

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

2945: @*/
2946: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2947: {

2955:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2956:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
2957:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2958:     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);
2959:   }
2960:   MatCheckPreallocated(mat,2);

2962:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2963:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
2964:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

2966:   MatView_Private(fact);
2967:   PetscObjectStateIncrease((PetscObject)fact);
2968:   return(0);
2969: }

2971: /* ----------------------------------------------------------------*/
2974: /*@
2975:    MatSolve - Solves A x = b, given a factored matrix.

2977:    Neighbor-wise Collective on Mat and Vec

2979:    Input Parameters:
2980: +  mat - the factored matrix
2981: -  b - the right-hand-side vector

2983:    Output Parameter:
2984: .  x - the result vector

2986:    Notes:
2987:    The vectors b and x cannot be the same.  I.e., one cannot
2988:    call MatSolve(A,x,x).

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

2995:    Level: developer

2997:    Concepts: matrices^triangular solves

2999: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3000: @*/
3001: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3002: {

3012:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3013:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3014:   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);
3015:   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);
3016:   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);
3017:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3018:   if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3019:   MatCheckPreallocated(mat,1);

3021:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3022:   (*mat->ops->solve)(mat,b,x);
3023:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3024:   PetscObjectStateIncrease((PetscObject)x);
3025:   return(0);
3026: }

3030: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3031: {
3033:   Vec            b,x;
3034:   PetscInt       m,N,i;
3035:   PetscScalar    *bb,*xx;
3036:   PetscBool      flg;

3039:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3040:   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3041:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3042:   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3044:   MatGetArray(B,&bb);
3045:   MatGetArray(X,&xx);
3046:   MatGetLocalSize(B,&m,PETSC_NULL);  /* number local rows */
3047:   MatGetSize(B,PETSC_NULL,&N);       /* total columns in dense matrix */
3048:   MatGetVecs(A,&x,&b);
3049:   for (i=0; i<N; i++) {
3050:     VecPlaceArray(b,bb + i*m);
3051:     VecPlaceArray(x,xx + i*m);
3052:     MatSolve(A,b,x);
3053:     VecResetArray(x);
3054:     VecResetArray(b);
3055:   }
3056:   VecDestroy(&b);
3057:   VecDestroy(&x);
3058:   MatRestoreArray(B,&bb);
3059:   MatRestoreArray(X,&xx);
3060:   return(0);
3061: }

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

3068:    Neighbor-wise Collective on Mat 

3070:    Input Parameters:
3071: +  mat - the factored matrix
3072: -  B - the right-hand-side matrix  (dense matrix)

3074:    Output Parameter:
3075: .  X - the result matrix (dense matrix)

3077:    Notes:
3078:    The matrices b and x cannot be the same.  I.e., one cannot
3079:    call MatMatSolve(A,x,x).

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

3087:    When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 
3088:    it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.

3090:    Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.

3092:    Level: developer

3094:    Concepts: matrices^triangular solves

3096: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3097: @*/
3098: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3099: {

3109:   if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3110:   if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3111:   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);
3112:   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);
3113:   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);
3114:   if (!A->rmap->N && !A->cmap->N) return(0);
3115:   MatCheckPreallocated(A,1);

3117:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3118:   if (!A->ops->matsolve) {
3119:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3120:     MatMatSolve_Basic(A,B,X);
3121:   } else {
3122:     (*A->ops->matsolve)(A,B,X);
3123:   }
3124:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3125:   PetscObjectStateIncrease((PetscObject)X);
3126:   return(0);
3127: }


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

3136:    Neighbor-wise Collective on Mat and Vec

3138:    Input Parameters:
3139: +  mat - the factored matrix
3140: -  b - the right-hand-side vector

3142:    Output Parameter:
3143: .  x - the result vector

3145:    Notes:
3146:    MatSolve() should be used for most applications, as it performs
3147:    a forward solve followed by a backward solve.

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

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

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

3162:    Level: developer

3164:    Concepts: matrices^forward solves

3166: .seealso: MatSolve(), MatBackwardSolve()
3167: @*/
3168: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3169: {

3179:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3180:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3181:   if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3182:   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);
3183:   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);
3184:   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);
3185:   MatCheckPreallocated(mat,1);
3186:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3187:   (*mat->ops->forwardsolve)(mat,b,x);
3188:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3189:   PetscObjectStateIncrease((PetscObject)x);
3190:   return(0);
3191: }

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

3199:    Neighbor-wise Collective on Mat and Vec

3201:    Input Parameters:
3202: +  mat - the factored matrix
3203: -  b - the right-hand-side vector

3205:    Output Parameter:
3206: .  x - the result vector

3208:    Notes:
3209:    MatSolve() should be used for most applications, as it performs
3210:    a forward solve followed by a backward solve.

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

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

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

3225:    Level: developer

3227:    Concepts: matrices^backward solves

3229: .seealso: MatSolve(), MatForwardSolve()
3230: @*/
3231: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3232: {

3242:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3243:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3244:   if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3245:   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);
3246:   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);
3247:   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);
3248:   MatCheckPreallocated(mat,1);

3250:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3251:   (*mat->ops->backwardsolve)(mat,b,x);
3252:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3253:   PetscObjectStateIncrease((PetscObject)x);
3254:   return(0);
3255: }

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

3262:    Neighbor-wise Collective on Mat and Vec

3264:    Input Parameters:
3265: +  mat - the factored matrix
3266: .  b - the right-hand-side vector
3267: -  y - the vector to be added to 

3269:    Output Parameter:
3270: .  x - the result vector

3272:    Notes:
3273:    The vectors b and x cannot be the same.  I.e., one cannot
3274:    call MatSolveAdd(A,x,y,x).

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

3280:    Level: developer

3282:    Concepts: matrices^triangular solves

3284: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3285: @*/
3286: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3287: {
3288:   PetscScalar    one = 1.0;
3289:   Vec            tmp;

3301:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3302:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3303:   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);
3304:   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);
3305:   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);
3306:   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);
3307:   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);
3308:   MatCheckPreallocated(mat,1);

3310:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3311:   if (mat->ops->solveadd)  {
3312:     (*mat->ops->solveadd)(mat,b,y,x);
3313:   } else {
3314:     /* do the solve then the add manually */
3315:     if (x != y) {
3316:       MatSolve(mat,b,x);
3317:       VecAXPY(x,one,y);
3318:     } else {
3319:       VecDuplicate(x,&tmp);
3320:       PetscLogObjectParent(mat,tmp);
3321:       VecCopy(x,tmp);
3322:       MatSolve(mat,b,x);
3323:       VecAXPY(x,one,tmp);
3324:       VecDestroy(&tmp);
3325:     }
3326:   }
3327:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3328:   PetscObjectStateIncrease((PetscObject)x);
3329:   return(0);
3330: }

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

3337:    Neighbor-wise Collective on Mat and Vec

3339:    Input Parameters:
3340: +  mat - the factored matrix
3341: -  b - the right-hand-side vector

3343:    Output Parameter:
3344: .  x - the result vector

3346:    Notes:
3347:    The vectors b and x cannot be the same.  I.e., one cannot
3348:    call MatSolveTranspose(A,x,x).

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

3354:    Level: developer

3356:    Concepts: matrices^triangular solves

3358: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3359: @*/
3360: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3361: {

3371:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3372:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3373:   if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3374:   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);
3375:   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);
3376:   MatCheckPreallocated(mat,1);
3377:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3378:   (*mat->ops->solvetranspose)(mat,b,x);
3379:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3380:   PetscObjectStateIncrease((PetscObject)x);
3381:   return(0);
3382: }

3386: /*@
3387:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
3388:                       factored matrix. 

3390:    Neighbor-wise Collective on Mat and Vec

3392:    Input Parameters:
3393: +  mat - the factored matrix
3394: .  b - the right-hand-side vector
3395: -  y - the vector to be added to 

3397:    Output Parameter:
3398: .  x - the result vector

3400:    Notes:
3401:    The vectors b and x cannot be the same.  I.e., one cannot
3402:    call MatSolveTransposeAdd(A,x,y,x).

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

3408:    Level: developer

3410:    Concepts: matrices^triangular solves

3412: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3413: @*/
3414: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3415: {
3416:   PetscScalar    one = 1.0;
3418:   Vec            tmp;

3429:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3430:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3431:   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);
3432:   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);
3433:   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);
3434:   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);
3435:   MatCheckPreallocated(mat,1);

3437:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3438:   if (mat->ops->solvetransposeadd) {
3439:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3440:   } else {
3441:     /* do the solve then the add manually */
3442:     if (x != y) {
3443:       MatSolveTranspose(mat,b,x);
3444:       VecAXPY(x,one,y);
3445:     } else {
3446:       VecDuplicate(x,&tmp);
3447:       PetscLogObjectParent(mat,tmp);
3448:       VecCopy(x,tmp);
3449:       MatSolveTranspose(mat,b,x);
3450:       VecAXPY(x,one,tmp);
3451:       VecDestroy(&tmp);
3452:     }
3453:   }
3454:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3455:   PetscObjectStateIncrease((PetscObject)x);
3456:   return(0);
3457: }
3458: /* ----------------------------------------------------------------*/

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

3465:    Neighbor-wise Collective on Mat and Vec

3467:    Input Parameters:
3468: +  mat - the matrix
3469: .  b - the right hand side
3470: .  omega - the relaxation factor
3471: .  flag - flag indicating the type of SOR (see below)
3472: .  shift -  diagonal shift
3473: .  its - the number of iterations
3474: -  lits - the number of local iterations 

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

3479:    SOR Flags:
3480: .     SOR_FORWARD_SWEEP - forward SOR
3481: .     SOR_BACKWARD_SWEEP - backward SOR
3482: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3483: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
3484: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
3485: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3486: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
3487:          upper/lower triangular part of matrix to
3488:          vector (with omega)
3489: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3491:    Notes:
3492:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3493:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3494:    on each processor. 

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

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

3501:    Notes for Advanced Users:
3502:    The flags are implemented as bitwise inclusive or operations.
3503:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3504:    to specify a zero initial guess for SSOR.

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

3510:    Vectors x and b CANNOT be the same

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

3514:    Level: developer

3516:    Concepts: matrices^relaxation
3517:    Concepts: matrices^SOR
3518:    Concepts: matrices^Gauss-Seidel

3520: @*/
3521: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3522: {

3532:   if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3533:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3534:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3535:   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);
3536:   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);
3537:   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);
3538:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3539:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3540:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3542:   MatCheckPreallocated(mat,1);
3543:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3544:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3545:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3546:   PetscObjectStateIncrease((PetscObject)x);
3547:   return(0);
3548: }

3552: /*
3553:       Default matrix copy routine.
3554: */
3555: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3556: {
3557:   PetscErrorCode    ierr;
3558:   PetscInt          i,rstart = 0,rend = 0,nz;
3559:   const PetscInt    *cwork;
3560:   const PetscScalar *vwork;

3563:   if (B->assembled) {
3564:     MatZeroEntries(B);
3565:   }
3566:   MatGetOwnershipRange(A,&rstart,&rend);
3567:   for (i=rstart; i<rend; i++) {
3568:     MatGetRow(A,i,&nz,&cwork,&vwork);
3569:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3570:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3571:   }
3572:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3573:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3574:   PetscObjectStateIncrease((PetscObject)B);
3575:   return(0);
3576: }

3580: /*@
3581:    MatCopy - Copys a matrix to another matrix.

3583:    Collective on Mat

3585:    Input Parameters:
3586: +  A - the matrix
3587: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3589:    Output Parameter:
3590: .  B - where the copy is put

3592:    Notes:
3593:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
3594:    same nonzero pattern or the routine will crash.

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

3600:    Level: intermediate
3601:    
3602:    Concepts: matrices^copying

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

3606: @*/
3607: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3608: {
3610:   PetscInt       i;

3618:   MatCheckPreallocated(B,2);
3619:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3620:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3621:   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);
3622:   MatCheckPreallocated(A,1);

3624:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3625:   if (A->ops->copy) {
3626:     (*A->ops->copy)(A,B,str);
3627:   } else { /* generic conversion */
3628:     MatCopy_Basic(A,B,str);
3629:   }

3631:   B->stencil.dim = A->stencil.dim;
3632:   B->stencil.noc = A->stencil.noc;
3633:   for (i=0; i<=A->stencil.dim; i++) {
3634:     B->stencil.dims[i]   = A->stencil.dims[i];
3635:     B->stencil.starts[i] = A->stencil.starts[i];
3636:   }

3638:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3639:   PetscObjectStateIncrease((PetscObject)B);
3640:   return(0);
3641: }

3645: /*@C  
3646:    MatConvert - Converts a matrix to another matrix, either of the same
3647:    or different type.

3649:    Collective on Mat

3651:    Input Parameters:
3652: +  mat - the matrix
3653: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3654:    same type as the original matrix.
3655: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3656:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3657:    MAT_INITIAL_MATRIX.

3659:    Output Parameter:
3660: .  M - pointer to place new matrix

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

3667:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3668:    the MPI communicator of the generated matrix is always the same as the communicator
3669:    of the input matrix.

3671:    Level: intermediate

3673:    Concepts: matrices^converting between storage formats

3675: .seealso: MatCopy(), MatDuplicate()
3676: @*/
3677: PetscErrorCode  MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3678: {
3679:   PetscErrorCode         ierr;
3680:   PetscBool              sametype,issame,flg;
3681:   char                   convname[256],mtype[256];
3682:   Mat                    B;

3688:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3689:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3690:   MatCheckPreallocated(mat,1);
3691:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3693:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3694:   if (flg) {
3695:     newtype = mtype;
3696:   }
3697:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3698:   PetscStrcmp(newtype,"same",&issame);
3699:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

3701:   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3702: 
3703:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3704:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3705:   } else {
3706:     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3707:     const char     *prefix[3] = {"seq","mpi",""};
3708:     PetscInt       i;
3709:     /* 
3710:        Order of precedence:
3711:        1) See if a specialized converter is known to the current matrix.
3712:        2) See if a specialized converter is known to the desired matrix class.
3713:        3) See if a good general converter is registered for the desired class
3714:           (as of 6/27/03 only MATMPIADJ falls into this category).
3715:        4) See if a good general converter is known for the current matrix.
3716:        5) Use a really basic converter.
3717:     */
3718: 
3719:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3720:     for (i=0; i<3; i++) {
3721:       PetscStrcpy(convname,"MatConvert_");
3722:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3723:       PetscStrcat(convname,"_");
3724:       PetscStrcat(convname,prefix[i]);
3725:       PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);
3726:       PetscStrcat(convname,"_C");
3727:       PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3728:       if (conv) goto foundconv;
3729:     }

3731:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3732:     MatCreate(((PetscObject)mat)->comm,&B);
3733:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3734:     MatSetType(B,newtype);
3735:     for (i=0; i<3; i++) {
3736:       PetscStrcpy(convname,"MatConvert_");
3737:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3738:       PetscStrcat(convname,"_");
3739:       PetscStrcat(convname,prefix[i]);
3740:       PetscStrcat(convname,newtype);
3741:       PetscStrcat(convname,"_C");
3742:       PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3743:       if (conv) {
3744:         MatDestroy(&B);
3745:         goto foundconv;
3746:       }
3747:     }

3749:     /* 3) See if a good general converter is registered for the desired class */
3750:     conv = B->ops->convertfrom;
3751:     MatDestroy(&B);
3752:     if (conv) goto foundconv;

3754:     /* 4) See if a good general converter is known for the current matrix */
3755:     if (mat->ops->convert) {
3756:       conv = mat->ops->convert;
3757:     }
3758:     if (conv) goto foundconv;

3760:     /* 5) Use a really basic converter. */
3761:     conv = MatConvert_Basic;

3763:     foundconv:
3764:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3765:     (*conv)(mat,newtype,reuse,M);
3766:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3767:   }
3768:   PetscObjectStateIncrease((PetscObject)*M);

3770:   /* Copy Mat options */
3771:   if (mat->symmetric){MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3772:   if (mat->hermitian){MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3773:   return(0);
3774: }

3778: /*@C  
3779:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3781:    Not Collective

3783:    Input Parameter:
3784: .  mat - the matrix, must be a factored matrix

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

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

3793:    Level: intermediate

3795: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3796: @*/
3797: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3798: {
3799:   PetscErrorCode         ierr;
3800:   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);

3805:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3806:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3807:   if (!conv) {
3808:     *type = MATSOLVERPETSC;
3809:   } else {
3810:     (*conv)(mat,type);
3811:   }
3812:   return(0);
3813: }

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

3820:    Collective on Mat

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

3827:    Output Parameters:
3828: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

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

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

3836:    Level: intermediate

3838: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3839: @*/
3840: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3841: {
3842:   PetscErrorCode  ierr,(*conv)(Mat,MatFactorType,Mat*);
3843:   char            convname[256];


3849:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3850:   MatCheckPreallocated(mat,1);

3852:   PetscStrcpy(convname,"MatGetFactor_");
3853:   PetscStrcat(convname,type);
3854:   PetscStrcat(convname,"_C");
3855:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3856:   if (!conv) {
3857:     PetscBool  flag;
3858:     MPI_Comm   comm;

3860:     PetscObjectGetComm((PetscObject)mat,&comm);
3861:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3862:     if (flag) {
3863:       SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3864:     } else {
3865:       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);
3866:     }
3867:   }
3868:   (*conv)(mat,ftype,f);
3869:   return(0);
3870: }

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

3877:    Not Collective

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

3884:    Output Parameter:
3885: .    flg - PETSC_TRUE if the factorization is available

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

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

3893:    Level: intermediate

3895: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3896: @*/
3897: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
3898: {
3899:   PetscErrorCode         ierr;
3900:   char                   convname[256];
3901:   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscBool *);


3907:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3908:   MatCheckPreallocated(mat,1);

3910:   PetscStrcpy(convname,"MatGetFactorAvailable_");
3911:   PetscStrcat(convname,type);
3912:   PetscStrcat(convname,"_C");
3913:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3914:   if (!conv) {
3915:     *flg = PETSC_FALSE;
3916:   } else {
3917:     (*conv)(mat,ftype,flg);
3918:   }
3919:   return(0);
3920: }


3925: /*@
3926:    MatDuplicate - Duplicates a matrix including the non-zero structure.

3928:    Collective on Mat

3930:    Input Parameters:
3931: +  mat - the matrix
3932: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3933:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

3935:    Output Parameter:
3936: .  M - pointer to place new matrix

3938:    Level: intermediate

3940:    Concepts: matrices^duplicating

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

3944: .seealso: MatCopy(), MatConvert()
3945: @*/
3946: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3947: {
3949:   Mat            B;
3950:   PetscInt       i;

3956:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3957:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3958:   MatCheckPreallocated(mat,1);

3960:   *M  = 0;
3961:   if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
3962:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3963:   (*mat->ops->duplicate)(mat,op,M);
3964:   B = *M;
3965: 
3966:   B->stencil.dim = mat->stencil.dim;
3967:   B->stencil.noc = mat->stencil.noc;
3968:   for (i=0; i<=mat->stencil.dim; i++) {
3969:     B->stencil.dims[i]   = mat->stencil.dims[i];
3970:     B->stencil.starts[i] = mat->stencil.starts[i];
3971:   }

3973:   B->nooffproczerorows = mat->nooffproczerorows;
3974:   B->nooffprocentries  = mat->nooffprocentries;
3975:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3976:   PetscObjectStateIncrease((PetscObject)B);
3977:   return(0);
3978: }

3982: /*@
3983:    MatGetDiagonal - Gets the diagonal of a matrix.

3985:    Logically Collective on Mat and Vec

3987:    Input Parameters:
3988: +  mat - the matrix
3989: -  v - the vector for storing the diagonal

3991:    Output Parameter:
3992: .  v - the diagonal of the matrix

3994:    Level: intermediate

3996:    Note:
3997:    Currently only correct in parallel for square matrices.

3999:    Concepts: matrices^accessing diagonals

4001: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4002: @*/
4003: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4004: {

4011:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4012:   if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4013:   MatCheckPreallocated(mat,1);

4015:   (*mat->ops->getdiagonal)(mat,v);
4016:   PetscObjectStateIncrease((PetscObject)v);
4017:   return(0);
4018: }

4022: /*@ 
4023:    MatGetRowMin - Gets the minimum value (of the real part) of each
4024:         row of the matrix

4026:    Logically Collective on Mat and Vec

4028:    Input Parameters:
4029: .  mat - the matrix

4031:    Output Parameter:
4032: +  v - the vector for storing the maximums
4033: -  idx - the indices of the column found for each row (optional)

4035:    Level: intermediate

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

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

4042:    Concepts: matrices^getting row maximums

4044: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4045:           MatGetRowMax()
4046: @*/
4047: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4048: {

4055:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4056:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4057:   MatCheckPreallocated(mat,1);

4059:   (*mat->ops->getrowmin)(mat,v,idx);
4060:   PetscObjectStateIncrease((PetscObject)v);
4061:   return(0);
4062: }

4066: /*@ 
4067:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4068:         row of the matrix

4070:    Logically Collective on Mat and Vec

4072:    Input Parameters:
4073: .  mat - the matrix

4075:    Output Parameter:
4076: +  v - the vector for storing the minimums
4077: -  idx - the indices of the column found for each row (or PETSC_NULL if not needed)

4079:    Level: intermediate

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

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

4086:    Concepts: matrices^getting row maximums

4088: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4089: @*/
4090: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4091: {

4098:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4099:   if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4100:   MatCheckPreallocated(mat,1);
4101:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

4103:   (*mat->ops->getrowminabs)(mat,v,idx);
4104:   PetscObjectStateIncrease((PetscObject)v);
4105:   return(0);
4106: }

4110: /*@ 
4111:    MatGetRowMax - Gets the maximum value (of the real part) of each
4112:         row of the matrix

4114:    Logically Collective on Mat and Vec

4116:    Input Parameters:
4117: .  mat - the matrix

4119:    Output Parameter:
4120: +  v - the vector for storing the maximums
4121: -  idx - the indices of the column found for each row (optional)

4123:    Level: intermediate

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

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

4130:    Concepts: matrices^getting row maximums

4132: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4133: @*/
4134: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4135: {

4142:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4143:   if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4144:   MatCheckPreallocated(mat,1);

4146:   (*mat->ops->getrowmax)(mat,v,idx);
4147:   PetscObjectStateIncrease((PetscObject)v);
4148:   return(0);
4149: }

4153: /*@ 
4154:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4155:         row of the matrix

4157:    Logically Collective on Mat and Vec

4159:    Input Parameters:
4160: .  mat - the matrix

4162:    Output Parameter:
4163: +  v - the vector for storing the maximums
4164: -  idx - the indices of the column found for each row (or PETSC_NULL if not needed)

4166:    Level: intermediate

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

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

4173:    Concepts: matrices^getting row maximums

4175: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4176: @*/
4177: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4178: {

4185:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4186:   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4187:   MatCheckPreallocated(mat,1);
4188:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

4190:   (*mat->ops->getrowmaxabs)(mat,v,idx);
4191:   PetscObjectStateIncrease((PetscObject)v);
4192:   return(0);
4193: }

4197: /*@ 
4198:    MatGetRowSum - Gets the sum of each row of the matrix

4200:    Logically Collective on Mat and Vec

4202:    Input Parameters:
4203: .  mat - the matrix

4205:    Output Parameter:
4206: .  v - the vector for storing the sum of rows

4208:    Level: intermediate

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

4212:    Concepts: matrices^getting row sums

4214: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4215: @*/
4216: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4217: {
4218:   PetscInt       start = 0, end = 0, row;
4219:   PetscScalar   *array;

4226:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4227:   MatCheckPreallocated(mat,1);
4228:   MatGetOwnershipRange(mat, &start, &end);
4229:   VecGetArray(v, &array);
4230:   for(row = start; row < end; ++row) {
4231:     PetscInt           ncols, col;
4232:     const PetscInt    *cols;
4233:     const PetscScalar *vals;

4235:     array[row - start] = 0.0;
4236:     MatGetRow(mat, row, &ncols, &cols, &vals);
4237:     for(col = 0; col < ncols; col++) {
4238:       array[row - start] += vals[col];
4239:     }
4240:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4241:   }
4242:   VecRestoreArray(v, &array);
4243:   PetscObjectStateIncrease((PetscObject) v);
4244:   return(0);
4245: }

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

4252:    Collective on Mat

4254:    Input Parameter:
4255: +  mat - the matrix to transpose
4256: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4258:    Output Parameters:
4259: .  B - the transpose 

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

4264:      Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.

4266:    Level: intermediate

4268:    Concepts: matrices^transposing

4270: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4271: @*/
4272: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4273: {

4279:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4280:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4281:   if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4282:   MatCheckPreallocated(mat,1);

4284:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4285:   (*mat->ops->transpose)(mat,reuse,B);
4286:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4287:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4288:   return(0);
4289: }

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

4297:    Collective on Mat

4299:    Input Parameter:
4300: +  A - the matrix to test
4301: -  B - the matrix to test against, this can equal the first parameter

4303:    Output Parameters:
4304: .  flg - the result

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

4311:    Level: intermediate

4313:    Concepts: matrices^transposing, matrix^symmetry

4315: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4316: @*/
4317: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4318: {
4319:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);

4325:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4326:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4327:   *flg = PETSC_FALSE;
4328:   if (f && g) {
4329:     if (f == g) {
4330:       (*f)(A,B,tol,flg);
4331:     } else {
4332:       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4333:     }
4334:   } else {
4335:     const MatType mattype;
4336:     if (!f) {MatGetType(A,&mattype);}
4337:     else    {MatGetType(B,&mattype);}
4338:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4339:   }
4340:   return(0);
4341: }

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

4348:    Collective on Mat

4350:    Input Parameter:
4351: +  mat - the matrix to transpose and complex conjugate
4352: -  reuse - store the transpose matrix in the provided B

4354:    Output Parameters:
4355: .  B - the Hermitian

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

4360:    Level: intermediate

4362:    Concepts: matrices^transposing, complex conjugatex

4364: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4365: @*/
4366: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4367: {

4371:   MatTranspose(mat,reuse,B);
4372: #if defined(PETSC_USE_COMPLEX)
4373:   MatConjugate(*B);
4374: #endif
4375:   return(0);
4376: }

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

4383:    Collective on Mat

4385:    Input Parameter:
4386: +  A - the matrix to test
4387: -  B - the matrix to test against, this can equal the first parameter

4389:    Output Parameters:
4390: .  flg - the result

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

4397:    Level: intermediate

4399:    Concepts: matrices^transposing, matrix^symmetry

4401: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4402: @*/
4403: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4404: {
4405:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);

4411:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4412:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4413:   if (f && g) {
4414:     if (f==g) {
4415:       (*f)(A,B,tol,flg);
4416:     } else {
4417:       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4418:     }
4419:   }
4420:   return(0);
4421: }

4425: /*@
4426:    MatPermute - Creates a new matrix with rows and columns permuted from the 
4427:    original.

4429:    Collective on Mat

4431:    Input Parameters:
4432: +  mat - the matrix to permute
4433: .  row - row permutation, each processor supplies only the permutation for its rows
4434: -  col - column permutation, each processor needs the entire column permutation, that is
4435:          this is the same size as the total number of columns in the matrix. It can often
4436:          be obtained with ISAllGather() on the row permutation

4438:    Output Parameters:
4439: .  B - the permuted matrix

4441:    Level: advanced

4443:    Concepts: matrices^permuting

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

4447: @*/
4448: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4449: {

4458:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4459:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4460:   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4461:   MatCheckPreallocated(mat,1);

4463:   (*mat->ops->permute)(mat,row,col,B);
4464:   PetscObjectStateIncrease((PetscObject)*B);
4465:   return(0);
4466: }

4470: /*@
4471:    MatEqual - Compares two matrices.

4473:    Collective on Mat

4475:    Input Parameters:
4476: +  A - the first matrix
4477: -  B - the second matrix

4479:    Output Parameter:
4480: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4482:    Level: intermediate

4484:    Concepts: matrices^equality between
4485: @*/
4486: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4487: {

4497:   MatCheckPreallocated(B,2);
4498:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4499:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4500:   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);
4501:   if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4502:   if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4503:   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);
4504:   MatCheckPreallocated(A,1);

4506:   (*A->ops->equal)(A,B,flg);
4507:   return(0);
4508: }

4512: /*@
4513:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4514:    matrices that are stored as vectors.  Either of the two scaling
4515:    matrices can be PETSC_NULL.

4517:    Collective on Mat

4519:    Input Parameters:
4520: +  mat - the matrix to be scaled
4521: .  l - the left scaling vector (or PETSC_NULL)
4522: -  r - the right scaling vector (or PETSC_NULL)

4524:    Notes:
4525:    MatDiagonalScale() computes A = LAR, where
4526:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4527:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4529:    Level: intermediate

4531:    Concepts: matrices^diagonal scaling
4532:    Concepts: diagonal scaling of matrices

4534: .seealso: MatScale()
4535: @*/
4536: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4537: {

4543:   if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4546:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4547:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4548:   MatCheckPreallocated(mat,1);

4550:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4551:   (*mat->ops->diagonalscale)(mat,l,r);
4552:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4553:   PetscObjectStateIncrease((PetscObject)mat);
4554: #if defined(PETSC_HAVE_CUSP)
4555:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4556:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4557:   }
4558: #endif
4559:   return(0);
4560: }

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

4567:     Logically Collective on Mat

4569:     Input Parameters:
4570: +   mat - the matrix to be scaled
4571: -   a  - the scaling value

4573:     Output Parameter:
4574: .   mat - the scaled matrix

4576:     Level: intermediate

4578:     Concepts: matrices^scaling all entries

4580: .seealso: MatDiagonalScale()
4581: @*/
4582: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4583: {

4589:   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4590:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4591:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4593:   MatCheckPreallocated(mat,1);

4595:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4596:   if (a != (PetscScalar)1.0) {
4597:     (*mat->ops->scale)(mat,a);
4598:     PetscObjectStateIncrease((PetscObject)mat);
4599:   }
4600:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4601: #if defined(PETSC_HAVE_CUSP)
4602:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4603:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4604:   }
4605: #endif
4606:   return(0);
4607: }

4611: /*@ 
4612:    MatNorm - Calculates various norms of a matrix.

4614:    Collective on Mat

4616:    Input Parameters:
4617: +  mat - the matrix
4618: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4620:    Output Parameters:
4621: .  nrm - the resulting norm 

4623:    Level: intermediate

4625:    Concepts: matrices^norm
4626:    Concepts: norm^of matrix
4627: @*/
4628: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4629: {


4637:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4638:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4639:   if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4640:   MatCheckPreallocated(mat,1);

4642:   (*mat->ops->norm)(mat,type,nrm);
4643:   return(0);
4644: }

4646: /* 
4647:      This variable is used to prevent counting of MatAssemblyBegin() that
4648:    are called from within a MatAssemblyEnd().
4649: */
4650: static PetscInt MatAssemblyEnd_InUse = 0;
4653: /*@
4654:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4655:    be called after completing all calls to MatSetValues().

4657:    Collective on Mat

4659:    Input Parameters:
4660: +  mat - the matrix 
4661: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4662:  
4663:    Notes: 
4664:    MatSetValues() generally caches the values.  The matrix is ready to
4665:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4666:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4667:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4668:    using the matrix.

4670:    Level: beginner

4672:    Concepts: matrices^assembling

4674: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4675: @*/
4676: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4677: {

4683:   MatCheckPreallocated(mat,1);
4684:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4685:   if (mat->assembled) {
4686:     mat->was_assembled = PETSC_TRUE;
4687:     mat->assembled     = PETSC_FALSE;
4688:   }
4689:   if (!MatAssemblyEnd_InUse) {
4690:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4691:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4692:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4693:   } else {
4694:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4695:   }
4696:   return(0);
4697: }

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

4705:    Not Collective

4707:    Input Parameter:
4708: .  mat - the matrix 

4710:    Output Parameter:
4711: .  assembled - PETSC_TRUE or PETSC_FALSE

4713:    Level: advanced

4715:    Concepts: matrices^assembled?

4717: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4718: @*/
4719: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4720: {
4725:   *assembled = mat->assembled;
4726:   return(0);
4727: }

4731: /*
4732:     Processes command line options to determine if/how a matrix
4733:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4734: */
4735: PetscErrorCode MatView_Private(Mat mat)
4736: {
4737:   PetscErrorCode    ierr;
4738:   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4739:   static PetscBool  incall = PETSC_FALSE;
4740: #if defined(PETSC_USE_SOCKET_VIEWER)
4741:   PetscBool         flg5 = PETSC_FALSE;
4742: #endif

4745:   if (incall) return(0);
4746:   incall = PETSC_TRUE;
4747:   PetscObjectOptionsBegin((PetscObject)mat);
4748:     PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4749:     PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4750:     PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4751:     PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4752: #if defined(PETSC_USE_SOCKET_VIEWER)
4753:     PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4754: #endif
4755:     PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4756:     PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4757:   PetscOptionsEnd();

4759:   if (flg1) {
4760:     PetscViewer viewer;

4762:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4763:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4764:     MatView(mat,viewer);
4765:     PetscViewerPopFormat(viewer);
4766:   }
4767:   if (flg2) {
4768:     PetscViewer viewer;

4770:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4771:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4772:     MatView(mat,viewer);
4773:     PetscViewerPopFormat(viewer);
4774:   }
4775:   if (flg3) {
4776:     PetscViewer viewer;

4778:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4779:     MatView(mat,viewer);
4780:   }
4781:   if (flg4) {
4782:     PetscViewer viewer;

4784:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4785:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4786:     MatView(mat,viewer);
4787:     PetscViewerPopFormat(viewer);
4788:   }
4789: #if defined(PETSC_USE_SOCKET_VIEWER)
4790:   if (flg5) {
4791:     MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4792:     PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4793:   }
4794: #endif
4795:   if (flg6) {
4796:     MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4797:     PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4798:   }
4799:   if (flg7) {
4800:     PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4801:     if (flg8) {
4802:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4803:     }
4804:     MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4805:     PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4806:     if (flg8) {
4807:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4808:     }
4809:   }
4810:   incall = PETSC_FALSE;
4811:   return(0);
4812: }

4816: /*@
4817:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4818:    be called after MatAssemblyBegin().

4820:    Collective on Mat

4822:    Input Parameters:
4823: +  mat - the matrix 
4824: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4826:    Options Database Keys:
4827: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4828: .  -mat_view_info_detailed - Prints more detailed info
4829: .  -mat_view - Prints matrix in ASCII format
4830: .  -mat_view_matlab - Prints matrix in Matlab format
4831: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4832: .  -display <name> - Sets display name (default is host)
4833: .  -draw_pause <sec> - Sets number of seconds to pause after display
4834: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4835: .  -viewer_socket_machine <machine>
4836: .  -viewer_socket_port <port>
4837: .  -mat_view_binary - save matrix to file in binary format
4838: -  -viewer_binary_filename <name>

4840:    Notes: 
4841:    MatSetValues() generally caches the values.  The matrix is ready to
4842:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4843:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4844:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4845:    using the matrix.

4847:    Level: beginner

4849: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4850: @*/
4851: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4852: {
4853:   PetscErrorCode  ierr;
4854:   static PetscInt inassm = 0;
4855:   PetscBool       flg = PETSC_FALSE;


4861:   inassm++;
4862:   MatAssemblyEnd_InUse++;
4863:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4864:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4865:     if (mat->ops->assemblyend) {
4866:       (*mat->ops->assemblyend)(mat,type);
4867:     }
4868:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4869:   } else {
4870:     if (mat->ops->assemblyend) {
4871:       (*mat->ops->assemblyend)(mat,type);
4872:     }
4873:   }

4875:   /* Flush assembly is not a true assembly */
4876:   if (type != MAT_FLUSH_ASSEMBLY) {
4877:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4878:   }
4879:   mat->insertmode = NOT_SET_VALUES;
4880:   MatAssemblyEnd_InUse--;
4881:   PetscObjectStateIncrease((PetscObject)mat);
4882:   if (!mat->symmetric_eternal) {
4883:     mat->symmetric_set              = PETSC_FALSE;
4884:     mat->hermitian_set              = PETSC_FALSE;
4885:     mat->structurally_symmetric_set = PETSC_FALSE;
4886:   }
4887: #if defined(PETSC_HAVE_CUSP)
4888:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4889:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4890:   }
4891: #endif
4892:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4893:     MatView_Private(mat);
4894:     PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4895:     if (flg) {
4896:       PetscReal tol = 0.0;
4897:       PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4898:       MatIsSymmetric(mat,tol,&flg);
4899:       if (flg) {
4900:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4901:       } else {
4902:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4903:       }
4904:     }
4905:   }
4906:   inassm--;
4907:   return(0);
4908: }

4912: /*@
4913:    MatSetOption - Sets a parameter option for a matrix. Some options
4914:    may be specific to certain storage formats.  Some options
4915:    determine how values will be inserted (or added). Sorted, 
4916:    row-oriented input will generally assemble the fastest. The default
4917:    is row-oriented. 

4919:    Logically Collective on Mat

4921:    Input Parameters:
4922: +  mat - the matrix 
4923: .  option - the option, one of those listed below (and possibly others),
4924: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

4926:   Options Describing Matrix Structure:
4927: +    MAT_SPD - symmetric positive definite
4928: -    MAT_SYMMETRIC - symmetric in terms of both structure and value
4929: .    MAT_HERMITIAN - transpose is the complex conjugation
4930: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4931: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4932:                             you set to be kept with all future use of the matrix
4933:                             including after MatAssemblyBegin/End() which could
4934:                             potentially change the symmetry structure, i.e. you 
4935:                             KNOW the matrix will ALWAYS have the property you set.


4938:    Options For Use with MatSetValues():
4939:    Insert a logically dense subblock, which can be
4940: .    MAT_ROW_ORIENTED - row-oriented (default)

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

4946:    When (re)assembling a matrix, we can restrict the input for
4947:    efficiency/debugging purposes.  These options include
4948: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4949:         allowed if they generate a new nonzero
4950: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4951: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4952: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4953: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4954: +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4955:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4956:         performance for very large process counts.

4958:    Notes:
4959:    Some options are relevant only for particular matrix types and
4960:    are thus ignored by others.  Other options are not supported by
4961:    certain matrix types and will generate an error message if set.

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

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

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

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

4986:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
4987:    other processors should be dropped, rather than stashed.
4988:    This is useful if you know that the "owning" processor is also 
4989:    always generating the correct matrix entries, so that PETSc need
4990:    not transfer duplicate entries generated on another processor.
4991:    
4992:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4993:    searches during matrix assembly. When this flag is set, the hash table
4994:    is created during the first Matrix Assembly. This hash table is
4995:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4996:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 
4997:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4998:    supported by MATMPIBAIJ format only.

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

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

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

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

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

5015:    Notes: Can only be called after MatSetSizes() and MatSetType() have been set.

5017:    Level: intermediate

5019:    Concepts: matrices^setting options

5021: @*/
5022: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5023: {


5032:   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);
5033:   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()");

5035:   switch (op) {
5036:   case MAT_NO_OFF_PROC_ENTRIES:
5037:     mat->nooffprocentries                = flg;
5038:     return(0);
5039:     break;
5040:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5041:     mat->nooffproczerorows               = flg;
5042:     return(0);
5043:     break;
5044:   case MAT_SPD:
5045:     mat->spd_set                         = PETSC_TRUE;
5046:     mat->spd                             = flg;
5047:     if (flg) {
5048:       mat->symmetric                     = PETSC_TRUE;
5049:       mat->structurally_symmetric        = PETSC_TRUE;
5050:       mat->symmetric_set                 = PETSC_TRUE;
5051:       mat->structurally_symmetric_set    = PETSC_TRUE;
5052:     }
5053:     break;
5054:   case MAT_SYMMETRIC:
5055:     mat->symmetric                       = flg;
5056:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5057:     mat->symmetric_set                   = PETSC_TRUE;
5058:     mat->structurally_symmetric_set      = flg;
5059:     break;
5060:   case MAT_HERMITIAN:
5061:     mat->hermitian                       = flg;
5062:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5063:     mat->hermitian_set                   = PETSC_TRUE;
5064:     mat->structurally_symmetric_set      = flg;
5065:     break;
5066:   case MAT_STRUCTURALLY_SYMMETRIC:
5067:     mat->structurally_symmetric          = flg;
5068:     mat->structurally_symmetric_set      = PETSC_TRUE;
5069:     break;
5070:   case MAT_SYMMETRY_ETERNAL:
5071:     mat->symmetric_eternal               = flg;
5072:     break;
5073:   default:
5074:     break;
5075:   }
5076:   if (mat->ops->setoption) {
5077:     (*mat->ops->setoption)(mat,op,flg);
5078:   }
5079:   return(0);
5080: }

5084: /*@
5085:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5086:    this routine retains the old nonzero structure.

5088:    Logically Collective on Mat

5090:    Input Parameters:
5091: .  mat - the matrix 

5093:    Level: intermediate

5095:    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. 
5096:    See the Performance chapter of the users manual for information on preallocating matrices.

5098:    Concepts: matrices^zeroing

5100: .seealso: MatZeroRows()
5101: @*/
5102: PetscErrorCode  MatZeroEntries(Mat mat)
5103: {

5109:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5110:   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");
5111:   if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5112:   MatCheckPreallocated(mat,1);

5114:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5115:   (*mat->ops->zeroentries)(mat);
5116:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5117:   PetscObjectStateIncrease((PetscObject)mat);
5118: #if defined(PETSC_HAVE_CUSP)
5119:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5120:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5121:   }
5122: #endif
5123:   return(0);
5124: }

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

5132:    Collective on Mat

5134:    Input Parameters:
5135: +  mat - the matrix
5136: .  numRows - the number of rows to remove
5137: .  rows - the global row indices
5138: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5139: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5140: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5159:    Level: intermediate

5161:    Concepts: matrices^zeroing rows

5163: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5164: @*/
5165: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5166: {

5173:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5174:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5175:   if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5176:   MatCheckPreallocated(mat,1);

5178:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5179:   MatView_Private(mat);
5180:   PetscObjectStateIncrease((PetscObject)mat);
5181: #if defined(PETSC_HAVE_CUSP)
5182:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5183:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5184:   }
5185: #endif
5186:   return(0);
5187: }

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

5195:    Collective on Mat

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

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

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

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

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

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

5221:    Level: intermediate

5223:    Concepts: matrices^zeroing rows

5225: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5226: @*/
5227: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5228: {
5230:   PetscInt       numRows;
5231:   const PetscInt *rows;

5238:   ISGetLocalSize(is,&numRows);
5239:   ISGetIndices(is,&rows);
5240:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5241:   ISRestoreIndices(is,&rows);
5242:   return(0);
5243: }

5247: /*@C
5248:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5249:    of a set of rows of a matrix.

5251:    Collective on Mat

5253:    Input Parameters:
5254: +  mat - the matrix
5255: .  numRows - the number of rows to remove
5256: .  rows - the global row indices
5257: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5258: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5259: -  b - optional vector of right hand side, that will be adjusted by provided solution

5261:    Notes:
5262:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5263:    but does not release memory.  For the dense and block diagonal
5264:    formats this does not alter the nonzero structure.

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

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

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

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

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

5285:    Level: intermediate

5287:    Concepts: matrices^zeroing rows

5289: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5290: @*/
5291: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5292: {

5299:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5300:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5301:   if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5302:   MatCheckPreallocated(mat,1);

5304:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5305:   MatView_Private(mat);
5306:   PetscObjectStateIncrease((PetscObject)mat);
5307: #if defined(PETSC_HAVE_CUSP)
5308:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5309:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5310:   }
5311: #endif
5312:   return(0);
5313: }

5317: /*@C
5318:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5319:    of a set of rows of a matrix.

5321:    Collective on Mat

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

5330:    Notes:
5331:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5332:    but does not release memory.  For the dense and block diagonal
5333:    formats this does not alter the nonzero structure.

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

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

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

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

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

5354:    Level: intermediate

5356:    Concepts: matrices^zeroing rows

5358: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5359: @*/
5360: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5361: {
5362:   PetscInt       numRows;
5363:   const PetscInt *rows;

5370:   ISGetLocalSize(is,&numRows);
5371:   ISGetIndices(is,&rows);
5372:   MatZeroRows(mat,numRows,rows,diag,x,b);
5373:   ISRestoreIndices(is,&rows);
5374:   return(0);
5375: }

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

5383:    Collective on Mat

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

5393:    Notes:
5394:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5395:    but does not release memory.  For the dense and block diagonal
5396:    formats this does not alter the nonzero structure.

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

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

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

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

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

5416:    In Fortran idxm and idxn should be declared as
5417: $     MatStencil idxm(4,m)
5418:    and the values inserted using
5419: $    idxm(MatStencil_i,1) = i
5420: $    idxm(MatStencil_j,1) = j
5421: $    idxm(MatStencil_k,1) = k
5422: $    idxm(MatStencil_c,1) = c
5423:    etc

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

5430:    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
5431:    a single value per point) you can skip filling those indices.

5433:    Level: intermediate

5435:    Concepts: matrices^zeroing rows

5437: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5438: @*/
5439: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5440: {
5441:   PetscInt       dim    = mat->stencil.dim;
5442:   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5443:   PetscInt      *dims   = mat->stencil.dims+1;
5444:   PetscInt      *starts = mat->stencil.starts;
5445:   PetscInt      *dxm    = (PetscInt *) rows;
5446:   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;


5454:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5455:   for(i = 0; i < numRows; ++i) {
5456:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5457:     for(j = 0; j < 3-sdim; ++j) dxm++;
5458:     /* Local index in X dir */
5459:     tmp = *dxm++ - starts[0];
5460:     /* Loop over remaining dimensions */
5461:     for(j = 0; j < dim-1; ++j) {
5462:       /* If nonlocal, set index to be negative */
5463:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5464:       /* Update local index */
5465:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5466:     }
5467:     /* Skip component slot if necessary */
5468:     if (mat->stencil.noc) dxm++;
5469:     /* Local row number */
5470:     if (tmp >= 0) {
5471:       jdxm[numNewRows++] = tmp;
5472:     }
5473:   }
5474:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5475:   PetscFree(jdxm);
5476:   return(0);
5477: }

5481: /*@C
5482:    MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5483:    of a set of rows and columns of a matrix. 

5485:    Collective on Mat

5487:    Input Parameters:
5488: +  mat - the matrix
5489: .  numRows - the number of rows/columns to remove
5490: .  rows - the grid coordinates (and component number when dof > 1) for matrix rows
5491: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5492: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5493: -  b - optional vector of right hand side, that will be adjusted by provided solution

5495:    Notes:
5496:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5497:    but does not release memory.  For the dense and block diagonal
5498:    formats this does not alter the nonzero structure.

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

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

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

5513:    Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5514:    list only rows local to itself, but the row/column numbers are given in local numbering).

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

5518:    In Fortran idxm and idxn should be declared as
5519: $     MatStencil idxm(4,m)
5520:    and the values inserted using
5521: $    idxm(MatStencil_i,1) = i
5522: $    idxm(MatStencil_j,1) = j
5523: $    idxm(MatStencil_k,1) = k
5524: $    idxm(MatStencil_c,1) = c
5525:    etc

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

5532:    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
5533:    a single value per point) you can skip filling those indices.

5535:    Level: intermediate

5537:    Concepts: matrices^zeroing rows

5539: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5540: @*/
5541: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5542: {
5543:   PetscInt       dim    = mat->stencil.dim;
5544:   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5545:   PetscInt      *dims   = mat->stencil.dims+1;
5546:   PetscInt      *starts = mat->stencil.starts;
5547:   PetscInt      *dxm    = (PetscInt *) rows;
5548:   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;


5556:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5557:   for(i = 0; i < numRows; ++i) {
5558:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5559:     for(j = 0; j < 3-sdim; ++j) dxm++;
5560:     /* Local index in X dir */
5561:     tmp = *dxm++ - starts[0];
5562:     /* Loop over remaining dimensions */
5563:     for(j = 0; j < dim-1; ++j) {
5564:       /* If nonlocal, set index to be negative */
5565:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5566:       /* Update local index */
5567:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5568:     }
5569:     /* Skip component slot if necessary */
5570:     if (mat->stencil.noc) dxm++;
5571:     /* Local row number */
5572:     if (tmp >= 0) {
5573:       jdxm[numNewRows++] = tmp;
5574:     }
5575:   }
5576:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5577:   PetscFree(jdxm);
5578:   return(0);
5579: }

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

5587:    Collective on Mat

5589:    Input Parameters:
5590: +  mat - the matrix
5591: .  numRows - the number of rows to remove
5592: .  rows - the global row indices
5593: .  diag - value put in all diagonals of eliminated rows
5594: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5595: -  b - optional vector of right hand side, that will be adjusted by provided solution

5597:    Notes:
5598:    Before calling MatZeroRowsLocal(), the user must first set the
5599:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5601:    For the AIJ matrix formats this removes the old nonzero structure,
5602:    but does not release memory.  For the dense and block diagonal
5603:    formats this does not alter the nonzero structure.

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

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

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

5616:    Level: intermediate

5618:    Concepts: matrices^zeroing

5620: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5621: @*/
5622: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5623: {
5625:   PetscMPIInt    size;

5631:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5632:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5633:   MatCheckPreallocated(mat,1);

5635:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
5636:   if (mat->ops->zerorowslocal) {
5637:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5638:   } else if (size == 1) {
5639:     (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5640:   } else {
5641:     IS             is, newis;
5642:     const PetscInt *newRows;

5644:     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5645:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5646:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5647:     ISGetIndices(newis,&newRows);
5648:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5649:     ISRestoreIndices(newis,&newRows);
5650:     ISDestroy(&newis);
5651:     ISDestroy(&is);
5652:   }
5653:   PetscObjectStateIncrease((PetscObject)mat);
5654: #if defined(PETSC_HAVE_CUSP)
5655:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5656:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5657:   }
5658: #endif
5659:   return(0);
5660: }

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

5668:    Collective on Mat

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

5677:    Notes:
5678:    Before calling MatZeroRowsLocalIS(), the user must first set the
5679:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5681:    For the AIJ matrix formats this removes the old nonzero structure,
5682:    but does not release memory.  For the dense and block diagonal
5683:    formats this does not alter the nonzero structure.

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

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

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

5696:    Level: intermediate

5698:    Concepts: matrices^zeroing

5700: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5701: @*/
5702: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5703: {
5705:   PetscInt       numRows;
5706:   const PetscInt *rows;

5712:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5713:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5714:   MatCheckPreallocated(mat,1);

5716:   ISGetLocalSize(is,&numRows);
5717:   ISGetIndices(is,&rows);
5718:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5719:   ISRestoreIndices(is,&rows);
5720:   return(0);
5721: }

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

5729:    Collective on Mat

5731:    Input Parameters:
5732: +  mat - the matrix
5733: .  numRows - the number of rows to remove
5734: .  rows - the global row indices
5735: .  diag - value put in all diagonals of eliminated rows
5736: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5737: -  b - optional vector of right hand side, that will be adjusted by provided solution

5739:    Notes:
5740:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5741:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5747:    Level: intermediate

5749:    Concepts: matrices^zeroing

5751: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5752: @*/
5753: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5754: {
5756:   PetscMPIInt    size;

5762:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5763:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5764:   MatCheckPreallocated(mat,1);

5766:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
5767:   if (size == 1) {
5768:     (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5769:   } else {
5770:     IS             is, newis;
5771:     const PetscInt *newRows;

5773:     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5774:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5775:     ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5776:     ISGetIndices(newis,&newRows);
5777:     (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5778:     ISRestoreIndices(newis,&newRows);
5779:     ISDestroy(&newis);
5780:     ISDestroy(&is);
5781:   }
5782:   PetscObjectStateIncrease((PetscObject)mat);
5783: #if defined(PETSC_HAVE_CUSP)
5784:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5785:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5786:   }
5787: #endif
5788:   return(0);
5789: }

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

5797:    Collective on Mat

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

5806:    Notes:
5807:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5808:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5814:    Level: intermediate

5816:    Concepts: matrices^zeroing

5818: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5819: @*/
5820: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5821: {
5823:   PetscInt       numRows;
5824:   const PetscInt *rows;

5830:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5831:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5832:   MatCheckPreallocated(mat,1);

5834:   ISGetLocalSize(is,&numRows);
5835:   ISGetIndices(is,&rows);
5836:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5837:   ISRestoreIndices(is,&rows);
5838:   return(0);
5839: }

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

5846:    Not Collective

5848:    Input Parameter:
5849: .  mat - the matrix

5851:    Output Parameters:
5852: +  m - the number of global rows
5853: -  n - the number of global columns

5855:    Note: both output parameters can be PETSC_NULL on input.

5857:    Level: beginner

5859:    Concepts: matrices^size

5861: .seealso: MatGetLocalSize()
5862: @*/
5863: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5864: {
5867:   if (m) *m = mat->rmap->N;
5868:   if (n) *n = mat->cmap->N;
5869:   return(0);
5870: }

5874: /*@
5875:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5876:    stored locally.  This information may be implementation dependent, so
5877:    use with care.

5879:    Not Collective

5881:    Input Parameters:
5882: .  mat - the matrix

5884:    Output Parameters:
5885: +  m - the number of local rows
5886: -  n - the number of local columns

5888:    Note: both output parameters can be PETSC_NULL on input.

5890:    Level: beginner

5892:    Concepts: matrices^local size

5894: .seealso: MatGetSize()
5895: @*/
5896: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5897: {
5902:   if (m) *m = mat->rmap->n;
5903:   if (n) *n = mat->cmap->n;
5904:   return(0);
5905: }

5909: /*@
5910:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5911:    this processor. (The columns of the "diagonal block")

5913:    Not Collective, unless matrix has not been allocated, then collective on Mat

5915:    Input Parameters:
5916: .  mat - the matrix

5918:    Output Parameters:
5919: +  m - the global index of the first local column
5920: -  n - one more than the global index of the last local column

5922:    Notes: both output parameters can be PETSC_NULL on input.

5924:    Level: developer

5926:    Concepts: matrices^column ownership

5928: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

5930: @*/
5931: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5932: {

5939:   MatCheckPreallocated(mat,1);
5940:   if (m) *m = mat->cmap->rstart;
5941:   if (n) *n = mat->cmap->rend;
5942:   return(0);
5943: }

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

5953:    Not Collective, unless matrix has not been allocated, then collective on Mat

5955:    Input Parameters:
5956: .  mat - the matrix

5958:    Output Parameters:
5959: +  m - the global index of the first local row
5960: -  n - one more than the global index of the last local row

5962:    Note: both output parameters can be PETSC_NULL on input.

5964:    Level: beginner

5966:    Concepts: matrices^row ownership

5968: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

5970: @*/
5971: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5972: {

5979:   MatCheckPreallocated(mat,1);
5980:   if (m) *m = mat->rmap->rstart;
5981:   if (n) *n = mat->rmap->rend;
5982:   return(0);
5983: }

5987: /*@C
5988:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5989:    each process

5991:    Not Collective, unless matrix has not been allocated, then collective on Mat

5993:    Input Parameters:
5994: .  mat - the matrix

5996:    Output Parameters:
5997: .  ranges - start of each processors portion plus one more then the total length at the end

5999:    Level: beginner

6001:    Concepts: matrices^row ownership

6003: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6005: @*/
6006: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6007: {

6013:   MatCheckPreallocated(mat,1);
6014:   PetscLayoutGetRanges(mat->rmap,ranges);
6015:   return(0);
6016: }

6020: /*@C
6021:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6022:    this processor. (The columns of the "diagonal blocks" for each process)

6024:    Not Collective, unless matrix has not been allocated, then collective on Mat

6026:    Input Parameters:
6027: .  mat - the matrix

6029:    Output Parameters:
6030: .  ranges - start of each processors portion plus one more then the total length at the end

6032:    Level: beginner

6034:    Concepts: matrices^column ownership

6036: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6038: @*/
6039: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6040: {

6046:   MatCheckPreallocated(mat,1);
6047:   PetscLayoutGetRanges(mat->cmap,ranges);
6048:   return(0);
6049: }

6053: /*@C
6054:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6055:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
6056:    to complete the factorization.

6058:    Collective on Mat

6060:    Input Parameters:
6061: +  mat - the matrix
6062: .  row - row permutation
6063: .  column - column permutation
6064: -  info - structure containing 
6065: $      levels - number of levels of fill.
6066: $      expected fill - as ratio of original fill.
6067: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6068:                 missing diagonal entries)

6070:    Output Parameters:
6071: .  fact - new matrix that has been symbolically factored

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

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

6081:    Level: developer

6083:   Concepts: matrices^symbolic LU factorization
6084:   Concepts: matrices^factorization
6085:   Concepts: LU^symbolic factorization

6087: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6088:           MatGetOrdering(), MatFactorInfo

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

6093: @*/
6094: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6095: {

6105:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6106:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6107:   if (!(fact)->ops->ilufactorsymbolic) {
6108:     const MatSolverPackage spackage;
6109:     MatFactorGetSolverPackage(fact,&spackage);
6110:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6111:   }
6112:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6113:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6114:   MatCheckPreallocated(mat,2);

6116:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6117:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6118:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6119:   return(0);
6120: }

6124: /*@C
6125:    MatICCFactorSymbolic - Performs symbolic incomplete
6126:    Cholesky factorization for a symmetric matrix.  Use 
6127:    MatCholeskyFactorNumeric() to complete the factorization.

6129:    Collective on Mat

6131:    Input Parameters:
6132: +  mat - the matrix
6133: .  perm - row and column permutation
6134: -  info - structure containing 
6135: $      levels - number of levels of fill.
6136: $      expected fill - as ratio of original fill.

6138:    Output Parameter:
6139: .  fact - the factored matrix

6141:    Notes:
6142:    Most users should employ the KSP interface for linear solvers
6143:    instead of working directly with matrix algebra routines such as this.
6144:    See, e.g., KSPCreate().

6146:    Level: developer

6148:   Concepts: matrices^symbolic incomplete Cholesky factorization
6149:   Concepts: matrices^factorization
6150:   Concepts: Cholsky^symbolic factorization

6152: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6157: @*/
6158: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6159: {

6168:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6169:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6170:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6171:   if (!(fact)->ops->iccfactorsymbolic) {
6172:     const MatSolverPackage spackage;
6173:     MatFactorGetSolverPackage(fact,&spackage);
6174:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6175:   }
6176:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6177:   MatCheckPreallocated(mat,2);

6179:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6180:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6181:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6182:   return(0);
6183: }

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

6193:    Not Collective

6195:    Input Parameter:
6196: .  mat - the matrix

6198:    Output Parameter:
6199: .  v - the location of the values


6202:    Fortran Note:
6203:    This routine is used differently from Fortran, e.g.,
6204: .vb
6205:         Mat         mat
6206:         PetscScalar mat_array(1)
6207:         PetscOffset i_mat
6208:         PetscErrorCode ierr
6209:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

6215:         [... other code ...]
6216:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6217: .ve

6219:    See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a> and 
6220:    src/mat/examples/tests for details.

6222:    Level: advanced

6224:    Concepts: matrices^access array

6226: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6227: @*/
6228: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6229: {

6236:   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6237:   MatCheckPreallocated(mat,1);
6238:   (*mat->ops->getarray)(mat,v);
6239:   CHKMEMQ;
6240:   return(0);
6241: }

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

6248:    Not Collective

6250:    Input Parameter:
6251: +  mat - the matrix
6252: -  v - the location of the values

6254:    Fortran Note:
6255:    This routine is used differently from Fortran, e.g.,
6256: .vb
6257:         Mat         mat
6258:         PetscScalar mat_array(1)
6259:         PetscOffset i_mat
6260:         PetscErrorCode ierr
6261:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

6267:         [... other code ...]
6268:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6269: .ve

6271:    See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6272:    src/mat/examples/tests for details

6274:    Level: advanced

6276: .seealso: MatGetArray(), MatRestoreArrayF90()
6277: @*/
6278: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6279: {

6286:   CHKMEMQ;
6287:   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6288:   (*mat->ops->restorearray)(mat,v);
6289:   PetscObjectStateIncrease((PetscObject)mat);
6290: #if defined(PETSC_HAVE_CUSP)
6291:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6292:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6293:   }
6294: #endif
6295:   return(0);
6296: }

6300: /*@C
6301:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6302:    points to an array of valid matrices, they may be reused to store the new
6303:    submatrices.

6305:    Collective on Mat

6307:    Input Parameters:
6308: +  mat - the matrix
6309: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6310: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6311: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6313:    Output Parameter:
6314: .  submat - the array of submatrices

6316:    Notes:
6317:    MatGetSubMatrices() can extract ONLY sequential submatrices
6318:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6319:    to extract a parallel submatrix.

6321:    Currently both row and column indices must be sorted to guarantee 
6322:    correctness with all matrix types.

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

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

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

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

6337:    For BAIJ matrices the index sets must respect the block structure, that is if they
6338:    request one row/column in a block, they must request all rows/columns that are in
6339:    that block. For example, if the block size is 2 you cannot request just row 0 and 
6340:    column 0.

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

6346:    Level: advanced

6348:    Concepts: matrices^accessing submatrices
6349:    Concepts: submatrices

6351: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6352: @*/
6353: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6354: {
6356:   PetscInt        i;
6357:   PetscBool       eq;

6362:   if (n) {
6367:   }
6369:   if (n && scall == MAT_REUSE_MATRIX) {
6372:   }
6373:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6374:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6375:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6376:   MatCheckPreallocated(mat,1);

6378:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6379:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6380:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6381:   for (i=0; i<n; i++) {
6382:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6383:       ISEqual(irow[i],icol[i],&eq);
6384:       if (eq) {
6385:         if (mat->symmetric){
6386:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6387:         } else if (mat->hermitian) {
6388:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6389:         } else if (mat->structurally_symmetric) {
6390:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6391:         }
6392:       }
6393:     }
6394:   }
6395:   return(0);
6396: }

6400: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6401: {
6403:   PetscInt        i;
6404:   PetscBool       eq;

6409:   if (n) {
6414:   }
6416:   if (n && scall == MAT_REUSE_MATRIX) {
6419:   }
6420:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6421:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6422:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6423:   MatCheckPreallocated(mat,1);

6425:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6426:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6427:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6428:   for (i=0; i<n; i++) {
6429:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6430:       ISEqual(irow[i],icol[i],&eq);
6431:       if (eq) {
6432:         if (mat->symmetric){
6433:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6434:         } else if (mat->hermitian) {
6435:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6436:         } else if (mat->structurally_symmetric) {
6437:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6438:         }
6439:       }
6440:     }
6441:   }
6442:   return(0);
6443: }

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

6450:    Collective on Mat

6452:    Input Parameters:
6453: +  n - the number of local matrices
6454: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6455:                        sequence of MatGetSubMatrices())

6457:    Level: advanced

6459:     Notes: Frees not only the matrices, but also the array that contains the matrices
6460:            In Fortran will not free the array.

6462: .seealso: MatGetSubMatrices()
6463: @*/
6464: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6465: {
6467:   PetscInt       i;

6470:   if (!*mat) return(0);
6471:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6473:   for (i=0; i<n; i++) {
6474:     MatDestroy(&(*mat)[i]);
6475:   }
6476:   /* memory is allocated even if n = 0 */
6477:   PetscFree(*mat);
6478:   *mat = PETSC_NULL;
6479:   return(0);
6480: }

6484: /*@C
6485:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 

6487:    Collective on Mat

6489:    Input Parameters:
6490: .  mat - the matrix

6492:    Output Parameter:
6493: .  matstruct - the sequential matrix with the nonzero structure of mat

6495:   Level: intermediate

6497: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6498: @*/
6499: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6500: {

6506: 
6508:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6509:   MatCheckPreallocated(mat,1);

6511:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6512:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6513:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6514:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6515:   return(0);
6516: }

6520: /*@C
6521:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6523:    Collective on Mat

6525:    Input Parameters:
6526: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6527:                        sequence of MatGetSequentialNonzeroStructure())

6529:    Level: advanced

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

6533: .seealso: MatGetSeqNonzeroStructure()
6534: @*/
6535: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6536: {

6541:   MatDestroy(mat);
6542:   return(0);
6543: }

6547: /*@
6548:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6549:    replaces the index sets by larger ones that represent submatrices with
6550:    additional overlap.

6552:    Collective on Mat

6554:    Input Parameters:
6555: +  mat - the matrix
6556: .  n   - the number of index sets
6557: .  is  - the array of index sets (these index sets will changed during the call)
6558: -  ov  - the additional overlap requested

6560:    Level: developer

6562:    Concepts: overlap
6563:    Concepts: ASM^computing overlap

6565: .seealso: MatGetSubMatrices()
6566: @*/
6567: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6568: {

6574:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6575:   if (n) {
6578:   }
6579:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6580:   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6581:   MatCheckPreallocated(mat,1);

6583:   if (!ov) return(0);
6584:   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6585:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6586:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6587:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6588:   return(0);
6589: }

6593: /*@
6594:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6595:    block row and block diagonal formats.
6596:    
6597:    Not Collective

6599:    Input Parameter:
6600: .  mat - the matrix

6602:    Output Parameter:
6603: .  bs - block size

6605:    Notes:
6606:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6608:    Level: intermediate

6610:    Concepts: matrices^block size

6612: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6613: @*/
6614: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6615: {

6621:   MatCheckPreallocated(mat,1);
6622:   *bs = mat->rmap->bs;
6623:   return(0);
6624: }

6628: /*@
6629:    MatGetBlockSizes - Returns the matrix block row and column sizes; 
6630:    useful especially for the block row and block diagonal formats.
6631:    
6632:    Not Collective

6634:    Input Parameter:
6635: .  mat - the matrix

6637:    Output Parameter:
6638: .  rbs - row block size
6639: .  cbs - coumn block size

6641:    Notes:
6642:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6644:    Level: intermediate

6646:    Concepts: matrices^block size

6648: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6649: @*/
6650: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6651: {

6658:   MatCheckPreallocated(mat,1);
6659:   if(rbs) *rbs = mat->rmap->bs;
6660:   if(cbs) *cbs = mat->cmap->bs;
6661:   return(0);
6662: }

6666: /*@
6667:    MatSetBlockSize - Sets the matrix block size.
6668:    
6669:    Logically Collective on Mat

6671:    Input Parameters:
6672: +  mat - the matrix
6673: -  bs - block size

6675:    Notes:
6676:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6678:    Level: intermediate

6680:    Concepts: matrices^block size

6682: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6683: @*/
6684: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6685: {

6691:   PetscLayoutSetBlockSize(mat->rmap,bs);
6692:   PetscLayoutSetBlockSize(mat->cmap,bs);
6693:   return(0);
6694: }

6698: /*@
6699:    MatSetBlockSizes - Sets the matrix block row and column sizes.
6700:    
6701:    Logically Collective on Mat

6703:    Input Parameters:
6704: +  mat - the matrix
6705: -  rbs - row block size
6706: -  cbs - column block size

6708:    Notes:
6709:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6711:    Level: intermediate

6713:    Concepts: matrices^block size

6715: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6716: @*/
6717: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6718: {

6724:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6725:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6726:   return(0);
6727: }

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

6734:    Collective on Mat

6736:     Input Parameters:
6737: +   mat - the matrix
6738: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6739: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6740: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6741:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6742:                  always used.

6744:     Output Parameters:
6745: +   n - number of rows in the (possibly compressed) matrix
6746: .   ia - the row pointers [of length n+1]
6747: .   ja - the column indices
6748: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6749:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6751:     Level: developer

6753:     Notes: You CANNOT change any of the ia[] or ja[] values.

6755:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6757:     Fortran Node

6759:            In Fortran use
6760: $           PetscInt ia(1), ja(1)
6761: $           PetscOffset iia, jja
6762: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6763: $
6764: $          or 
6765: $
6766: $           PetscScalar, pointer :: xx_v(:)
6767: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6768:   
6769:  
6770:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6772: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6773: @*/
6774: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6775: {

6785:   MatCheckPreallocated(mat,1);
6786:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6787:   else {
6788:     *done = PETSC_TRUE;
6789:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6790:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6791:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6792:   }
6793:   return(0);
6794: }

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

6801:     Collective on Mat

6803:     Input Parameters:
6804: +   mat - the matrix
6805: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6806: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6807:                 symmetrized
6808: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6809:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6810:                  always used.

6812:     Output Parameters:
6813: +   n - number of columns in the (possibly compressed) matrix
6814: .   ia - the column pointers
6815: .   ja - the row indices
6816: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6818:     Level: developer

6820: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6821: @*/
6822: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6823: {

6833:   MatCheckPreallocated(mat,1);
6834:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6835:   else {
6836:     *done = PETSC_TRUE;
6837:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6838:   }
6839:   return(0);
6840: }

6844: /*@C
6845:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6846:     MatGetRowIJ().

6848:     Collective on Mat

6850:     Input Parameters:
6851: +   mat - the matrix
6852: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6853: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6854:                 symmetrized
6855: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6856:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6857:                  always used.

6859:     Output Parameters:
6860: +   n - size of (possibly compressed) matrix
6861: .   ia - the row pointers
6862: .   ja - the column indices
6863: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6865:     Level: developer

6867: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6868: @*/
6869: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6870: {

6879:   MatCheckPreallocated(mat,1);

6881:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6882:   else {
6883:     *done = PETSC_TRUE;
6884:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6885:   }
6886:   return(0);
6887: }

6891: /*@C
6892:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6893:     MatGetColumnIJ().

6895:     Collective on Mat

6897:     Input Parameters:
6898: +   mat - the matrix
6899: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6900: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6901:                 symmetrized
6902: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6903:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6904:                  always used.

6906:     Output Parameters:
6907: +   n - size of (possibly compressed) matrix
6908: .   ia - the column pointers
6909: .   ja - the row indices
6910: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6912:     Level: developer

6914: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6915: @*/
6916: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6917: {

6926:   MatCheckPreallocated(mat,1);

6928:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6929:   else {
6930:     *done = PETSC_TRUE;
6931:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6932:   }
6933:   return(0);
6934: }

6938: /*@C
6939:     MatColoringPatch -Used inside matrix coloring routines that 
6940:     use MatGetRowIJ() and/or MatGetColumnIJ().

6942:     Collective on Mat

6944:     Input Parameters:
6945: +   mat - the matrix
6946: .   ncolors - max color value
6947: .   n   - number of entries in colorarray
6948: -   colorarray - array indicating color for each column

6950:     Output Parameters:
6951: .   iscoloring - coloring generated using colorarray information

6953:     Level: developer

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

6957: @*/
6958: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6959: {

6967:   MatCheckPreallocated(mat,1);

6969:   if (!mat->ops->coloringpatch){
6970:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6971:   } else {
6972:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6973:   }
6974:   return(0);
6975: }


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

6983:    Logically Collective on Mat

6985:    Input Parameter:
6986: .  mat - the factored matrix to be reset

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

6995:    Note that one can specify in-place ILU(0) factorization by calling 
6996: .vb
6997:      PCType(pc,PCILU);
6998:      PCFactorSeUseInPlace(pc);
6999: .ve
7000:    or by using the options -pc_type ilu -pc_factor_in_place

7002:    In-place factorization ILU(0) can also be used as a local
7003:    solver for the blocks within the block Jacobi or additive Schwarz
7004:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion 
7005:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7006:    local solver options.

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

7012:    Level: developer

7014: .seealso: PCFactorSetUseInPlace()

7016:    Concepts: matrices^unfactored

7018: @*/
7019: PetscErrorCode  MatSetUnfactored(Mat mat)
7020: {

7026:   MatCheckPreallocated(mat,1);
7027:   mat->factortype = MAT_FACTOR_NONE;
7028:   if (!mat->ops->setunfactored) return(0);
7029:   (*mat->ops->setunfactored)(mat);
7030:   return(0);
7031: }

7033: /*MC
7034:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

7036:     Synopsis:
7037:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7039:     Not collective

7041:     Input Parameter:
7042: .   x - matrix

7044:     Output Parameters:
7045: +   xx_v - the Fortran90 pointer to the array
7046: -   ierr - error code

7048:     Example of Usage: 
7049: .vb
7050:       PetscScalar, pointer xx_v(:,:)
7051:       ....
7052:       call MatGetArrayF90(x,xx_v,ierr)
7053:       a = xx_v(3)
7054:       call MatRestoreArrayF90(x,xx_v,ierr)
7055: .ve

7057:     Notes:
7058:     Not yet supported for all F90 compilers

7060:     Level: advanced

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

7064:     Concepts: matrices^accessing array

7066: M*/

7068: /*MC
7069:     MatRestoreArrayF90 - Restores a matrix array that has been
7070:     accessed with MatGetArrayF90().

7072:     Synopsis:
7073:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7075:     Not collective

7077:     Input Parameters:
7078: +   x - matrix
7079: -   xx_v - the Fortran90 pointer to the array

7081:     Output Parameter:
7082: .   ierr - error code

7084:     Example of Usage: 
7085: .vb
7086:        PetscScalar, pointer xx_v(:)
7087:        ....
7088:        call MatGetArrayF90(x,xx_v,ierr)
7089:        a = xx_v(3)
7090:        call MatRestoreArrayF90(x,xx_v,ierr)
7091: .ve
7092:    
7093:     Notes:
7094:     Not yet supported for all F90 compilers

7096:     Level: advanced

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

7100: M*/


7105: /*@
7106:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7107:                       as the original matrix.

7109:     Collective on Mat

7111:     Input Parameters:
7112: +   mat - the original matrix
7113: .   isrow - parallel IS containing the rows this processor should obtain
7114: .   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.
7115: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7117:     Output Parameter:
7118: .   newmat - the new submatrix, of the same type as the old

7120:     Level: advanced

7122:     Notes:
7123:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7125:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7127:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7128:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7129:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX  
7130:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when 
7131:    you are finished using it.

7133:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7134:     the input matrix.

7136:     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).

7138:    Example usage:
7139:    Consider the following 8x8 matrix with 34 non-zero values, that is
7140:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7141:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7142:    as follows:

7144: .vb
7145:             1  2  0  |  0  3  0  |  0  4
7146:     Proc0   0  5  6  |  7  0  0  |  8  0
7147:             9  0 10  | 11  0  0  | 12  0
7148:     -------------------------------------
7149:            13  0 14  | 15 16 17  |  0  0
7150:     Proc1   0 18  0  | 19 20 21  |  0  0
7151:             0  0  0  | 22 23  0  | 24  0
7152:     -------------------------------------
7153:     Proc2  25 26 27  |  0  0 28  | 29  0
7154:            30  0  0  | 31 32 33  |  0 34
7155: .ve

7157:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7159: .vb
7160:             2  0  |  0  3  0  |  0
7161:     Proc0   5  6  |  7  0  0  |  8
7162:     -------------------------------
7163:     Proc1  18  0  | 19 20 21  |  0
7164:     -------------------------------
7165:     Proc2  26 27  |  0  0 28  | 29
7166:             0  0  | 31 32 33  |  0
7167: .ve


7170:     Concepts: matrices^submatrices

7172: .seealso: MatGetSubMatrices()
7173: @*/
7174: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7175: {
7177:   PetscMPIInt    size;
7178:   Mat            *local;
7179:   IS             iscoltmp;

7188:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7189:   MatCheckPreallocated(mat,1);
7190:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

7192:   if (!iscol) {
7193:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7194:   } else {
7195:     iscoltmp = iscol;
7196:   }

7198:   /* if original matrix is on just one processor then use submatrix generated */
7199:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7200:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7201:     if (!iscol) {ISDestroy(&iscoltmp);}
7202:     return(0);
7203:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7204:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7205:     *newmat = *local;
7206:     PetscFree(local);
7207:     if (!iscol) {ISDestroy(&iscoltmp);}
7208:     return(0);
7209:   } else if (!mat->ops->getsubmatrix) {
7210:     /* Create a new matrix type that implements the operation using the full matrix */
7211:     switch (cll) {
7212:       case MAT_INITIAL_MATRIX:
7213:         MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7214:         break;
7215:       case MAT_REUSE_MATRIX:
7216:         MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7217:         break;
7218:       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7219:     }
7220:     if (!iscol) {ISDestroy(&iscoltmp);}
7221:     return(0);
7222:   }

7224:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7225:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7226:   if (!iscol) {ISDestroy(&iscoltmp);}
7227:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7228:   return(0);
7229: }

7233: /*@
7234:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7235:    used during the assembly process to store values that belong to 
7236:    other processors.

7238:    Not Collective

7240:    Input Parameters:
7241: +  mat   - the matrix
7242: .  size  - the initial size of the stash.
7243: -  bsize - the initial size of the block-stash(if used).

7245:    Options Database Keys:
7246: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7247: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7249:    Level: intermediate

7251:    Notes: 
7252:      The block-stash is used for values set with MatSetValuesBlocked() while
7253:      the stash is used for values set with MatSetValues()

7255:      Run with the option -info and look for output of the form
7256:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7257:      to determine the appropriate value, MM, to use for size and 
7258:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7259:      to determine the value, BMM to use for bsize

7261:    Concepts: stash^setting matrix size
7262:    Concepts: matrices^stash

7264: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7266: @*/
7267: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7268: {

7274:   MatStashSetInitialSize_Private(&mat->stash,size);
7275:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7276:   return(0);
7277: }

7281: /*@
7282:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
7283:      the matrix

7285:    Neighbor-wise Collective on Mat

7287:    Input Parameters:
7288: +  mat   - the matrix
7289: .  x,y - the vectors
7290: -  w - where the result is stored

7292:    Level: intermediate

7294:    Notes: 
7295:     w may be the same vector as y. 

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

7300:     Concepts: interpolation

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

7304: @*/
7305: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7306: {
7308:   PetscInt       M,N,Ny;

7316:   MatCheckPreallocated(A,1);
7317:   MatGetSize(A,&M,&N);
7318:   VecGetSize(y,&Ny);
7319:   if (M == Ny) {
7320:     MatMultAdd(A,x,y,w);
7321:   } else {
7322:     MatMultTransposeAdd(A,x,y,w);
7323:   }
7324:   return(0);
7325: }

7329: /*@
7330:    MatInterpolate - y = A*x or A'*x depending on the shape of 
7331:      the matrix

7333:    Neighbor-wise Collective on Mat

7335:    Input Parameters:
7336: +  mat   - the matrix
7337: -  x,y - the vectors

7339:    Level: intermediate

7341:    Notes: 
7342:     This allows one to use either the restriction or interpolation (its transpose)
7343:     matrix to do the interpolation

7345:    Concepts: matrices^interpolation

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

7349: @*/
7350: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7351: {
7353:   PetscInt       M,N,Ny;

7360:   MatCheckPreallocated(A,1);
7361:   MatGetSize(A,&M,&N);
7362:   VecGetSize(y,&Ny);
7363:   if (M == Ny) {
7364:     MatMult(A,x,y);
7365:   } else {
7366:     MatMultTranspose(A,x,y);
7367:   }
7368:   return(0);
7369: }

7373: /*@
7374:    MatRestrict - y = A*x or A'*x

7376:    Neighbor-wise Collective on Mat

7378:    Input Parameters:
7379: +  mat   - the matrix
7380: -  x,y - the vectors

7382:    Level: intermediate

7384:    Notes: 
7385:     This allows one to use either the restriction or interpolation (its transpose)
7386:     matrix to do the restriction

7388:    Concepts: matrices^restriction

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

7392: @*/
7393: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7394: {
7396:   PetscInt       M,N,Ny;

7403:   MatCheckPreallocated(A,1);

7405:   MatGetSize(A,&M,&N);
7406:   VecGetSize(y,&Ny);
7407:   if (M == Ny) {
7408:     MatMult(A,x,y);
7409:   } else {
7410:     MatMultTranspose(A,x,y);
7411:   }
7412:   return(0);
7413: }

7417: /*@
7418:    MatGetNullSpace - retrieves the null space to a matrix.

7420:    Logically Collective on Mat and MatNullSpace

7422:    Input Parameters:
7423: +  mat - the matrix
7424: -  nullsp - the null space object

7426:    Level: developer

7428:    Notes:
7429:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7431:    Concepts: null space^attaching to matrix

7433: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7434: @*/
7435: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7436: {
7441:   *nullsp = mat->nullsp;
7442:   return(0);
7443: }

7447: /*@
7448:    MatSetNullSpace - attaches a null space to a matrix.
7449:         This null space will be removed from the resulting vector whenever
7450:         MatMult() is called

7452:    Logically Collective on Mat and MatNullSpace

7454:    Input Parameters:
7455: +  mat - the matrix
7456: -  nullsp - the null space object

7458:    Level: advanced

7460:    Notes:
7461:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7463:    Concepts: null space^attaching to matrix

7465: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7466: @*/
7467: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7468: {

7475:   MatCheckPreallocated(mat,1);
7476:   PetscObjectReference((PetscObject)nullsp);
7477:   MatNullSpaceDestroy(&mat->nullsp);
7478:   mat->nullsp = nullsp;
7479:   return(0);
7480: }

7484: /*@
7485:    MatSetNearNullSpace - attaches a null space to a matrix.
7486:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7488:    Logically Collective on Mat and MatNullSpace

7490:    Input Parameters:
7491: +  mat - the matrix
7492: -  nullsp - the null space object

7494:    Level: advanced

7496:    Notes:
7497:       Overwrites any previous near null space that may have been attached

7499:    Concepts: null space^attaching to matrix

7501: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7502: @*/
7503: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7504: {

7511:   MatCheckPreallocated(mat,1);
7512:   PetscObjectReference((PetscObject)nullsp);
7513:   MatNullSpaceDestroy(&mat->nearnullsp);
7514:   mat->nearnullsp = nullsp;
7515:   return(0);
7516: }

7520: /*@
7521:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7523:    Not Collective

7525:    Input Parameters:
7526: .  mat - the matrix

7528:    Output Parameters:
7529: .  nullsp - the null space object, PETSC_NULL if not set

7531:    Level: developer

7533:    Concepts: null space^attaching to matrix

7535: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7536: @*/
7537: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7538: {

7544:   MatCheckPreallocated(mat,1);
7545:   *nullsp = mat->nearnullsp;
7546:   return(0);
7547: }

7551: /*@C
7552:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7554:    Collective on Mat

7556:    Input Parameters:
7557: +  mat - the matrix
7558: .  row - row/column permutation
7559: .  fill - expected fill factor >= 1.0
7560: -  level - level of fill, for ICC(k)

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

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

7570:    Level: developer

7572:    Concepts: matrices^incomplete Cholesky factorization
7573:    Concepts: Cholesky factorization

7575: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

7580: @*/
7581: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7582: {

7590:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7591:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7592:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7593:   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7594:   MatCheckPreallocated(mat,1);
7595:   (*mat->ops->iccfactor)(mat,row,info);
7596:   PetscObjectStateIncrease((PetscObject)mat);
7597:   return(0);
7598: }

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

7605:    Not Collective

7607:    Input Parameters:
7608: +  mat - the matrix
7609: -  v - the values compute with ADIC

7611:    Level: developer

7613:    Notes:
7614:      Must call MatSetColoring() before using this routine. Also this matrix must already
7615:      have its nonzero pattern determined.

7617: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7618:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7619: @*/
7620: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7621: {


7629:   if (!mat->assembled) {
7630:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7631:   }
7632:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7633:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7634:   (*mat->ops->setvaluesadic)(mat,v);
7635:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7636:   MatView_Private(mat);
7637:   PetscObjectStateIncrease((PetscObject)mat);
7638:   return(0);
7639: }


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

7647:    Not Collective

7649:    Input Parameters:
7650: +  mat - the matrix
7651: -  coloring - the coloring

7653:    Level: developer

7655: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7656:           MatSetValues(), MatSetValuesAdic()
7657: @*/
7658: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7659: {


7667:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7668:   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7669:   (*mat->ops->setcoloring)(mat,coloring);
7670:   return(0);
7671: }

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

7678:    Not Collective

7680:    Input Parameters:
7681: +  mat - the matrix
7682: .  nl - leading dimension of v
7683: -  v - the values compute with ADIFOR

7685:    Level: developer

7687:    Notes:
7688:      Must call MatSetColoring() before using this routine. Also this matrix must already
7689:      have its nonzero pattern determined.

7691: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7692:           MatSetValues(), MatSetColoring()
7693: @*/
7694: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7695: {


7703:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7704:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7705:   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7706:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7707:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7708:   PetscObjectStateIncrease((PetscObject)mat);
7709:   return(0);
7710: }

7714: /*@ 
7715:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
7716:          ghosted ones.

7718:    Not Collective

7720:    Input Parameters:
7721: +  mat - the matrix
7722: -  diag = the diagonal values, including ghost ones

7724:    Level: developer

7726:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7727:       
7728: .seealso: MatDiagonalScale()
7729: @*/
7730: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7731: {
7733:   PetscMPIInt    size;


7740:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7741:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7742:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
7743:   if (size == 1) {
7744:     PetscInt n,m;
7745:     VecGetSize(diag,&n);
7746:     MatGetSize(mat,0,&m);
7747:     if (m == n) {
7748:       MatDiagonalScale(mat,0,diag);
7749:     } else {
7750:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7751:     }
7752:   } else {
7753:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7754:   }
7755:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7756:   PetscObjectStateIncrease((PetscObject)mat);
7757:   return(0);
7758: }

7762: /*@ 
7763:    MatGetInertia - Gets the inertia from a factored matrix

7765:    Collective on Mat

7767:    Input Parameter:
7768: .  mat - the matrix

7770:    Output Parameters:
7771: +   nneg - number of negative eigenvalues
7772: .   nzero - number of zero eigenvalues
7773: -   npos - number of positive eigenvalues

7775:    Level: advanced

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


7780: @*/
7781: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7782: {

7788:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7789:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7790:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7791:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7792:   return(0);
7793: }

7795: /* ----------------------------------------------------------------*/
7798: /*@C
7799:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7801:    Neighbor-wise Collective on Mat and Vecs

7803:    Input Parameters:
7804: +  mat - the factored matrix
7805: -  b - the right-hand-side vectors

7807:    Output Parameter:
7808: .  x - the result vectors

7810:    Notes:
7811:    The vectors b and x cannot be the same.  I.e., one cannot
7812:    call MatSolves(A,x,x).

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

7819:    Level: developer

7821:    Concepts: matrices^triangular solves

7823: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7824: @*/
7825: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7826: {

7832:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7833:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7834:   if (!mat->rmap->N && !mat->cmap->N) return(0);

7836:   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7837:   MatCheckPreallocated(mat,1);
7838:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7839:   (*mat->ops->solves)(mat,b,x);
7840:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7841:   return(0);
7842: }

7846: /*@
7847:    MatIsSymmetric - Test whether a matrix is symmetric

7849:    Collective on Mat

7851:    Input Parameter:
7852: +  A - the matrix to test
7853: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

7855:    Output Parameters:
7856: .  flg - the result

7858:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

7860:    Level: intermediate

7862:    Concepts: matrix^symmetry

7864: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7865: @*/
7866: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7867: {


7874:   if (!A->symmetric_set) {
7875:     if (!A->ops->issymmetric) {
7876:       const MatType mattype;
7877:       MatGetType(A,&mattype);
7878:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7879:     }
7880:     (*A->ops->issymmetric)(A,tol,flg);
7881:     if (!tol) {
7882:       A->symmetric_set = PETSC_TRUE;
7883:       A->symmetric = *flg;
7884:       if (A->symmetric) {
7885:         A->structurally_symmetric_set = PETSC_TRUE;
7886:         A->structurally_symmetric     = PETSC_TRUE;
7887:       }
7888:     }
7889:   } else if (A->symmetric) {
7890:     *flg = PETSC_TRUE;
7891:   } else if (!tol) {
7892:     *flg = PETSC_FALSE;
7893:   } else {
7894:     if (!A->ops->issymmetric) {
7895:       const MatType mattype;
7896:       MatGetType(A,&mattype);
7897:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7898:     }
7899:     (*A->ops->issymmetric)(A,tol,flg);
7900:   }
7901:   return(0);
7902: }

7906: /*@
7907:    MatIsHermitian - Test whether a matrix is Hermitian

7909:    Collective on Mat

7911:    Input Parameter:
7912: +  A - the matrix to test
7913: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

7915:    Output Parameters:
7916: .  flg - the result

7918:    Level: intermediate

7920:    Concepts: matrix^symmetry

7922: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7923:           MatIsSymmetricKnown(), MatIsSymmetric()
7924: @*/
7925: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7926: {


7933:   if (!A->hermitian_set) {
7934:     if (!A->ops->ishermitian) {
7935:       const MatType mattype;
7936:       MatGetType(A,&mattype);
7937:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7938:     }
7939:     (*A->ops->ishermitian)(A,tol,flg);
7940:     if (!tol) {
7941:       A->hermitian_set = PETSC_TRUE;
7942:       A->hermitian = *flg;
7943:       if (A->hermitian) {
7944:         A->structurally_symmetric_set = PETSC_TRUE;
7945:         A->structurally_symmetric     = PETSC_TRUE;
7946:       }
7947:     }
7948:   } else if (A->hermitian) {
7949:     *flg = PETSC_TRUE;
7950:   } else if (!tol) {
7951:     *flg = PETSC_FALSE;
7952:   } else {
7953:     if (!A->ops->ishermitian) {
7954:       const MatType mattype;
7955:       MatGetType(A,&mattype);
7956:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7957:     }
7958:     (*A->ops->ishermitian)(A,tol,flg);
7959:   }
7960:   return(0);
7961: }

7965: /*@
7966:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

7968:    Not Collective

7970:    Input Parameter:
7971: .  A - the matrix to check

7973:    Output Parameters:
7974: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7975: -  flg - the result

7977:    Level: advanced

7979:    Concepts: matrix^symmetry

7981:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7982:          if you want it explicitly checked

7984: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7985: @*/
7986: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
7987: {
7992:   if (A->symmetric_set) {
7993:     *set = PETSC_TRUE;
7994:     *flg = A->symmetric;
7995:   } else {
7996:     *set = PETSC_FALSE;
7997:   }
7998:   return(0);
7999: }

8003: /*@
8004:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8006:    Not Collective

8008:    Input Parameter:
8009: .  A - the matrix to check

8011:    Output Parameters:
8012: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8013: -  flg - the result

8015:    Level: advanced

8017:    Concepts: matrix^symmetry

8019:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8020:          if you want it explicitly checked

8022: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8023: @*/
8024: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8025: {
8030:   if (A->hermitian_set) {
8031:     *set = PETSC_TRUE;
8032:     *flg = A->hermitian;
8033:   } else {
8034:     *set = PETSC_FALSE;
8035:   }
8036:   return(0);
8037: }

8041: /*@
8042:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8044:    Collective on Mat

8046:    Input Parameter:
8047: .  A - the matrix to test

8049:    Output Parameters:
8050: .  flg - the result

8052:    Level: intermediate

8054:    Concepts: matrix^symmetry

8056: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8057: @*/
8058: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8059: {

8065:   if (!A->structurally_symmetric_set) {
8066:     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8067:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8068:     A->structurally_symmetric_set = PETSC_TRUE;
8069:   }
8070:   *flg = A->structurally_symmetric;
8071:   return(0);
8072: }

8076: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8077: /*@ 
8078:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8079:        to be communicated to other processors during the MatAssemblyBegin/End() process

8081:     Not collective

8083:    Input Parameter:
8084: .   vec - the vector

8086:    Output Parameters:
8087: +   nstash   - the size of the stash
8088: .   reallocs - the number of additional mallocs incurred.
8089: .   bnstash   - the size of the block stash
8090: -   breallocs - the number of additional mallocs incurred.in the block stash
8091:  
8092:    Level: advanced

8094: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8095:   
8096: @*/
8097: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8098: {
8101:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8102:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8103:   return(0);
8104: }

8108: /*@C
8109:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
8110:      parallel layout
8111:    
8112:    Collective on Mat

8114:    Input Parameter:
8115: .  mat - the matrix

8117:    Output Parameter:
8118: +   right - (optional) vector that the matrix can be multiplied against
8119: -   left - (optional) vector that the matrix vector product can be stored in

8121:   Level: advanced

8123: .seealso: MatCreate()
8124: @*/
8125: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8126: {

8132:   MatCheckPreallocated(mat,1);
8133:   if (mat->ops->getvecs) {
8134:     (*mat->ops->getvecs)(mat,right,left);
8135:   } else {
8136:     PetscMPIInt size;
8137:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
8138:     if (right) {
8139:       VecCreate(((PetscObject)mat)->comm,right);
8140:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8141:       VecSetBlockSize(*right,mat->rmap->bs);
8142:       VecSetType(*right,VECSTANDARD);
8143:       PetscLayoutReference(mat->cmap,&(*right)->map);
8144:     }
8145:     if (left) {
8146:       VecCreate(((PetscObject)mat)->comm,left);
8147:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8148:       VecSetBlockSize(*left,mat->rmap->bs);
8149:       VecSetType(*left,VECSTANDARD);
8150:       PetscLayoutReference(mat->rmap,&(*left)->map);
8151:     }
8152:   }
8153:   return(0);
8154: }

8158: /*@C
8159:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8160:      with default values.

8162:    Not Collective

8164:    Input Parameters:
8165: .    info - the MatFactorInfo data structure


8168:    Notes: The solvers are generally used through the KSP and PC objects, for example
8169:           PCLU, PCILU, PCCHOLESKY, PCICC

8171:    Level: developer

8173: .seealso: MatFactorInfo

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

8178: @*/

8180: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8181: {

8185:   PetscMemzero(info,sizeof(MatFactorInfo));
8186:   return(0);
8187: }

8191: /*@
8192:    MatPtAP - Creates the matrix product C = P^T * A * P

8194:    Neighbor-wise Collective on Mat

8196:    Input Parameters:
8197: +  A - the matrix
8198: .  P - the projection matrix
8199: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8200: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8202:    Output Parameters:
8203: .  C - the product matrix

8205:    Notes:
8206:    C will be created and must be destroyed by the user with MatDestroy().

8208:    This routine is currently only implemented for pairs of AIJ matrices and classes
8209:    which inherit from AIJ.  

8211:    Level: intermediate

8213: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8214: @*/
8215: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8216: {

8222:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8223:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8226:   MatCheckPreallocated(P,2);
8227:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8228:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8230:   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);
8231:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8232:   MatCheckPreallocated(A,1);

8234:   if (!A->ops->ptap) {
8235:     const MatType mattype;
8236:     MatGetType(A,&mattype);
8237:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8238:   }
8239:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8240:   (*A->ops->ptap)(A,P,scall,fill,C);
8241:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8242:   return(0);
8243: }

8247: /*@
8248:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8250:    Neighbor-wise Collective on Mat

8252:    Input Parameters:
8253: +  A - the matrix
8254: -  P - the projection matrix

8256:    Output Parameters:
8257: .  C - the product matrix

8259:    Notes:
8260:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8261:    the user using MatDeatroy().

8263:    This routine is currently only implemented for pairs of AIJ matrices and classes
8264:    which inherit from AIJ.  C will be of type MATAIJ.

8266:    Level: intermediate

8268: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8269: @*/
8270: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8271: {

8277:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8278:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8281:   MatCheckPreallocated(P,2);
8282:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8283:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8286:   MatCheckPreallocated(C,3);
8287:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8288:   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);
8289:   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);
8290:   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);
8291:   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);
8292:   MatCheckPreallocated(A,1);

8294:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8295:   (*A->ops->ptapnumeric)(A,P,C);
8296:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8297:   return(0);
8298: }

8302: /*@
8303:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8305:    Neighbor-wise Collective on Mat

8307:    Input Parameters:
8308: +  A - the matrix
8309: -  P - the projection matrix

8311:    Output Parameters:
8312: .  C - the (i,j) structure of the product matrix

8314:    Notes:
8315:    C will be created and must be destroyed by the user with MatDestroy().

8317:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8318:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8319:    this (i,j) structure by calling MatPtAPNumeric().

8321:    Level: intermediate

8323: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8324: @*/
8325: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8326: {

8332:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8333:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8334:   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8337:   MatCheckPreallocated(P,2);
8338:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8339:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8342:   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);
8343:   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);
8344:   MatCheckPreallocated(A,1);
8345:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8346:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8347:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8349:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */

8351:   return(0);
8352: }

8356: /*@
8357:    MatRARt - Creates the matrix product C = R * A * R^T

8359:    Neighbor-wise Collective on Mat

8361:    Input Parameters:
8362: +  A - the matrix
8363: .  R - the projection matrix
8364: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8365: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

8367:    Output Parameters:
8368: .  C - the product matrix

8370:    Notes:
8371:    C will be created and must be destroyed by the user with MatDestroy().

8373:    This routine is currently only implemented for pairs of AIJ matrices and classes
8374:    which inherit from AIJ.  

8376:    Level: intermediate

8378: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8379: @*/
8380: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8381: {

8387:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8388:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8391:   MatCheckPreallocated(R,2);
8392:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8393:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8395:   if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)R)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8396:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8397:   MatCheckPreallocated(A,1);

8399:   if (!A->ops->rart) {
8400:     const MatType mattype;
8401:     MatGetType(A,&mattype);
8402:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8403:   }
8404:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8405:   (*A->ops->rart)(A,R,scall,fill,C);
8406:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8407:   return(0);
8408: }

8412: /*@
8413:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8415:    Neighbor-wise Collective on Mat

8417:    Input Parameters:
8418: +  A - the matrix
8419: -  R - the projection matrix

8421:    Output Parameters:
8422: .  C - the product matrix

8424:    Notes:
8425:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8426:    the user using MatDeatroy().

8428:    This routine is currently only implemented for pairs of AIJ matrices and classes
8429:    which inherit from AIJ.  C will be of type MATAIJ.

8431:    Level: intermediate

8433: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8434: @*/
8435: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8436: {

8442:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8443:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8446:   MatCheckPreallocated(R,2);
8447:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8448:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8451:   MatCheckPreallocated(C,3);
8452:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8453:   if (R->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
8454:   if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8455:   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);
8456:   if (R->rmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
8457:   MatCheckPreallocated(A,1);

8459:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8460:   (*A->ops->rartnumeric)(A,R,C);
8461:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8462:   return(0);
8463: }

8467: /*@
8468:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8470:    Neighbor-wise Collective on Mat

8472:    Input Parameters:
8473: +  A - the matrix
8474: -  R - the projection matrix

8476:    Output Parameters:
8477: .  C - the (i,j) structure of the product matrix

8479:    Notes:
8480:    C will be created and must be destroyed by the user with MatDestroy().

8482:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8483:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8484:    this (i,j) structure by calling MatRARtNumeric().

8486:    Level: intermediate

8488: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8489: @*/
8490: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8491: {

8497:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8498:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8499:   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8502:   MatCheckPreallocated(R,2);
8503:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8504:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8507:   if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8508:   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);
8509:   MatCheckPreallocated(A,1);
8510:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8511:   (*A->ops->rartsymbolic)(A,R,fill,C);
8512:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8514:   MatSetBlockSize(*C,A->rmap->bs);
8515:   return(0);
8516: }

8518: extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);

8522: /*@
8523:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8525:    Neighbor-wise Collective on Mat

8527:    Input Parameters:
8528: +  A - the left matrix
8529: .  B - the right matrix
8530: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8531: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8532:           if the result is a dense matrix this is irrelevent

8534:    Output Parameters:
8535: .  C - the product matrix

8537:    Notes:
8538:    Unless scall is MAT_REUSE_MATRIX C will be created.

8540:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8541:    
8542:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8543:    actually needed.

8545:    If you have many matrices with the same non-zero structure to multiply, you 
8546:    should either 
8547: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8548: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8550:    Level: intermediate

8552: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8553: @*/
8554: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8555: {
8557:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8558:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8559:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

8564:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8565:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8568:   MatCheckPreallocated(B,2);
8569:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8570:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8572:   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);
8573:   if (scall == MAT_REUSE_MATRIX){
8576:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8577:     (*(*C)->ops->matmult)(A,B,scall,fill,C);
8578:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8579:   }
8580:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8581:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8582:   MatCheckPreallocated(A,1);

8584:   fA = A->ops->matmult;
8585:   fB = B->ops->matmult;
8586:   if (fB == fA) {
8587:     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8588:     mult = fB;
8589:   } else {
8590:     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8591:     char  multname[256];
8592:     PetscStrcpy(multname,"MatMatMult_");
8593:     PetscStrcat(multname,((PetscObject)A)->type_name);
8594:     PetscStrcat(multname,"_");
8595:     PetscStrcat(multname,((PetscObject)B)->type_name);
8596:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8597:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8598:     if(!mult){
8599:       /* dual dispatch using MatQueryOp */
8600:       MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8601:       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);
8602:     }
8603:   }
8604:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8605:   (*mult)(A,B,scall,fill,C);
8606:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8607:   return(0);
8608: }

8612: /*@
8613:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8614:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8616:    Neighbor-wise Collective on Mat

8618:    Input Parameters:
8619: +  A - the left matrix
8620: .  B - the right matrix
8621: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8622:       if C is a dense matrix this is irrelevent
8623:  
8624:    Output Parameters:
8625: .  C - the product matrix

8627:    Notes:
8628:    Unless scall is MAT_REUSE_MATRIX C will be created.

8630:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8631:    actually needed.

8633:    This routine is currently implemented for 
8634:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8635:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8636:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8638:    Level: intermediate

8640:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8641:      We should incorporate them into PETSc.

8643: .seealso: MatMatMult(), MatMatMultNumeric()
8644: @*/
8645: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8646: {
8648:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8649:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8650:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

8655:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8656:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8660:   MatCheckPreallocated(B,2);
8661:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8662:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8665:   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);
8666:   if (fill == PETSC_DEFAULT) fill = 2.0;
8667:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8668:   MatCheckPreallocated(A,1);
8669: 
8670:   Asymbolic = A->ops->matmultsymbolic;
8671:   Bsymbolic = B->ops->matmultsymbolic;
8672:   if (Asymbolic == Bsymbolic){
8673:     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8674:     symbolic = Bsymbolic;
8675:   } else { /* dispatch based on the type of A and B */
8676:     char  symbolicname[256];
8677:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8678:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8679:     PetscStrcat(symbolicname,"_");
8680:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8681:     PetscStrcat(symbolicname,"_C");
8682:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8683:     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);
8684:   }
8685:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8686:   (*symbolic)(A,B,fill,C);
8687:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8688:   return(0);
8689: }

8693: /*@
8694:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8695:    Call this routine after first calling MatMatMultSymbolic().

8697:    Neighbor-wise Collective on Mat

8699:    Input Parameters:
8700: +  A - the left matrix
8701: -  B - the right matrix

8703:    Output Parameters:
8704: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8706:    Notes:
8707:    C must have been created with MatMatMultSymbolic().

8709:    This routine is currently implemented for 
8710:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8711:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8712:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8714:    Level: intermediate

8716: .seealso: MatMatMult(), MatMatMultSymbolic()
8717: @*/
8718: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8719: {
8721:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8722:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8723:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

8728:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8729:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8733:   MatCheckPreallocated(B,2);
8734:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8735:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8739:   MatCheckPreallocated(C,3);
8740:   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8741:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8743:   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);
8744:   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);
8745:   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);
8746:   MatCheckPreallocated(A,1);

8748:   Anumeric = A->ops->matmultnumeric;
8749:   Bnumeric = B->ops->matmultnumeric;
8750:   if (Anumeric == Bnumeric){
8751:     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8752:     numeric = Bnumeric;
8753:   } else {
8754:     char  numericname[256];
8755:     PetscStrcpy(numericname,"MatMatMultNumeric_");
8756:     PetscStrcat(numericname,((PetscObject)A)->type_name);
8757:     PetscStrcat(numericname,"_");
8758:     PetscStrcat(numericname,((PetscObject)B)->type_name);
8759:     PetscStrcat(numericname,"_C");
8760:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8761:     if (!numeric)
8762:       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);
8763:   }
8764:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8765:   (*numeric)(A,B,C);
8766:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8767:   return(0);
8768: }

8772: /*@
8773:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

8775:    Neighbor-wise Collective on Mat

8777:    Input Parameters:
8778: +  A - the left matrix
8779: .  B - the right matrix
8780: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8781: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8783:    Output Parameters:
8784: .  C - the product matrix

8786:    Notes:
8787:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8789:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8791:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8792:    actually needed.

8794:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

8796:    Level: intermediate

8798: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8799: @*/
8800: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8801: {
8803:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8804:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8809:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8810:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8813:   MatCheckPreallocated(B,2);
8814:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8815:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8817:   if (B->cmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
8818:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8819:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8820:   MatCheckPreallocated(A,1);

8822:   fA = A->ops->mattransposemult;
8823:   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8824:   fB = B->ops->mattransposemult;
8825:   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8826:   if (fB!=fA) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

8828:   if (scall == MAT_INITIAL_MATRIX){
8829:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8830:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8831:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8832:   }
8833:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8834:   (*A->ops->mattransposemultnumeric)(A,B,*C);
8835:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8836:   return(0);
8837: }

8841: /*@
8842:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

8844:    Neighbor-wise Collective on Mat

8846:    Input Parameters:
8847: +  A - the left matrix
8848: .  B - the right matrix
8849: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8850: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8852:    Output Parameters:
8853: .  C - the product matrix

8855:    Notes:
8856:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8858:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8860:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8861:    actually needed.

8863:    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8864:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.

8866:    Level: intermediate

8868: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8869: @*/
8870: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8871: {
8873:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8874:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8875:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);

8880:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8881:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8884:   MatCheckPreallocated(B,2);
8885:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8886:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8888:   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);
8889:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8890:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8891:   MatCheckPreallocated(A,1);

8893:   fA = A->ops->transposematmult;
8894:   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8895:   fB = B->ops->transposematmult;
8896:   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8897:   if (fB==fA) {
8898:     transposematmult = fA;
8899:   }
8900:   else {
8901:     /* dual dispatch using MatQueryOp */
8902:     MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8903:     if(!transposematmult)
8904:       SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8905:   }
8906:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8907:   (*transposematmult)(A,B,scall,fill,C);
8908:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8909:   return(0);
8910: }

8914: /*@C
8915:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 

8917:    Collective on Mat

8919:    Input Parameters:
8920: +  mat - the matrix
8921: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8922: .  subcomm - MPI communicator split from the communicator where mat resides in
8923: .  mlocal_red - number of local rows of the redundant matrix
8924: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

8926:    Output Parameter:
8927: .  matredundant - redundant matrix

8929:    Notes:
8930:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the 
8931:    original matrix has not changed from that last call to MatGetRedundantMatrix().

8933:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8934:    calling it. 

8936:    Only MPIAIJ matrix is supported. 
8937:    
8938:    Level: advanced

8940:    Concepts: subcommunicator
8941:    Concepts: duplicate matrix

8943: .seealso: MatDestroy()
8944: @*/
8945: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8946: {

8951:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8954:   }
8955:   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8956:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8957:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8958:   MatCheckPreallocated(mat,1);

8960:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8961:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8962:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8963:   return(0);
8964: }

8968: /*@C
8969:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8970:    a given 'mat' object. Each submatrix can span multiple procs.

8972:    Collective on Mat

8974:    Input Parameters:
8975: +  mat - the matrix
8976: .  subcomm - the subcommunicator obtained by com_split(comm)
8977: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

8979:    Output Parameter:
8980: .  subMat - 'parallel submatrices each spans a given subcomm

8982:   Notes:
8983:   The submatrix partition across processors is dicated by 'subComm' a
8984:   communicator obtained by com_split(comm). The comm_split
8985:   is not restriced to be grouped with consequitive original ranks.

8987:   Due the comm_split() usage, the parallel layout of the submatrices
8988:   map directly to the layout of the original matrix [wrt the local
8989:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
8990:   into the 'DiagonalMat' of the subMat, hence it is used directly from
8991:   the subMat. However the offDiagMat looses some columns - and this is
8992:   reconstructed with MatSetValues()

8994:   Level: advanced

8996:   Concepts: subcommunicator
8997:   Concepts: submatrices

8999: .seealso: MatGetSubMatrices()
9000: @*/
9001: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9002: {
9004:   PetscMPIInt    commsize,subCommSize;

9007:   MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
9008:   MPI_Comm_size(subComm,&subCommSize);
9009:   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9010: 
9011:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9012:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9013:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9014:   return(0);
9015: }

9019: /*@
9020:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9022:    Not Collective

9024:    Input Arguments:
9025:    mat - matrix to extract local submatrix from
9026:    isrow - local row indices for submatrix
9027:    iscol - local column indices for submatrix

9029:    Output Arguments:
9030:    submat - the submatrix

9032:    Level: intermediate

9034:    Notes:
9035:    The submat should be returned with MatRestoreLocalSubMatrix().

9037:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9038:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9040:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9041:    MatSetValuesBlockedLocal() will also be implemented.

9043: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9044: @*/
9045: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9046: {


9056:   if (mat->ops->getlocalsubmatrix) {
9057:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9058:   } else {
9059:     MatCreateLocalRef(mat,isrow,iscol,submat);
9060:   }
9061:   return(0);
9062: }

9066: /*@
9067:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9069:    Not Collective

9071:    Input Arguments:
9072:    mat - matrix to extract local submatrix from
9073:    isrow - local row indices for submatrix
9074:    iscol - local column indices for submatrix
9075:    submat - the submatrix

9077:    Level: intermediate

9079: .seealso: MatGetLocalSubMatrix()
9080: @*/
9081: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9082: {


9093:   if (mat->ops->restorelocalsubmatrix) {
9094:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9095:   } else {
9096:     MatDestroy(submat);
9097:   }
9098:   *submat = PETSC_NULL;
9099:   return(0);
9100: }

9102: /* --------------------------------------------------------*/
9105: /*@
9106:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9108:    Collective on Mat

9110:    Input Parameter:
9111: .  mat - the matrix

9113:    Output Parameter:
9114: .  is - if any rows have zero diagonals this contains the list of them

9116:    Level: developer

9118:    Concepts: matrix-vector product

9120: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9121: @*/
9122: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9123: {

9129:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9130:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9132:   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9133:   (*mat->ops->findzerodiagonals)(mat,is);
9134:   return(0);
9135: }

9139: /*@C
9140:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9142:   Collective on Mat

9144:   Input Parameters:
9145: . mat - the matrix

9147:   Output Parameters:
9148: . values - the block inverses in column major order (FORTRAN-like)

9150:    Note:
9151:    This routine is not available from Fortran.

9153:   Level: advanced
9154: @*/
9155: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9156: {

9161:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9162:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9163:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9164:   (*mat->ops->invertblockdiagonal)(mat,values);
9165:   return(0);
9166: }

9170: /*@C
9171:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9172:     via MatTransposeColoringCreate().

9174:     Collective on MatTransposeColoring

9176:     Input Parameter:
9177: .   c - coloring context

9179:     Level: intermediate

9181: .seealso: MatTransposeColoringCreate()
9182: @*/
9183: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9184: {
9185:   PetscErrorCode       ierr;
9186:   MatTransposeColoring matcolor=*c;

9189:   if (!matcolor) return(0);
9190:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9192:   PetscFree(matcolor->ncolumns);
9193:   PetscFree(matcolor->nrows);
9194:   PetscFree(matcolor->colorforrow);
9195:   PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9196:   PetscFree(matcolor->colorforcol);
9197:   PetscFree(matcolor->columns);
9198:   PetscHeaderDestroy(c);
9199:   return(0);
9200: }

9204: /*@C
9205:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 
9206:     a MatTransposeColoring context has been created, computes a dense B^T by Apply 
9207:     MatTransposeColoring to sparse B.

9209:     Collective on MatTransposeColoring

9211:     Input Parameters:
9212: +   B - sparse matrix B
9213: .   Btdense - symbolic dense matrix B^T
9214: -   coloring - coloring context created with MatTransposeColoringCreate()

9216:     Output Parameter:
9217: .   Btdense - dense matrix B^T 

9219:     Options Database Keys:
9220: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9221: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9222: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9224:     Level: intermediate

9226: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9228: .keywords: coloring
9229: @*/
9230: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9231: {

9238: 
9239:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9240:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9241:   return(0);
9242: }

9246: /*@C
9247:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 
9248:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9249:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 
9250:     Csp from Cden.

9252:     Collective on MatTransposeColoring

9254:     Input Parameters:
9255: +   coloring - coloring context created with MatTransposeColoringCreate()
9256: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9258:     Output Parameter:
9259: .   Csp - sparse matrix  

9261:     Options Database Keys:
9262: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9263: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9264: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9266:     Level: intermediate

9268: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9270: .keywords: coloring
9271: @*/
9272: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9273: {

9280: 
9281:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9282:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9283:   return(0);
9284: }

9288: /*@C
9289:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9291:    Collective on Mat

9293:    Input Parameters:
9294: +  mat - the matrix product C
9295: -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()

9297:     Output Parameter:
9298: .   color - the new coloring context
9299:    
9300:     Level: intermediate

9302: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9303:            MatTransColoringApplyDen()ToSp, MatTransposeColoringView(), 
9304: @*/
9305: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9306: {
9307:   MatTransposeColoring  c;
9308:   MPI_Comm              comm;
9309:   PetscErrorCode        ierr;

9312:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9313:   PetscObjectGetComm((PetscObject)mat,&comm);
9314:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,0,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9316:   c->ctype = iscoloring->ctype;
9317:   if (mat->ops->transposecoloringcreate) {
9318:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9319:   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");

9321:   *color = c;
9322:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9323:   return(0);
9324: }