Date: 2013-07-02T14:40:58+00:00

Actual source code: matrix.c
petsc-3.4.2 2013-07-02

      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_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
     28: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
     29: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
     30: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
     31: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
     32: PetscLogEvent MAT_GetMultiProcBlock;
     33: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
     34: PetscLogEvent MAT_Merge;

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

     40: /*@
     41:    MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations

     43:    Logically Collective on Vec

     45:    Input Parameters:
     46: +  x  - the vector
     47: -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
     48:           it will create one internally.

     50:    Output Parameter:
     51: .  x  - the vector

     53:    Example of Usage:
     54: .vb
     55:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
     56:      VecSetRandom(x,rctx);
     57:      PetscRandomDestroy(rctx);
     58: .ve

     60:    Level: intermediate

     62:    Concepts: vector^setting to random
     63:    Concepts: random^vector

     65: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
     66: @*/
     67: PetscErrorCode  MatSetRandom(Mat x,PetscRandom rctx)
     68: {
     70:   PetscRandom    randObj = NULL;

     77:   if (!rctx) {
     78:     MPI_Comm comm;
     79:     PetscObjectGetComm((PetscObject)x,&comm);
     80:     PetscRandomCreate(comm,&randObj);
     81:     PetscRandomSetFromOptions(randObj);
     82:     rctx = randObj;
     83:   }

     85:   PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
     86:   (*x->ops->setrandom)(x,rctx);
     87:   PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);

     89:   x->assembled = PETSC_TRUE;
     90:   PetscRandomDestroy(&randObj);
     91:   return(0);
     92: }

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

    100:   Input Parameter:
    101: .    A  - the matrix

    103:   Output Parameter:
    104: .    keptrows - the rows that are not completely zero

    106:   Level: intermediate

    108:  @*/
    109: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
    110: {

    115:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    116:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    117:   if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
    118:   (*mat->ops->findnonzerorows)(mat,keptrows);
    119:   return(0);
    120: }

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

    127:    Not Collective

    129:    Input Parameters:
    130: .   A - the matrix

    132:    Output Parameters:
    133: .   a - the diagonal part (which is a SEQUENTIAL matrix)

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

    137:    Level: advanced

    139: @*/
    140: PetscErrorCode  MatGetDiagonalBlock(Mat A,Mat *a)
    141: {
    142:   PetscErrorCode ierr,(*f)(Mat,Mat*);
    143:   PetscMPIInt    size;

    149:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    150:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    151:   MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
    152:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
    153:   if (f) {
    154:     (*f)(A,a);
    155:     return(0);
    156:   } else if (size == 1) {
    157:     *a = A;
    158:   } else {
    159:     MatType mattype;
    160:     MatGetType(A,&mattype);
    161:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
    162:   }
    163:   return(0);
    164: }

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

    171:    Collective on Mat

    173:    Input Parameters:
    174: .  mat - the matrix

    176:    Output Parameter:
    177: .   trace - the sum of the diagonal entries

    179:    Level: advanced

    181: @*/
    182: PetscErrorCode  MatGetTrace(Mat mat,PetscScalar *trace)
    183: {
    185:   Vec            diag;

    188:   MatGetVecs(mat,&diag,NULL);
    189:   MatGetDiagonal(mat,diag);
    190:   VecSum(diag,trace);
    191:   VecDestroy(&diag);
    192:   return(0);
    193: }

    197: /*@
    198:    MatRealPart - Zeros out the imaginary part of the matrix

    200:    Logically Collective on Mat

    202:    Input Parameters:
    203: .  mat - the matrix

    205:    Level: advanced

    208: .seealso: MatImaginaryPart()
    209: @*/
    210: PetscErrorCode  MatRealPart(Mat mat)
    211: {

    217:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    218:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    219:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    220:   MatCheckPreallocated(mat,1);
    221:   (*mat->ops->realpart)(mat);
    222: #if defined(PETSC_HAVE_CUSP)
    223:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    224:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    225:   }
    226: #endif
    227:   return(0);
    228: }

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

    235:    Collective on Mat

    237:    Input Parameter:
    238: .  mat - the matrix

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

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

    246:    Level: advanced

    248: @*/
    249: PetscErrorCode  MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
    250: {

    256:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    257:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    258:   if (!mat->ops->getghosts) {
    259:     if (nghosts) *nghosts = 0;
    260:     if (ghosts) *ghosts = 0;
    261:   } else {
    262:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
    263:   }
    264:   return(0);
    265: }

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

    273:    Logically Collective on Mat

    275:    Input Parameters:
    276: .  mat - the matrix

    278:    Level: advanced

    281: .seealso: MatRealPart()
    282: @*/
    283: PetscErrorCode  MatImaginaryPart(Mat mat)
    284: {

    290:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    291:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    292:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    293:   MatCheckPreallocated(mat,1);
    294:   (*mat->ops->imaginarypart)(mat);
    295: #if defined(PETSC_HAVE_CUSP)
    296:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    297:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    298:   }
    299: #endif
    300:   return(0);
    301: }

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

    308:    Collective on Mat

    310:    Input Parameter:
    311: .  mat - the matrix

    313:    Output Parameters:
    314: +  missing - is any diagonal missing
    315: -  dd - first diagonal entry that is missing (optional)

    317:    Level: advanced

    320: .seealso: MatRealPart()
    321: @*/
    322: PetscErrorCode  MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
    323: {

    329:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    330:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    331:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    332:   (*mat->ops->missingdiagonal)(mat,missing,dd);
    333:   return(0);
    334: }

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

    343:    Not Collective

    345:    Input Parameters:
    346: +  mat - the matrix
    347: -  row - the row to get

    349:    Output Parameters:
    350: +  ncols -  if not NULL, the number of nonzeros in the row
    351: .  cols - if not NULL, the column numbers
    352: -  vals - if not NULL, the values

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

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

    362:    For better efficiency, set cols and/or vals to NULL if you do
    363:    not wish to extract these quantities.

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

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

    376:    Fortran Notes:
    377:    The calling sequence from Fortran is
    378: .vb
    379:    MatGetRow(matrix,row,ncols,cols,values,ierr)
    380:          Mat     matrix (input)
    381:          integer row    (input)
    382:          integer ncols  (output)
    383:          integer cols(maxcols) (output)
    384:          double precision (or double complex) values(maxcols) output
    385: .ve
    386:    where maxcols >= maximum nonzeros in any row of the matrix.

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

    393:    Level: advanced

    395:    Concepts: matrices^row access

    397: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
    398: @*/
    399: PetscErrorCode  MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
    400: {
    402:   PetscInt       incols;

    407:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    408:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    409:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    410:   MatCheckPreallocated(mat,1);
    411:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
    412:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
    413:   if (ncols) *ncols = incols;
    414:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
    415:   return(0);
    416: }

    420: /*@
    421:    MatConjugate - replaces the matrix values with their complex conjugates

    423:    Logically Collective on Mat

    425:    Input Parameters:
    426: .  mat - the matrix

    428:    Level: advanced

    430: .seealso:  VecConjugate()
    431: @*/
    432: PetscErrorCode  MatConjugate(Mat mat)
    433: {
    434: #if defined(PETSC_USE_COMPLEX)

    439:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    440:   if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
    441:   (*mat->ops->conjugate)(mat);
    442: #if defined(PETSC_HAVE_CUSP)
    443:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    444:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    445:   }
    446: #endif
    447:   return(0);
    448: #else
    449:   return 0;
    450: #endif
    451: }

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

    458:    Not Collective

    460:    Input Parameters:
    461: +  mat - the matrix
    462: .  row - the row to get
    463: .  ncols, cols - the number of nonzeros and their columns
    464: -  vals - if nonzero the column values

    466:    Notes:
    467:    This routine should be called after you have finished examining the entries.

    469:    Fortran Notes:
    470:    The calling sequence from Fortran is
    471: .vb
    472:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
    473:       Mat     matrix (input)
    474:       integer row    (input)
    475:       integer ncols  (output)
    476:       integer cols(maxcols) (output)
    477:       double precision (or double complex) values(maxcols) output
    478: .ve
    479:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

    484:    Level: advanced

    486: .seealso:  MatGetRow()
    487: @*/
    488: PetscErrorCode  MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
    489: {

    495:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    496:   if (!mat->ops->restorerow) return(0);
    497:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
    498:   if (ncols) *ncols = 0;
    499:   if (cols)  *cols = NULL;
    500:   if (vals)  *vals = NULL;
    501:   return(0);
    502: }

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

    510:    Not Collective

    512:    Input Parameters:
    513: +  mat - the matrix

    515:    Notes:
    516:    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.

    518:    Level: advanced

    520:    Concepts: matrices^row access

    522: .seealso: MatRestoreRowRowUpperTriangular()
    523: @*/
    524: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
    525: {

    531:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    532:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    533:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    534:   MatCheckPreallocated(mat,1);
    535:   (*mat->ops->getrowuppertriangular)(mat);
    536:   return(0);
    537: }

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

    544:    Not Collective

    546:    Input Parameters:
    547: +  mat - the matrix

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

    553:    Level: advanced

    555: .seealso:  MatGetRowUpperTriangular()
    556: @*/
    557: PetscErrorCode  MatRestoreRowUpperTriangular(Mat mat)
    558: {

    563:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    564:   if (!mat->ops->restorerowuppertriangular) return(0);
    565:   (*mat->ops->restorerowuppertriangular)(mat);
    566:   return(0);
    567: }

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

    575:    Logically Collective on Mat

    577:    Input Parameter:
    578: +  A - the Mat context
    579: -  prefix - the prefix to prepend to all option names

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

    585:    Level: advanced

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

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

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

    603: /*@C
    604:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
    605:    Mat options in the database.

    607:    Logically Collective on Mat

    609:    Input Parameters:
    610: +  A - the Mat context
    611: -  prefix - the prefix to prepend to all option names

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

    617:    Level: advanced

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

    621: .seealso: MatGetOptionsPrefix()
    622: @*/
    623: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
    624: {

    629:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
    630:   return(0);
    631: }

    635: /*@C
    636:    MatGetOptionsPrefix - Sets the prefix used for searching for all
    637:    Mat options in the database.

    639:    Not Collective

    641:    Input Parameter:
    642: .  A - the Mat context

    644:    Output Parameter:
    645: .  prefix - pointer to the prefix string used

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

    650:    Level: advanced

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

    654: .seealso: MatAppendOptionsPrefix()
    655: @*/
    656: PetscErrorCode  MatGetOptionsPrefix(Mat A,const char *prefix[])
    657: {

    662:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
    663:   return(0);
    664: }

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

    671:    Collective on Mat

    673:    Input Parameters:
    674: .  A - the Mat context

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

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

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

    683:    Level: beginner

    685: .keywords: Mat, setup

    687: .seealso: MatCreate(), MatDestroy()
    688: @*/
    689: PetscErrorCode  MatSetUp(Mat A)
    690: {
    691:   PetscMPIInt    size;

    696:   if (!((PetscObject)A)->type_name) {
    697:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
    698:     if (size == 1) {
    699:       MatSetType(A, MATSEQAIJ);
    700:     } else {
    701:       MatSetType(A, MATMPIAIJ);
    702:     }
    703:   }
    704:   if (!A->preallocated && A->ops->setup) {
    705:     PetscInfo(A,"Warning not preallocating matrix storage\n");
    706:     (*A->ops->setup)(A);
    707:   }
    708:   A->preallocated = PETSC_TRUE;
    709:   return(0);
    710: }

    712: #if defined(PETSC_HAVE_AMS)
    713: #include <petscviewerams.h>
    714: #endif
    717: /*@C
    718:    MatView - Visualizes a matrix object.

    720:    Collective on Mat

    722:    Input Parameters:
    723: +  mat - the matrix
    724: -  viewer - visualization context

    726:   Notes:
    727:   The available visualization contexts include
    728: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
    729: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    730:         output where only the first processor opens
    731:         the file.  All other processors send their
    732:         data to the first processor to print.
    733: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

    735:    The user can open alternative visualization contexts with
    736: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
    737: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
    738:          specified file; corresponding input uses MatLoad()
    739: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
    740:          an X window display
    741: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
    742:          Currently only the sequential dense and AIJ
    743:          matrix types support the Socket viewer.

    745:    The user can call PetscViewerSetFormat() to specify the output
    746:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
    747:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
    748: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
    749: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
    750: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
    751: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
    752:          format common among all matrix types
    753: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
    754:          format (which is in many cases the same as the default)
    755: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
    756:          size and structure (not the matrix entries)
    757: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
    758:          the matrix structure

    760:    Options Database Keys:
    761: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
    762: .  -mat_view ::ascii_info_detail - Prints more detailed info
    763: .  -mat_view - Prints matrix in ASCII format
    764: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
    765: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
    766: .  -display <name> - Sets display name (default is host)
    767: .  -draw_pause <sec> - Sets number of seconds to pause after display
    768: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
    769: .  -viewer_socket_machine <machine>
    770: .  -viewer_socket_port <port>
    771: .  -mat_view binary - save matrix to file in binary format
    772: -  -viewer_binary_filename <name>
    773:    Level: beginner

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

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

    781:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
    782:       And then use the following mouse functions:
    783:           left mouse: zoom in
    784:           middle mouse: zoom out
    785:           right mouse: continue with the simulation

    787:    Concepts: matrices^viewing
    788:    Concepts: matrices^plotting
    789:    Concepts: matrices^printing

    791: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
    792:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
    793: @*/
    794: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
    795: {
    796:   PetscErrorCode    ierr;
    797:   PetscInt          rows,cols,bs;
    798:   PetscBool         iascii;
    799:   PetscViewerFormat format;
    800: #if defined(PETSC_HAVE_AMS)
    801:   PetscBool      isams;
    802: #endif

    807:   if (!viewer) {
    808:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
    809:   }
    812:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
    813:   MatCheckPreallocated(mat,1);

    815:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
    816:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    817: #if defined(PETSC_HAVE_AMS)
    818:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERAMS,&isams);
    819: #endif
    820:   if (iascii) {
    821:     PetscViewerGetFormat(viewer,&format);
    822:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    823:       PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
    824:       PetscViewerASCIIPushTab(viewer);
    825:       MatGetSize(mat,&rows,&cols);
    826:       MatGetBlockSize(mat,&bs);
    827:       if (bs != 1) {
    828:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
    829:       } else {
    830:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
    831:       }
    832:       if (mat->factortype) {
    833:         const MatSolverPackage solver;
    834:         MatFactorGetSolverPackage(mat,&solver);
    835:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
    836:       }
    837:       if (mat->ops->getinfo) {
    838:         MatInfo info;
    839:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
    840:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%lld, allocated nonzeros=%lld\n",(Petsc64bitInt)info.nz_used,(Petsc64bitInt)info.nz_allocated);
    841:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
    842:       }
    843:     }
    844: #if defined(PETSC_HAVE_AMS)
    845:   } else if (isams) {
    846:     if (((PetscObject)mat)->amsmem == -1) {
    847:       PetscObjectViewAMS((PetscObject)mat,viewer);
    848:     }
    849: #endif
    850:   }
    851:   if (mat->ops->view) {
    852:     PetscViewerASCIIPushTab(viewer);
    853:     (*mat->ops->view)(mat,viewer);
    854:     PetscViewerASCIIPopTab(viewer);
    855:   } else if (!iascii) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
    856:   if (iascii) {
    857:     PetscViewerGetFormat(viewer,&format);
    858:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    859:       PetscViewerASCIIPopTab(viewer);
    860:     }
    861:   }
    862:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
    863:   return(0);
    864: }

    866: #if defined(PETSC_USE_DEBUG)
    867: #include <../src/sys/totalview/tv_data_display.h>
    868: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
    869: {
    870:   TV_add_row("Local rows", "int", &mat->rmap->n);
    871:   TV_add_row("Local columns", "int", &mat->cmap->n);
    872:   TV_add_row("Global rows", "int", &mat->rmap->N);
    873:   TV_add_row("Global columns", "int", &mat->cmap->N);
    874:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
    875:   return TV_format_OK;
    876: }
    877: #endif

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

    887:    Collective on PetscViewer

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

    894:    Options Database Keys:
    895:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
    896:    block size
    897: .    -matload_block_size <bs>

    899:    Level: beginner

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

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

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

    914:    In parallel, each processor can load a subset of rows (or the
    915:    entire matrix).  This routine is especially useful when a large
    916:    matrix is stored on disk and only part of it is desired on each
    917:    processor.  For example, a parallel solver may access only some of
    918:    the rows from each processor.  The algorithm used here reads
    919:    relatively small blocks of data rather than reading the entire
    920:    matrix and then subsetting it.

    922:    Notes for advanced users:
    923:    Most users should not need to know the details of the binary storage
    924:    format, since MatLoad() and MatView() completely hide these details.
    925:    But for anyone who's interested, the standard binary matrix storage
    926:    format is

    928: $    int    MAT_FILE_CLASSID
    929: $    int    number of rows
    930: $    int    number of columns
    931: $    int    total number of nonzeros
    932: $    int    *number nonzeros in each row
    933: $    int    *column indices of all nonzeros (starting index is zero)
    934: $    PetscScalar *values of all nonzeros

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

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

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

    946:  @*/
    947: PetscErrorCode  MatLoad(Mat newmat,PetscViewer viewer)
    948: {
    950:   PetscBool      isbinary,flg;

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

    958:   if (!((PetscObject)newmat)->type_name) {
    959:     MatSetType(newmat,MATAIJ);
    960:   }

    962:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
    963:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
    964:   (*newmat->ops->load)(newmat,viewer);
    965:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

    967:   flg  = PETSC_FALSE;
    968:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
    969:   if (flg) {
    970:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
    971:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
    972:   }
    973:   flg  = PETSC_FALSE;
    974:   PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
    975:   if (flg) {
    976:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
    977:   }
    978:   return(0);
    979: }

    983: /*@
    984:    MatDestroy - Frees space taken by a matrix.

    986:    Collective on Mat

    988:    Input Parameter:
    989: .  A - the matrix

    991:    Level: beginner

    993: @*/
    994: PetscErrorCode  MatDestroy(Mat *A)
    995: {

    999:   if (!*A) return(0);
    1001:   if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}

    1003:   PetscViewerDestroy(&(*A)->viewonassembly);
    1004:   /* if memory was published with AMS then destroy it */
    1005:   PetscObjectAMSViewOff((PetscObject)*A);
    1006:   if ((*A)->ops->destroy) {
    1007:     (*(*A)->ops->destroy)(*A);
    1008:   }
    1009:   MatNullSpaceDestroy(&(*A)->nullsp);
    1010:   MatNullSpaceDestroy(&(*A)->nearnullsp);
    1011:   PetscLayoutDestroy(&(*A)->rmap);
    1012:   PetscLayoutDestroy(&(*A)->cmap);
    1013:   PetscHeaderDestroy(A);
    1014:   return(0);
    1015: }

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

    1024:    Not Collective

    1026:    Input Parameters:
    1027: +  mat - the matrix
    1028: .  v - a logically two-dimensional array of values
    1029: .  m, idxm - the number of rows and their global indices
    1030: .  n, idxn - the number of columns and their global indices
    1031: -  addv - either ADD_VALUES or INSERT_VALUES, where
    1032:    ADD_VALUES adds values to any existing entries, and
    1033:    INSERT_VALUES replaces existing entries with new values

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

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

    1041:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
    1042:    options cannot be mixed without intervening calls to the assembly
    1043:    routines.

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

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

    1053:    Efficiency Alert:
    1054:    The routine MatSetValuesBlocked() may offer much better efficiency
    1055:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

    1057:    Level: beginner

    1059:    Concepts: matrices^putting entries in

    1061: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    1062:           InsertMode, INSERT_VALUES, ADD_VALUES
    1063: @*/
    1064: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
    1065: {
    1067: #if defined(PETSC_USE_DEBUG)
    1068:   PetscInt i,j;
    1069: #endif

    1074:   if (!m || !n) return(0); /* no values to insert */
    1078:   MatCheckPreallocated(mat,1);
    1079:   if (mat->insertmode == NOT_SET_VALUES) {
    1080:     mat->insertmode = addv;
    1081:   }
    1082: #if defined(PETSC_USE_DEBUG)
    1083:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
    1084:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    1085:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

    1087:   if (v) {
    1088:     for (i=0; i<m; i++) {
    1089:       for (j=0; j<n; j++) {
    1090:         if (PetscIsInfOrNanScalar(v[i*n+j]))
    1091: #if defined(PETSC_USE_COMPLEX)
    1092:           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]);
    1093: #else
    1094:           SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G at matrix entry (%D,%D)",(PetscReal)v[i*n+j],idxm[i],idxn[j]);
    1095: #endif
    1096:       }
    1097:     }
    1098:   }
    1099: #endif

    1101:   if (mat->assembled) {
    1102:     mat->was_assembled = PETSC_TRUE;
    1103:     mat->assembled     = PETSC_FALSE;
    1104:   }
    1105:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    1106:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
    1107:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    1108: #if defined(PETSC_HAVE_CUSP)
    1109:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    1110:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    1111:   }
    1112: #endif
    1113:   return(0);
    1114: }

    1119: /*@
    1120:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
    1121:         values into a matrix

    1123:    Not Collective

    1125:    Input Parameters:
    1126: +  mat - the matrix
    1127: .  row - the (block) row to set
    1128: -  v - a logically two-dimensional array of values

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

    1133:    All the nonzeros in the row must be provided

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

    1137:    The row must belong to this process

    1139:    Level: intermediate

    1141:    Concepts: matrices^putting entries in

    1143: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    1144:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
    1145: @*/
    1146: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
    1147: {
    1149:   PetscInt       globalrow;

    1155:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
    1156:   MatSetValuesRow(mat,globalrow,v);
    1157: #if defined(PETSC_HAVE_CUSP)
    1158:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    1159:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    1160:   }
    1161: #endif
    1162:   return(0);
    1163: }

    1167: /*@
    1168:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
    1169:         values into a matrix

    1171:    Not Collective

    1173:    Input Parameters:
    1174: +  mat - the matrix
    1175: .  row - the (block) row to set
    1176: -  v - a logically two-dimensional array of values

    1178:    Notes:
    1179:    The values, v, are column-oriented for the block version.

    1181:    All the nonzeros in the row must be provided

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

    1185:    The row must belong to this process

    1187:    Level: advanced

    1189:    Concepts: matrices^putting entries in

    1191: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    1192:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
    1193: @*/
    1194: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
    1195: {

    1201:   MatCheckPreallocated(mat,1);
    1203: #if defined(PETSC_USE_DEBUG)
    1204:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
    1205:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    1206: #endif
    1207:   mat->insertmode = INSERT_VALUES;

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

    1227: /*@
    1228:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
    1229:      Using structured grid indexing

    1231:    Not Collective

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

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

    1247:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
    1248:    options cannot be mixed without intervening calls to the assembly
    1249:    routines.

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

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

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

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

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

    1267:    In Fortran idxm and idxn should be declared as
    1268: $     MatStencil idxm(4,m),idxn(4,n)
    1269:    and the values inserted using
    1270: $    idxm(MatStencil_i,1) = i
    1271: $    idxm(MatStencil_j,1) = j
    1272: $    idxm(MatStencil_k,1) = k
    1273: $    idxm(MatStencil_c,1) = c
    1274:    etc

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

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

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

    1287:    Efficiency Alert:
    1288:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
    1289:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

    1291:    Level: beginner

    1293:    Concepts: matrices^putting entries in

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

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

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

    1346: /*@C
    1347:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
    1348:      Using structured grid indexing

    1350:    Not Collective

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

    1363:    Notes:
    1364:    By default the values, v, are row-oriented and unsorted.
    1365:    See MatSetOption() for other options.

    1367:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
    1368:    options cannot be mixed without intervening calls to the assembly
    1369:    routines.

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

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

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

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

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

    1387:    In Fortran idxm and idxn should be declared as
    1388: $     MatStencil idxm(4,m),idxn(4,n)
    1389:    and the values inserted using
    1390: $    idxm(MatStencil_i,1) = i
    1391: $    idxm(MatStencil_j,1) = j
    1392: $    idxm(MatStencil_k,1) = k
    1393:    etc

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

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

    1403:    Level: beginner

    1405:    Concepts: matrices^putting entries in

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

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

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

    1464: /*@
    1465:    MatSetStencil - Sets the grid information for setting values into a matrix via
    1466:         MatSetValuesStencil()

    1468:    Not Collective

    1470:    Input Parameters:
    1471: +  mat - the matrix
    1472: .  dim - dimension of the grid 1, 2, or 3
    1473: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
    1474: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
    1475: -  dof - number of degrees of freedom per node

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

    1481:    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
    1482:    user.

    1484:    Level: beginner

    1486:    Concepts: matrices^putting entries in

    1488: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
    1489:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
    1490: @*/
    1491: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
    1492: {
    1493:   PetscInt i;

    1500:   mat->stencil.dim = dim + (dof > 1);
    1501:   for (i=0; i<dim; i++) {
    1502:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
    1503:     mat->stencil.starts[i] = starts[dim-i-1];
    1504:   }
    1505:   mat->stencil.dims[dim]   = dof;
    1506:   mat->stencil.starts[dim] = 0;
    1507:   mat->stencil.noc         = (PetscBool)(dof == 1);
    1508:   return(0);
    1509: }

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

    1516:    Not Collective

    1518:    Input Parameters:
    1519: +  mat - the matrix
    1520: .  v - a logically two-dimensional array of values
    1521: .  m, idxm - the number of block rows and their global block indices
    1522: .  n, idxn - the number of block columns and their global block indices
    1523: -  addv - either ADD_VALUES or INSERT_VALUES, where
    1524:    ADD_VALUES adds values to any existing entries, and
    1525:    INSERT_VALUES replaces existing entries with new values

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

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

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

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

    1543:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
    1544:    options cannot be mixed without intervening calls to the assembly
    1545:    routines.

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

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

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

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

    1576:    Level: intermediate

    1578:    Concepts: matrices^putting entries in blocked

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

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

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

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

    1646:    Not Collective; currently only returns a local block

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

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

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

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

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

    1670:    Level: advanced

    1672:    Concepts: matrices^accessing values

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

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

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

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

    1704:   Not Collective

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

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

    1716:   Level: advanced

    1718:   Concepts: matrices^putting entries in

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

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

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

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

    1756:    Not Collective

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

    1764:    Level: intermediate

    1766:    Concepts: matrices^local to global mapping
    1767:    Concepts: local to global mapping^for matrices

    1769: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
    1770: @*/
    1771: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
    1772: {

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

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

    1797:    Not Collective

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

    1805:    Level: intermediate

    1807:    Concepts: matrices^local to global mapping blocked
    1808:    Concepts: local to global mapping^for matrices, blocked

    1810: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
    1811:            MatSetValuesBlocked(), MatSetValuesLocal()
    1812: @*/
    1813: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
    1814: {

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

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

    1833:    Not Collective

    1835:    Input Parameters:
    1836: .  A - the matrix

    1838:    Output Parameters:
    1839: + rmapping - row mapping
    1840: - cmapping - column mapping

    1842:    Level: advanced

    1844:    Concepts: matrices^local to global mapping
    1845:    Concepts: local to global mapping^for matrices

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

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

    1866:    Not Collective

    1868:    Input Parameters:
    1869: .  A - the matrix

    1871:    Output Parameters:
    1872: + rmapping - row mapping
    1873: - cmapping - column mapping

    1875:    Level: advanced

    1877:    Concepts: matrices^local to global mapping blocked
    1878:    Concepts: local to global mapping^for matrices, blocked

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

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

    1900:    Not Collective

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

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

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

    1917:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
    1918:    options cannot be mixed without intervening calls to the assembly
    1919:    routines.

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

    1924:    Level: intermediate

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

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

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

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

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

    1987:    Not Collective

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

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

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

    2005:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
    2006:    options cannot be mixed without intervening calls to the assembly
    2007:    routines.

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

    2012:    Level: intermediate

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

    2016: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
    2017:            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
    2018: @*/
    2019: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
    2020: {

    2026:   MatCheckPreallocated(mat,1);
    2027:   if (!nrow || !ncol) return(0); /* no values to insert */
    2031:   if (mat->insertmode == NOT_SET_VALUES) {
    2032:     mat->insertmode = addv;
    2033:   }
    2034: #if defined(PETSC_USE_DEBUG)
    2035:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
    2036:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2037:   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);
    2038: #endif

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

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

    2092:    Collective on Mat and Vec

    2094:    Input Parameters:
    2095: +  mat - the matrix
    2096: -  x   - the vector to be multiplied

    2098:    Output Parameters:
    2099: .  y - the result

    2101:    Notes:
    2102:    The vectors x and y cannot be the same.  I.e., one cannot
    2103:    call MatMult(A,y,y).

    2105:    Level: developer

    2107:    Concepts: matrix-vector product

    2109: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2110: @*/
    2111: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
    2112: {

    2121:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2122:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2123:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2124:   MatCheckPreallocated(mat,1);

    2126:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
    2127:   (*mat->ops->multdiagonalblock)(mat,x,y);
    2128:   PetscObjectStateIncrease((PetscObject)y);
    2129:   return(0);
    2130: }

    2132: /* --------------------------------------------------------*/
    2135: /*@
    2136:    MatMult - Computes the matrix-vector product, y = Ax.

    2138:    Neighbor-wise Collective on Mat and Vec

    2140:    Input Parameters:
    2141: +  mat - the matrix
    2142: -  x   - the vector to be multiplied

    2144:    Output Parameters:
    2145: .  y - the result

    2147:    Notes:
    2148:    The vectors x and y cannot be the same.  I.e., one cannot
    2149:    call MatMult(A,y,y).

    2151:    Level: beginner

    2153:    Concepts: matrix-vector product

    2155: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2156: @*/
    2157: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
    2158: {

    2166:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2167:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2168:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2169: #if !defined(PETSC_HAVE_CONSTRAINTS)
    2170:   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);
    2171:   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);
    2172:   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);
    2173: #endif
    2174:   VecValidValues(x,2,PETSC_TRUE);
    2175:   MatCheckPreallocated(mat,1);

    2177:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
    2178:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
    2179:   (*mat->ops->mult)(mat,x,y);
    2180:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
    2181:   VecValidValues(y,3,PETSC_FALSE);
    2182:   return(0);
    2183: }

    2187: /*@
    2188:    MatMultTranspose - Computes matrix transpose times a vector.

    2190:    Neighbor-wise Collective on Mat and Vec

    2192:    Input Parameters:
    2193: +  mat - the matrix
    2194: -  x   - the vector to be multilplied

    2196:    Output Parameters:
    2197: .  y - the result

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

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

    2206:    Level: beginner

    2208:    Concepts: matrix vector product^transpose

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

    2222:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2223:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2224:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2225: #if !defined(PETSC_HAVE_CONSTRAINTS)
    2226:   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);
    2227:   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);
    2228: #endif
    2229:   VecValidValues(x,2,PETSC_TRUE);
    2230:   MatCheckPreallocated(mat,1);

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

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

    2246:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

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

    2263:    Level: beginner

    2265:    Concepts: matrix vector product^transpose

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

    2280:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2281:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2282:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2283: #if !defined(PETSC_HAVE_CONSTRAINTS)
    2284:   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);
    2285:   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);
    2286: #endif
    2287:   MatCheckPreallocated(mat,1);

    2289:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
    2290:   if (mat->ops->multhermitiantranspose) {
    2291:     (*mat->ops->multhermitiantranspose)(mat,x,y);
    2292:   } else {
    2293:     VecDuplicate(x,&w);
    2294:     VecCopy(x,w);
    2295:     VecConjugate(w);
    2296:     MatMultTranspose(mat,w,y);
    2297:     VecDestroy(&w);
    2298:     VecConjugate(y);
    2299:   }
    2300:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
    2301:   PetscObjectStateIncrease((PetscObject)y);
    2302:   return(0);
    2303: }

    2307: /*@
    2308:     MatMultAdd -  Computes v3 = v2 + A * v1.

    2310:     Neighbor-wise Collective on Mat and Vec

    2312:     Input Parameters:
    2313: +   mat - the matrix
    2314: -   v1, v2 - the vectors

    2316:     Output Parameters:
    2317: .   v3 - the result

    2319:     Notes:
    2320:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
    2321:     call MatMultAdd(A,v1,v2,v1).

    2323:     Level: beginner

    2325:     Concepts: matrix vector product^addition

    2327: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
    2328: @*/
    2329: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
    2330: {

    2340:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2341:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2342:   if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
    2343:   /* 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);
    2344:      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); */
    2345:   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);
    2346:   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);
    2347:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
    2348:   MatCheckPreallocated(mat,1);

    2350:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
    2351:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
    2352:   (*mat->ops->multadd)(mat,v1,v2,v3);
    2353:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
    2354:   PetscObjectStateIncrease((PetscObject)v3);
    2355:   return(0);
    2356: }

    2360: /*@
    2361:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

    2363:    Neighbor-wise Collective on Mat and Vec

    2365:    Input Parameters:
    2366: +  mat - the matrix
    2367: -  v1, v2 - the vectors

    2369:    Output Parameters:
    2370: .  v3 - the result

    2372:    Notes:
    2373:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
    2374:    call MatMultTransposeAdd(A,v1,v2,v1).

    2376:    Level: beginner

    2378:    Concepts: matrix vector product^transpose and addition

    2380: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
    2381: @*/
    2382: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
    2383: {

    2393:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2394:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2395:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2396:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
    2397:   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
    2398:   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
    2399:   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
    2400:   MatCheckPreallocated(mat,1);

    2402:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
    2403:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
    2404:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
    2405:   PetscObjectStateIncrease((PetscObject)v3);
    2406:   return(0);
    2407: }

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

    2414:    Neighbor-wise Collective on Mat and Vec

    2416:    Input Parameters:
    2417: +  mat - the matrix
    2418: -  v1, v2 - the vectors

    2420:    Output Parameters:
    2421: .  v3 - the result

    2423:    Notes:
    2424:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
    2425:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

    2427:    Level: beginner

    2429:    Concepts: matrix vector product^transpose and addition

    2431: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
    2432: @*/
    2433: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
    2434: {

    2444:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2445:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2446:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2447:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
    2448:   if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
    2449:   if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
    2450:   if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
    2451:   MatCheckPreallocated(mat,1);

    2453:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
    2454:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
    2455:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
    2456:   PetscObjectStateIncrease((PetscObject)v3);
    2457:   return(0);
    2458: }

    2462: /*@
    2463:    MatMultConstrained - The inner multiplication routine for a
    2464:    constrained matrix P^T A P.

    2466:    Neighbor-wise Collective on Mat and Vec

    2468:    Input Parameters:
    2469: +  mat - the matrix
    2470: -  x   - the vector to be multilplied

    2472:    Output Parameters:
    2473: .  y - the result

    2475:    Notes:
    2476:    The vectors x and y cannot be the same.  I.e., one cannot
    2477:    call MatMult(A,y,y).

    2479:    Level: beginner

    2481: .keywords: matrix, multiply, matrix-vector product, constraint
    2482: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2483: @*/
    2484: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
    2485: {

    2492:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2493:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2494:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2495:   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);
    2496:   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);
    2497:   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);

    2499:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
    2500:   (*mat->ops->multconstrained)(mat,x,y);
    2501:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
    2502:   PetscObjectStateIncrease((PetscObject)y);
    2503:   return(0);
    2504: }

    2508: /*@
    2509:    MatMultTransposeConstrained - The inner multiplication routine for a
    2510:    constrained matrix P^T A^T P.

    2512:    Neighbor-wise Collective on Mat and Vec

    2514:    Input Parameters:
    2515: +  mat - the matrix
    2516: -  x   - the vector to be multilplied

    2518:    Output Parameters:
    2519: .  y - the result

    2521:    Notes:
    2522:    The vectors x and y cannot be the same.  I.e., one cannot
    2523:    call MatMult(A,y,y).

    2525:    Level: beginner

    2527: .keywords: matrix, multiply, matrix-vector product, constraint
    2528: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2529: @*/
    2530: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
    2531: {

    2538:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2539:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2540:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2541:   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);
    2542:   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);

    2544:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
    2545:   (*mat->ops->multtransposeconstrained)(mat,x,y);
    2546:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
    2547:   PetscObjectStateIncrease((PetscObject)y);
    2548:   return(0);
    2549: }

    2553: /*@C
    2554:    MatGetFactorType - gets the type of factorization it is

    2556:    Note Collective
    2557:    as the flag

    2559:    Input Parameters:
    2560: .  mat - the matrix

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

    2565:     Level: intermediate

    2567: .seealso:    MatFactorType, MatGetFactor()
    2568: @*/
    2569: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
    2570: {
    2574:   *t = mat->factortype;
    2575:   return(0);
    2576: }

    2578: /* ------------------------------------------------------------*/
    2581: /*@C
    2582:    MatGetInfo - Returns information about matrix storage (number of
    2583:    nonzeros, memory, etc.).

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

    2587:    Input Parameters:
    2588: .  mat - the matrix

    2590:    Output Parameters:
    2591: +  flag - flag indicating the type of parameters to be returned
    2592:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
    2593:    MAT_GLOBAL_SUM - sum over all processors)
    2594: -  info - matrix information context

    2596:    Notes:
    2597:    The MatInfo context contains a variety of matrix data, including
    2598:    number of nonzeros allocated and used, number of mallocs during
    2599:    matrix assembly, etc.  Additional information for factored matrices
    2600:    is provided (such as the fill ratio, number of mallocs during
    2601:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
    2602:    when using the runtime options
    2603: $       -info -mat_view ::ascii_info

    2605:    Example for C/C++ Users:
    2606:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
    2607:    data within the MatInfo context.  For example,
    2608: .vb
    2609:       MatInfo info;
    2610:       Mat     A;
    2611:       double  mal, nz_a, nz_u;

    2613:       MatGetInfo(A,MAT_LOCAL,&info);
    2614:       mal  = info.mallocs;
    2615:       nz_a = info.nz_allocated;
    2616: .ve

    2618:    Example for Fortran Users:
    2619:    Fortran users should declare info as a double precision
    2620:    array of dimension MAT_INFO_SIZE, and then extract the parameters
    2621:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
    2622:    a complete list of parameter names.
    2623: .vb
    2624:       double  precision info(MAT_INFO_SIZE)
    2625:       double  precision mal, nz_a
    2626:       Mat     A
    2627:       integer ierr

    2629:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
    2630:       mal = info(MAT_INFO_MALLOCS)
    2631:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
    2632: .ve

    2634:     Level: intermediate

    2636:     Concepts: matrices^getting information on

    2638:     Developer Note: fortran interface is not autogenerated as the f90
    2639:     interface defintion cannot be generated correctly [due to MatInfo]

    2641: .seealso: MatStashGetInfo()

    2643: @*/
    2644: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
    2645: {

    2652:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2653:   MatCheckPreallocated(mat,1);
    2654:   (*mat->ops->getinfo)(mat,flag,info);
    2655:   return(0);
    2656: }

    2658: /* ----------------------------------------------------------*/

    2662: /*@C
    2663:    MatLUFactor - Performs in-place LU factorization of matrix.

    2665:    Collective on Mat

    2667:    Input Parameters:
    2668: +  mat - the matrix
    2669: .  row - row permutation
    2670: .  col - column permutation
    2671: -  info - options for factorization, includes
    2672: $          fill - expected fill as ratio of original fill.
    2673: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
    2674: $                   Run with the option -info to determine an optimal value to use

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

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

    2684:    Level: developer

    2686:    Concepts: matrices^LU factorization

    2688: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
    2689:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

    2694: @*/
    2695: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
    2696: {
    2698:   MatFactorInfo  tinfo;

    2706:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2707:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2708:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2709:   MatCheckPreallocated(mat,1);
    2710:   if (!info) {
    2711:     MatFactorInfoInitialize(&tinfo);
    2712:     info = &tinfo;
    2713:   }

    2715:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
    2716:   (*mat->ops->lufactor)(mat,row,col,info);
    2717:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
    2718:   PetscObjectStateIncrease((PetscObject)mat);
    2719:   return(0);
    2720: }

    2724: /*@C
    2725:    MatILUFactor - Performs in-place ILU factorization of matrix.

    2727:    Collective on Mat

    2729:    Input Parameters:
    2730: +  mat - the matrix
    2731: .  row - row permutation
    2732: .  col - column permutation
    2733: -  info - structure containing
    2734: $      levels - number of levels of fill.
    2735: $      expected fill - as ratio of original fill.
    2736: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
    2737:                 missing diagonal entries)

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

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

    2747:    Level: developer

    2749:    Concepts: matrices^ILU factorization

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

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

    2756: @*/
    2757: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
    2758: {

    2767:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
    2768:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2769:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2770:   if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2771:   MatCheckPreallocated(mat,1);

    2773:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
    2774:   (*mat->ops->ilufactor)(mat,row,col,info);
    2775:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
    2776:   PetscObjectStateIncrease((PetscObject)mat);
    2777:   return(0);
    2778: }

    2782: /*@C
    2783:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
    2784:    Call this routine before calling MatLUFactorNumeric().

    2786:    Collective on Mat

    2788:    Input Parameters:
    2789: +  fact - the factor matrix obtained with MatGetFactor()
    2790: .  mat - the matrix
    2791: .  row, col - row and column permutations
    2792: -  info - options for factorization, includes
    2793: $          fill - expected fill as ratio of original fill.
    2794: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
    2795: $                   Run with the option -info to determine an optimal value to use

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

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

    2806:    Level: developer

    2808:    Concepts: matrices^LU symbolic factorization

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

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

    2815: @*/
    2816: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
    2817: {

    2827:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2828:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2829:   if (!(fact)->ops->lufactorsymbolic) {
    2830:     const MatSolverPackage spackage;
    2831:     MatFactorGetSolverPackage(fact,&spackage);
    2832:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
    2833:   }
    2834:   MatCheckPreallocated(mat,2);

    2836:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
    2837:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
    2838:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
    2839:   PetscObjectStateIncrease((PetscObject)fact);
    2840:   return(0);
    2841: }

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

    2849:    Collective on Mat

    2851:    Input Parameters:
    2852: +  fact - the factor matrix obtained with MatGetFactor()
    2853: .  mat - the matrix
    2854: -  info - options for factorization

    2856:    Notes:
    2857:    See MatLUFactor() for in-place factorization.  See
    2858:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

    2864:    Level: developer

    2866:    Concepts: matrices^LU numeric factorization

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

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

    2873: @*/
    2874: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
    2875: {

    2883:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2884:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),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);

    2886:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
    2887:   MatCheckPreallocated(mat,2);
    2888:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
    2889:   (fact->ops->lufactornumeric)(fact,mat,info);
    2890:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

    2892:   if (fact->viewonassembly) {
    2893:     PetscViewerPushFormat(fact->viewonassembly,fact->viewformatonassembly);
    2894:     MatView(fact,fact->viewonassembly);
    2895:     PetscViewerPopFormat(fact->viewonassembly);
    2896:   }
    2897:   PetscObjectStateIncrease((PetscObject)fact);
    2898:   return(0);
    2899: }

    2903: /*@C
    2904:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
    2905:    symmetric matrix.

    2907:    Collective on Mat

    2909:    Input Parameters:
    2910: +  mat - the matrix
    2911: .  perm - row and column permutations
    2912: -  f - expected fill as ratio of original fill

    2914:    Notes:
    2915:    See MatLUFactor() for the nonsymmetric case.  See also
    2916:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

    2922:    Level: developer

    2924:    Concepts: matrices^Cholesky factorization

    2926: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
    2927:           MatGetOrdering()

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

    2932: @*/
    2933: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
    2934: {

    2942:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
    2943:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2944:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2945:   if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2946:   MatCheckPreallocated(mat,1);

    2948:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
    2949:   (*mat->ops->choleskyfactor)(mat,perm,info);
    2950:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
    2951:   PetscObjectStateIncrease((PetscObject)mat);
    2952:   return(0);
    2953: }

    2957: /*@C
    2958:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
    2959:    of a symmetric matrix.

    2961:    Collective on Mat

    2963:    Input Parameters:
    2964: +  fact - the factor matrix obtained with MatGetFactor()
    2965: .  mat - the matrix
    2966: .  perm - row and column permutations
    2967: -  info - options for factorization, includes
    2968: $          fill - expected fill as ratio of original fill.
    2969: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
    2970: $                   Run with the option -info to determine an optimal value to use

    2972:    Notes:
    2973:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
    2974:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

    2980:    Level: developer

    2982:    Concepts: matrices^Cholesky symbolic factorization

    2984: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
    2985:           MatGetOrdering()

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

    2990: @*/
    2991: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
    2992: {

    3001:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
    3002:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3003:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3004:   if (!(fact)->ops->choleskyfactorsymbolic) {
    3005:     const MatSolverPackage spackage;
    3006:     MatFactorGetSolverPackage(fact,&spackage);
    3007:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
    3008:   }
    3009:   MatCheckPreallocated(mat,2);

    3011:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
    3012:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
    3013:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
    3014:   PetscObjectStateIncrease((PetscObject)fact);
    3015:   return(0);
    3016: }

    3020: /*@C
    3021:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
    3022:    of a symmetric matrix. Call this routine after first calling
    3023:    MatCholeskyFactorSymbolic().

    3025:    Collective on Mat

    3027:    Input Parameters:
    3028: +  fact - the factor matrix obtained with MatGetFactor()
    3029: .  mat - the initial matrix
    3030: .  info - options for factorization
    3031: -  fact - the symbolic factor of mat

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

    3039:    Level: developer

    3041:    Concepts: matrices^Cholesky numeric factorization

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

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

    3048: @*/
    3049: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
    3050: {

    3058:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3059:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
    3060:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),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);
    3061:   MatCheckPreallocated(mat,2);

    3063:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
    3064:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
    3065:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

    3067:   if (fact->viewonassembly) {
    3068:     PetscViewerPushFormat(fact->viewonassembly,fact->viewformatonassembly);
    3069:     MatView(fact,fact->viewonassembly);
    3070:     PetscViewerPopFormat(fact->viewonassembly);
    3071:   }
    3072:   PetscObjectStateIncrease((PetscObject)fact);
    3073:   return(0);
    3074: }

    3076: /* ----------------------------------------------------------------*/
    3079: /*@
    3080:    MatSolve - Solves A x = b, given a factored matrix.

    3082:    Neighbor-wise Collective on Mat and Vec

    3084:    Input Parameters:
    3085: +  mat - the factored matrix
    3086: -  b - the right-hand-side vector

    3088:    Output Parameter:
    3089: .  x - the result vector

    3091:    Notes:
    3092:    The vectors b and x cannot be the same.  I.e., one cannot
    3093:    call MatSolve(A,x,x).

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

    3100:    Level: developer

    3102:    Concepts: matrices^triangular solves

    3104: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
    3105: @*/
    3106: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
    3107: {

    3117:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3118:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3119:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
    3120:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
    3121:   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);
    3122:   if (!mat->rmap->N && !mat->cmap->N) return(0);
    3123:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3124:   MatCheckPreallocated(mat,1);

    3126:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
    3127:   (*mat->ops->solve)(mat,b,x);
    3128:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
    3129:   PetscObjectStateIncrease((PetscObject)x);
    3130:   return(0);
    3131: }

    3135: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
    3136: {
    3138:   Vec            b,x;
    3139:   PetscInt       m,N,i;
    3140:   PetscScalar    *bb,*xx;
    3141:   PetscBool      flg;

    3144:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
    3145:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
    3146:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
    3147:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

    3149:   MatDenseGetArray(B,&bb);
    3150:   MatDenseGetArray(X,&xx);
    3151:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
    3152:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
    3153:   MatGetVecs(A,&x,&b);
    3154:   for (i=0; i<N; i++) {
    3155:     VecPlaceArray(b,bb + i*m);
    3156:     VecPlaceArray(x,xx + i*m);
    3157:     MatSolve(A,b,x);
    3158:     VecResetArray(x);
    3159:     VecResetArray(b);
    3160:   }
    3161:   VecDestroy(&b);
    3162:   VecDestroy(&x);
    3163:   MatDenseRestoreArray(B,&bb);
    3164:   MatDenseRestoreArray(X,&xx);
    3165:   return(0);
    3166: }

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

    3173:    Neighbor-wise Collective on Mat

    3175:    Input Parameters:
    3176: +  mat - the factored matrix
    3177: -  B - the right-hand-side matrix  (dense matrix)

    3179:    Output Parameter:
    3180: .  X - the result matrix (dense matrix)

    3182:    Notes:
    3183:    The matrices b and x cannot be the same.  I.e., one cannot
    3184:    call MatMatSolve(A,x,x).

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

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

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

    3197:    Level: developer

    3199:    Concepts: matrices^triangular solves

    3201: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
    3202: @*/
    3203: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
    3204: {

    3214:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
    3215:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3216:   if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
    3217:   if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
    3218:   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);
    3219:   if (!A->rmap->N && !A->cmap->N) return(0);
    3220:   MatCheckPreallocated(A,1);

    3222:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
    3223:   if (!A->ops->matsolve) {
    3224:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
    3225:     MatMatSolve_Basic(A,B,X);
    3226:   } else {
    3227:     (*A->ops->matsolve)(A,B,X);
    3228:   }
    3229:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
    3230:   PetscObjectStateIncrease((PetscObject)X);
    3231:   return(0);
    3232: }

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

    3241:    Neighbor-wise Collective on Mat and Vec

    3243:    Input Parameters:
    3244: +  mat - the factored matrix
    3245: -  b - the right-hand-side vector

    3247:    Output Parameter:
    3248: .  x - the result vector

    3250:    Notes:
    3251:    MatSolve() should be used for most applications, as it performs
    3252:    a forward solve followed by a backward solve.

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

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

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

    3267:    Level: developer

    3269:    Concepts: matrices^forward solves

    3271: .seealso: MatSolve(), MatBackwardSolve()
    3272: @*/
    3273: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
    3274: {

    3284:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3285:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3286:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3287:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
    3288:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
    3289:   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);
    3290:   MatCheckPreallocated(mat,1);
    3291:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
    3292:   (*mat->ops->forwardsolve)(mat,b,x);
    3293:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
    3294:   PetscObjectStateIncrease((PetscObject)x);
    3295:   return(0);
    3296: }

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

    3304:    Neighbor-wise Collective on Mat and Vec

    3306:    Input Parameters:
    3307: +  mat - the factored matrix
    3308: -  b - the right-hand-side vector

    3310:    Output Parameter:
    3311: .  x - the result vector

    3313:    Notes:
    3314:    MatSolve() should be used for most applications, as it performs
    3315:    a forward solve followed by a backward solve.

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

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

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

    3330:    Level: developer

    3332:    Concepts: matrices^backward solves

    3334: .seealso: MatSolve(), MatForwardSolve()
    3335: @*/
    3336: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
    3337: {

    3347:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3348:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3349:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3350:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
    3351:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
    3352:   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);
    3353:   MatCheckPreallocated(mat,1);

    3355:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
    3356:   (*mat->ops->backwardsolve)(mat,b,x);
    3357:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
    3358:   PetscObjectStateIncrease((PetscObject)x);
    3359:   return(0);
    3360: }

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

    3367:    Neighbor-wise Collective on Mat and Vec

    3369:    Input Parameters:
    3370: +  mat - the factored matrix
    3371: .  b - the right-hand-side vector
    3372: -  y - the vector to be added to

    3374:    Output Parameter:
    3375: .  x - the result vector

    3377:    Notes:
    3378:    The vectors b and x cannot be the same.  I.e., one cannot
    3379:    call MatSolveAdd(A,x,y,x).

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

    3385:    Level: developer

    3387:    Concepts: matrices^triangular solves

    3389: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
    3390: @*/
    3391: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
    3392: {
    3393:   PetscScalar    one = 1.0;
    3394:   Vec            tmp;

    3406:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3407:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3408:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
    3409:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
    3410:   if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
    3411:   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);
    3412:   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);
    3413:   MatCheckPreallocated(mat,1);

    3415:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
    3416:   if (mat->ops->solveadd) {
    3417:     (*mat->ops->solveadd)(mat,b,y,x);
    3418:   } else {
    3419:     /* do the solve then the add manually */
    3420:     if (x != y) {
    3421:       MatSolve(mat,b,x);
    3422:       VecAXPY(x,one,y);
    3423:     } else {
    3424:       VecDuplicate(x,&tmp);
    3425:       PetscLogObjectParent(mat,tmp);
    3426:       VecCopy(x,tmp);
    3427:       MatSolve(mat,b,x);
    3428:       VecAXPY(x,one,tmp);
    3429:       VecDestroy(&tmp);
    3430:     }
    3431:   }
    3432:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
    3433:   PetscObjectStateIncrease((PetscObject)x);
    3434:   return(0);
    3435: }

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

    3442:    Neighbor-wise Collective on Mat and Vec

    3444:    Input Parameters:
    3445: +  mat - the factored matrix
    3446: -  b - the right-hand-side vector

    3448:    Output Parameter:
    3449: .  x - the result vector

    3451:    Notes:
    3452:    The vectors b and x cannot be the same.  I.e., one cannot
    3453:    call MatSolveTranspose(A,x,x).

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

    3459:    Level: developer

    3461:    Concepts: matrices^triangular solves

    3463: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
    3464: @*/
    3465: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
    3466: {

    3476:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3477:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3478:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
    3479:   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
    3480:   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
    3481:   MatCheckPreallocated(mat,1);
    3482:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
    3483:   (*mat->ops->solvetranspose)(mat,b,x);
    3484:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
    3485:   PetscObjectStateIncrease((PetscObject)x);
    3486:   return(0);
    3487: }

    3491: /*@
    3492:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
    3493:                       factored matrix.

    3495:    Neighbor-wise Collective on Mat and Vec

    3497:    Input Parameters:
    3498: +  mat - the factored matrix
    3499: .  b - the right-hand-side vector
    3500: -  y - the vector to be added to

    3502:    Output Parameter:
    3503: .  x - the result vector

    3505:    Notes:
    3506:    The vectors b and x cannot be the same.  I.e., one cannot
    3507:    call MatSolveTransposeAdd(A,x,y,x).

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

    3513:    Level: developer

    3515:    Concepts: matrices^triangular solves

    3517: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
    3518: @*/
    3519: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
    3520: {
    3521:   PetscScalar    one = 1.0;
    3523:   Vec            tmp;

    3534:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3535:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3536:   if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
    3537:   if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
    3538:   if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
    3539:   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);
    3540:   MatCheckPreallocated(mat,1);

    3542:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
    3543:   if (mat->ops->solvetransposeadd) {
    3544:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
    3545:   } else {
    3546:     /* do the solve then the add manually */
    3547:     if (x != y) {
    3548:       MatSolveTranspose(mat,b,x);
    3549:       VecAXPY(x,one,y);
    3550:     } else {
    3551:       VecDuplicate(x,&tmp);
    3552:       PetscLogObjectParent(mat,tmp);
    3553:       VecCopy(x,tmp);
    3554:       MatSolveTranspose(mat,b,x);
    3555:       VecAXPY(x,one,tmp);
    3556:       VecDestroy(&tmp);
    3557:     }
    3558:   }
    3559:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
    3560:   PetscObjectStateIncrease((PetscObject)x);
    3561:   return(0);
    3562: }
    3563: /* ----------------------------------------------------------------*/

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

    3570:    Neighbor-wise Collective on Mat and Vec

    3572:    Input Parameters:
    3573: +  mat - the matrix
    3574: .  b - the right hand side
    3575: .  omega - the relaxation factor
    3576: .  flag - flag indicating the type of SOR (see below)
    3577: .  shift -  diagonal shift
    3578: .  its - the number of iterations
    3579: -  lits - the number of local iterations

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

    3584:    SOR Flags:
    3585: .     SOR_FORWARD_SWEEP - forward SOR
    3586: .     SOR_BACKWARD_SWEEP - backward SOR
    3587: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
    3588: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
    3589: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
    3590: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
    3591: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
    3592:          upper/lower triangular part of matrix to
    3593:          vector (with omega)
    3594: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

    3596:    Notes:
    3597:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
    3598:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
    3599:    on each processor.

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

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

    3606:    Notes for Advanced Users:
    3607:    The flags are implemented as bitwise inclusive or operations.
    3608:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
    3609:    to specify a zero initial guess for SSOR.

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

    3615:    Vectors x and b CANNOT be the same

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

    3619:    Level: developer

    3621:    Concepts: matrices^relaxation
    3622:    Concepts: matrices^SOR
    3623:    Concepts: matrices^Gauss-Seidel

    3625: @*/
    3626: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
    3627: {

    3637:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3638:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3639:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3640:   if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
    3641:   if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
    3642:   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);
    3643:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
    3644:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
    3645:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

    3647:   MatCheckPreallocated(mat,1);
    3648:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
    3649:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
    3650:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
    3651:   PetscObjectStateIncrease((PetscObject)x);
    3652:   return(0);
    3653: }

    3657: /*
    3658:       Default matrix copy routine.
    3659: */
    3660: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
    3661: {
    3662:   PetscErrorCode    ierr;
    3663:   PetscInt          i,rstart = 0,rend = 0,nz;
    3664:   const PetscInt    *cwork;
    3665:   const PetscScalar *vwork;

    3668:   if (B->assembled) {
    3669:     MatZeroEntries(B);
    3670:   }
    3671:   MatGetOwnershipRange(A,&rstart,&rend);
    3672:   for (i=rstart; i<rend; i++) {
    3673:     MatGetRow(A,i,&nz,&cwork,&vwork);
    3674:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
    3675:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
    3676:   }
    3677:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
    3678:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
    3679:   PetscObjectStateIncrease((PetscObject)B);
    3680:   return(0);
    3681: }

    3685: /*@
    3686:    MatCopy - Copys a matrix to another matrix.

    3688:    Collective on Mat

    3690:    Input Parameters:
    3691: +  A - the matrix
    3692: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

    3694:    Output Parameter:
    3695: .  B - where the copy is put

    3697:    Notes:
    3698:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
    3699:    same nonzero pattern or the routine will crash.

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

    3705:    Level: intermediate

    3707:    Concepts: matrices^copying

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

    3711: @*/
    3712: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
    3713: {
    3715:   PetscInt       i;

    3723:   MatCheckPreallocated(B,2);
    3724:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3725:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3726:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),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);
    3727:   MatCheckPreallocated(A,1);

    3729:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
    3730:   if (A->ops->copy) {
    3731:     (*A->ops->copy)(A,B,str);
    3732:   } else { /* generic conversion */
    3733:     MatCopy_Basic(A,B,str);
    3734:   }

    3736:   B->stencil.dim = A->stencil.dim;
    3737:   B->stencil.noc = A->stencil.noc;
    3738:   for (i=0; i<=A->stencil.dim; i++) {
    3739:     B->stencil.dims[i]   = A->stencil.dims[i];
    3740:     B->stencil.starts[i] = A->stencil.starts[i];
    3741:   }

    3743:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
    3744:   PetscObjectStateIncrease((PetscObject)B);
    3745:   return(0);
    3746: }

    3750: /*@C
    3751:    MatConvert - Converts a matrix to another matrix, either of the same
    3752:    or different type.

    3754:    Collective on Mat

    3756:    Input Parameters:
    3757: +  mat - the matrix
    3758: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
    3759:    same type as the original matrix.
    3760: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
    3761:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
    3762:    MAT_INITIAL_MATRIX.

    3764:    Output Parameter:
    3765: .  M - pointer to place new matrix

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

    3772:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
    3773:    the MPI communicator of the generated matrix is always the same as the communicator
    3774:    of the input matrix.

    3776:    Level: intermediate

    3778:    Concepts: matrices^converting between storage formats

    3780: .seealso: MatCopy(), MatDuplicate()
    3781: @*/
    3782: PetscErrorCode  MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
    3783: {
    3785:   PetscBool      sametype,issame,flg;
    3786:   char           convname[256],mtype[256];
    3787:   Mat            B;

    3793:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3794:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3795:   MatCheckPreallocated(mat,1);
    3796:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

    3798:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
    3799:   if (flg) {
    3800:     newtype = mtype;
    3801:   }
    3802:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
    3803:   PetscStrcmp(newtype,"same",&issame);
    3804:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

    3806:   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);

    3808:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
    3809:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
    3810:   } else {
    3811:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
    3812:     const char     *prefix[3] = {"seq","mpi",""};
    3813:     PetscInt       i;
    3814:     /*
    3815:        Order of precedence:
    3816:        1) See if a specialized converter is known to the current matrix.
    3817:        2) See if a specialized converter is known to the desired matrix class.
    3818:        3) See if a good general converter is registered for the desired class
    3819:           (as of 6/27/03 only MATMPIADJ falls into this category).
    3820:        4) See if a good general converter is known for the current matrix.
    3821:        5) Use a really basic converter.
    3822:     */

    3824:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
    3825:     for (i=0; i<3; i++) {
    3826:       PetscStrcpy(convname,"MatConvert_");
    3827:       PetscStrcat(convname,((PetscObject)mat)->type_name);
    3828:       PetscStrcat(convname,"_");
    3829:       PetscStrcat(convname,prefix[i]);
    3830:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
    3831:       PetscStrcat(convname,"_C");
    3832:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
    3833:       if (conv) goto foundconv;
    3834:     }

    3836:     /* 2)  See if a specialized converter is known to the desired matrix class. */
    3837:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
    3838:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
    3839:     MatSetType(B,newtype);
    3840:     for (i=0; i<3; i++) {
    3841:       PetscStrcpy(convname,"MatConvert_");
    3842:       PetscStrcat(convname,((PetscObject)mat)->type_name);
    3843:       PetscStrcat(convname,"_");
    3844:       PetscStrcat(convname,prefix[i]);
    3845:       PetscStrcat(convname,newtype);
    3846:       PetscStrcat(convname,"_C");
    3847:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
    3848:       if (conv) {
    3849:         MatDestroy(&B);
    3850:         goto foundconv;
    3851:       }
    3852:     }

    3854:     /* 3) See if a good general converter is registered for the desired class */
    3855:     conv = B->ops->convertfrom;
    3856:     MatDestroy(&B);
    3857:     if (conv) goto foundconv;

    3859:     /* 4) See if a good general converter is known for the current matrix */
    3860:     if (mat->ops->convert) {
    3861:       conv = mat->ops->convert;
    3862:     }
    3863:     if (conv) goto foundconv;

    3865:     /* 5) Use a really basic converter. */
    3866:     conv = MatConvert_Basic;

    3868: foundconv:
    3869:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
    3870:     (*conv)(mat,newtype,reuse,M);
    3871:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
    3872:   }
    3873:   PetscObjectStateIncrease((PetscObject)*M);

    3875:   /* Copy Mat options */
    3876:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
    3877:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
    3878:   return(0);
    3879: }

    3883: /*@C
    3884:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

    3886:    Not Collective

    3888:    Input Parameter:
    3889: .  mat - the matrix, must be a factored matrix

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

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

    3898:    Level: intermediate

    3900: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
    3901: @*/
    3902: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
    3903: {
    3904:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

    3909:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
    3910:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
    3911:   if (!conv) {
    3912:     *type = MATSOLVERPETSC;
    3913:   } else {
    3914:     (*conv)(mat,type);
    3915:   }
    3916:   return(0);
    3917: }

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

    3924:    Collective on Mat

    3926:    Input Parameters:
    3927: +  mat - the matrix
    3928: .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
    3929: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,

    3931:    Output Parameters:
    3932: .  f - the factor matrix used with MatXXFactorSymbolic() calls

    3934:    Notes:
    3935:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
    3936:      such as pastix, superlu, mumps etc.

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

    3940:    Level: intermediate

    3942: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
    3943: @*/
    3944: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
    3945: {
    3946:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
    3947:   char           convname[256];

    3953:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3954:   MatCheckPreallocated(mat,1);

    3956:   PetscStrcpy(convname,"MatGetFactor_");
    3957:   PetscStrcat(convname,type);
    3958:   PetscStrcat(convname,"_C");
    3959:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
    3960:   if (!conv) {
    3961:     PetscBool flag;
    3962:     MPI_Comm  comm;

    3964:     PetscObjectGetComm((PetscObject)mat,&comm);
    3965:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
    3966:     if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
    3967:     else 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);
    3968:   }
    3969:   (*conv)(mat,ftype,f);
    3970:   return(0);
    3971: }

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

    3978:    Not Collective

    3980:    Input Parameters:
    3981: +  mat - the matrix
    3982: .  type - name of solver type, for example, superlu, petsc (to use PETSc's default)
    3983: -  ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,

    3985:    Output Parameter:
    3986: .    flg - PETSC_TRUE if the factorization is available

    3988:    Notes:
    3989:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
    3990:      such as pastix, superlu, mumps etc.

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

    3994:    Level: intermediate

    3996: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
    3997: @*/
    3998: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
    3999: {
    4000:   PetscErrorCode ierr, (*conv)(Mat,MatFactorType,PetscBool*);
    4001:   char           convname[256];

    4007:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    4008:   MatCheckPreallocated(mat,1);

    4010:   PetscStrcpy(convname,"MatGetFactorAvailable_");
    4011:   PetscStrcat(convname,type);
    4012:   PetscStrcat(convname,"_C");
    4013:   PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
    4014:   if (!conv) {
    4015:     *flg = PETSC_FALSE;
    4016:   } else {
    4017:     (*conv)(mat,ftype,flg);
    4018:   }
    4019:   return(0);
    4020: }

    4025: /*@
    4026:    MatDuplicate - Duplicates a matrix including the non-zero structure.

    4028:    Collective on Mat

    4030:    Input Parameters:
    4031: +  mat - the matrix
    4032: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
    4033:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

    4035:    Output Parameter:
    4036: .  M - pointer to place new matrix

    4038:    Level: intermediate

    4040:    Concepts: matrices^duplicating

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

    4044: .seealso: MatCopy(), MatConvert()
    4045: @*/
    4046: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
    4047: {
    4049:   Mat            B;
    4050:   PetscInt       i;

    4056:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4057:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    4058:   MatCheckPreallocated(mat,1);

    4060:   *M = 0;
    4061:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
    4062:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
    4063:   (*mat->ops->duplicate)(mat,op,M);
    4064:   B    = *M;

    4066:   B->stencil.dim = mat->stencil.dim;
    4067:   B->stencil.noc = mat->stencil.noc;
    4068:   for (i=0; i<=mat->stencil.dim; i++) {
    4069:     B->stencil.dims[i]   = mat->stencil.dims[i];
    4070:     B->stencil.starts[i] = mat->stencil.starts[i];
    4071:   }

    4073:   B->nooffproczerorows = mat->nooffproczerorows;
    4074:   B->nooffprocentries  = mat->nooffprocentries;

    4076:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
    4077:   PetscObjectStateIncrease((PetscObject)B);
    4078:   return(0);
    4079: }

    4083: /*@
    4084:    MatGetDiagonal - Gets the diagonal of a matrix.

    4086:    Logically Collective on Mat and Vec

    4088:    Input Parameters:
    4089: +  mat - the matrix
    4090: -  v - the vector for storing the diagonal

    4092:    Output Parameter:
    4093: .  v - the diagonal of the matrix

    4095:    Level: intermediate

    4097:    Note:
    4098:    Currently only correct in parallel for square matrices.

    4100:    Concepts: matrices^accessing diagonals

    4102: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
    4103: @*/
    4104: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
    4105: {

    4112:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4113:   if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4114:   MatCheckPreallocated(mat,1);

    4116:   (*mat->ops->getdiagonal)(mat,v);
    4117:   PetscObjectStateIncrease((PetscObject)v);
    4118:   return(0);
    4119: }

    4123: /*@
    4124:    MatGetRowMin - Gets the minimum value (of the real part) of each
    4125:         row of the matrix

    4127:    Logically Collective on Mat and Vec

    4129:    Input Parameters:
    4130: .  mat - the matrix

    4132:    Output Parameter:
    4133: +  v - the vector for storing the maximums
    4134: -  idx - the indices of the column found for each row (optional)

    4136:    Level: intermediate

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

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

    4143:    Concepts: matrices^getting row maximums

    4145: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
    4146:           MatGetRowMax()
    4147: @*/
    4148: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
    4149: {

    4156:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4157:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4158:   MatCheckPreallocated(mat,1);

    4160:   (*mat->ops->getrowmin)(mat,v,idx);
    4161:   PetscObjectStateIncrease((PetscObject)v);
    4162:   return(0);
    4163: }

    4167: /*@
    4168:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
    4169:         row of the matrix

    4171:    Logically Collective on Mat and Vec

    4173:    Input Parameters:
    4174: .  mat - the matrix

    4176:    Output Parameter:
    4177: +  v - the vector for storing the minimums
    4178: -  idx - the indices of the column found for each row (or NULL if not needed)

    4180:    Level: intermediate

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

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

    4187:    Concepts: matrices^getting row maximums

    4189: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
    4190: @*/
    4191: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
    4192: {

    4199:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4200:   if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4201:   MatCheckPreallocated(mat,1);
    4202:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

    4204:   (*mat->ops->getrowminabs)(mat,v,idx);
    4205:   PetscObjectStateIncrease((PetscObject)v);
    4206:   return(0);
    4207: }

    4211: /*@
    4212:    MatGetRowMax - Gets the maximum value (of the real part) of each
    4213:         row of the matrix

    4215:    Logically Collective on Mat and Vec

    4217:    Input Parameters:
    4218: .  mat - the matrix

    4220:    Output Parameter:
    4221: +  v - the vector for storing the maximums
    4222: -  idx - the indices of the column found for each row (optional)

    4224:    Level: intermediate

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

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

    4231:    Concepts: matrices^getting row maximums

    4233: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
    4234: @*/
    4235: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
    4236: {

    4243:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4244:   if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4245:   MatCheckPreallocated(mat,1);

    4247:   (*mat->ops->getrowmax)(mat,v,idx);
    4248:   PetscObjectStateIncrease((PetscObject)v);
    4249:   return(0);
    4250: }

    4254: /*@
    4255:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
    4256:         row of the matrix

    4258:    Logically Collective on Mat and Vec

    4260:    Input Parameters:
    4261: .  mat - the matrix

    4263:    Output Parameter:
    4264: +  v - the vector for storing the maximums
    4265: -  idx - the indices of the column found for each row (or NULL if not needed)

    4267:    Level: intermediate

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

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

    4274:    Concepts: matrices^getting row maximums

    4276: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
    4277: @*/
    4278: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
    4279: {

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

    4291:   (*mat->ops->getrowmaxabs)(mat,v,idx);
    4292:   PetscObjectStateIncrease((PetscObject)v);
    4293:   return(0);
    4294: }

    4298: /*@
    4299:    MatGetRowSum - Gets the sum of each row of the matrix

    4301:    Logically Collective on Mat and Vec

    4303:    Input Parameters:
    4304: .  mat - the matrix

    4306:    Output Parameter:
    4307: .  v - the vector for storing the sum of rows

    4309:    Level: intermediate

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

    4313:    Concepts: matrices^getting row sums

    4315: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
    4316: @*/
    4317: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
    4318: {
    4319:   PetscInt       start = 0, end = 0, row;
    4320:   PetscScalar    *array;

    4327:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4328:   MatCheckPreallocated(mat,1);
    4329:   MatGetOwnershipRange(mat, &start, &end);
    4330:   VecGetArray(v, &array);
    4331:   for (row = start; row < end; ++row) {
    4332:     PetscInt          ncols, col;
    4333:     const PetscInt    *cols;
    4334:     const PetscScalar *vals;

    4336:     array[row - start] = 0.0;

    4338:     MatGetRow(mat, row, &ncols, &cols, &vals);
    4339:     for (col = 0; col < ncols; col++) {
    4340:       array[row - start] += vals[col];
    4341:     }
    4342:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
    4343:   }
    4344:   VecRestoreArray(v, &array);
    4345:   PetscObjectStateIncrease((PetscObject) v);
    4346:   return(0);
    4347: }

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

    4354:    Collective on Mat

    4356:    Input Parameter:
    4357: +  mat - the matrix to transpose
    4358: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    4360:    Output Parameters:
    4361: .  B - the transpose

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

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

    4368:    Level: intermediate

    4370:    Concepts: matrices^transposing

    4372: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
    4373: @*/
    4374: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
    4375: {

    4381:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4382:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    4383:   if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4384:   MatCheckPreallocated(mat,1);

    4386:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
    4387:   (*mat->ops->transpose)(mat,reuse,B);
    4388:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
    4389:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
    4390:   return(0);
    4391: }

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

    4399:    Collective on Mat

    4401:    Input Parameter:
    4402: +  A - the matrix to test
    4403: -  B - the matrix to test against, this can equal the first parameter

    4405:    Output Parameters:
    4406: .  flg - the result

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

    4413:    Level: intermediate

    4415:    Concepts: matrices^transposing, matrix^symmetry

    4417: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
    4418: @*/
    4419: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
    4420: {
    4421:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

    4427:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
    4428:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
    4429:   *flg = PETSC_FALSE;
    4430:   if (f && g) {
    4431:     if (f == g) {
    4432:       (*f)(A,B,tol,flg);
    4433:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
    4434:   } else {
    4435:     MatType mattype;
    4436:     if (!f) {
    4437:       MatGetType(A,&mattype);
    4438:     } else {
    4439:       MatGetType(B,&mattype);
    4440:     }
    4441:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
    4442:   }
    4443:   return(0);
    4444: }

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

    4451:    Collective on Mat

    4453:    Input Parameter:
    4454: +  mat - the matrix to transpose and complex conjugate
    4455: -  reuse - store the transpose matrix in the provided B

    4457:    Output Parameters:
    4458: .  B - the Hermitian

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

    4463:    Level: intermediate

    4465:    Concepts: matrices^transposing, complex conjugatex

    4467: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
    4468: @*/
    4469: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
    4470: {

    4474:   MatTranspose(mat,reuse,B);
    4475: #if defined(PETSC_USE_COMPLEX)
    4476:   MatConjugate(*B);
    4477: #endif
    4478:   return(0);
    4479: }

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

    4486:    Collective on Mat

    4488:    Input Parameter:
    4489: +  A - the matrix to test
    4490: -  B - the matrix to test against, this can equal the first parameter

    4492:    Output Parameters:
    4493: .  flg - the result

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

    4500:    Level: intermediate

    4502:    Concepts: matrices^transposing, matrix^symmetry

    4504: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
    4505: @*/
    4506: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
    4507: {
    4508:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

    4514:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
    4515:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
    4516:   if (f && g) {
    4517:     if (f==g) {
    4518:       (*f)(A,B,tol,flg);
    4519:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
    4520:   }
    4521:   return(0);
    4522: }

    4526: /*@
    4527:    MatPermute - Creates a new matrix with rows and columns permuted from the
    4528:    original.

    4530:    Collective on Mat

    4532:    Input Parameters:
    4533: +  mat - the matrix to permute
    4534: .  row - row permutation, each processor supplies only the permutation for its rows
    4535: -  col - column permutation, each processor supplies only the permutation for its columns

    4537:    Output Parameters:
    4538: .  B - the permuted matrix

    4540:    Level: advanced

    4542:    Note:
    4543:    The index sets map from row/col of permuted matrix to row/col of original matrix.
    4544:    The index sets should be on the same communicator as Mat and have the same local sizes.

    4546:    Concepts: matrices^permuting

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

    4550: @*/
    4551: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
    4552: {

    4561:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4562:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    4563:   if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
    4564:   MatCheckPreallocated(mat,1);

    4566:   (*mat->ops->permute)(mat,row,col,B);
    4567:   PetscObjectStateIncrease((PetscObject)*B);
    4568:   return(0);
    4569: }

    4573: /*@
    4574:    MatEqual - Compares two matrices.

    4576:    Collective on Mat

    4578:    Input Parameters:
    4579: +  A - the first matrix
    4580: -  B - the second matrix

    4582:    Output Parameter:
    4583: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

    4585:    Level: intermediate

    4587:    Concepts: matrices^equality between
    4588: @*/
    4589: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
    4590: {

    4600:   MatCheckPreallocated(B,2);
    4601:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4602:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4603:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),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);
    4604:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
    4605:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
    4606:   if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
    4607:   MatCheckPreallocated(A,1);

    4609:   (*A->ops->equal)(A,B,flg);
    4610:   return(0);
    4611: }

    4615: /*@
    4616:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
    4617:    matrices that are stored as vectors.  Either of the two scaling
    4618:    matrices can be NULL.

    4620:    Collective on Mat

    4622:    Input Parameters:
    4623: +  mat - the matrix to be scaled
    4624: .  l - the left scaling vector (or NULL)
    4625: -  r - the right scaling vector (or NULL)

    4627:    Notes:
    4628:    MatDiagonalScale() computes A = LAR, where
    4629:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
    4630:    The L scales the rows of the matrix, the R scales the columns of the matrix.

    4632:    Level: intermediate

    4634:    Concepts: matrices^diagonal scaling
    4635:    Concepts: diagonal scaling of matrices

    4637: .seealso: MatScale()
    4638: @*/
    4639: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
    4640: {

    4646:   if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4649:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4650:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    4651:   MatCheckPreallocated(mat,1);

    4653:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
    4654:   (*mat->ops->diagonalscale)(mat,l,r);
    4655:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
    4656:   PetscObjectStateIncrease((PetscObject)mat);
    4657: #if defined(PETSC_HAVE_CUSP)
    4658:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    4659:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    4660:   }
    4661: #endif
    4662:   return(0);
    4663: }

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

    4670:     Logically Collective on Mat

    4672:     Input Parameters:
    4673: +   mat - the matrix to be scaled
    4674: -   a  - the scaling value

    4676:     Output Parameter:
    4677: .   mat - the scaled matrix

    4679:     Level: intermediate

    4681:     Concepts: matrices^scaling all entries

    4683: .seealso: MatDiagonalScale()
    4684: @*/
    4685: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
    4686: {

    4692:   if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4693:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4694:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    4696:   MatCheckPreallocated(mat,1);

    4698:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
    4699:   if (a != (PetscScalar)1.0) {
    4700:     (*mat->ops->scale)(mat,a);
    4701:     PetscObjectStateIncrease((PetscObject)mat);
    4702:   }
    4703:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
    4704: #if defined(PETSC_HAVE_CUSP)
    4705:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    4706:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    4707:   }
    4708: #endif
    4709:   return(0);
    4710: }

    4714: /*@
    4715:    MatNorm - Calculates various norms of a matrix.

    4717:    Collective on Mat

    4719:    Input Parameters:
    4720: +  mat - the matrix
    4721: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

    4723:    Output Parameters:
    4724: .  nrm - the resulting norm

    4726:    Level: intermediate

    4728:    Concepts: matrices^norm
    4729:    Concepts: norm^of matrix
    4730: @*/
    4731: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
    4732: {

    4740:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4741:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    4742:   if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    4743:   MatCheckPreallocated(mat,1);

    4745:   (*mat->ops->norm)(mat,type,nrm);
    4746:   return(0);
    4747: }

    4749: /*
    4750:      This variable is used to prevent counting of MatAssemblyBegin() that
    4751:    are called from within a MatAssemblyEnd().
    4752: */
    4753: static PetscInt MatAssemblyEnd_InUse = 0;
    4756: /*@
    4757:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
    4758:    be called after completing all calls to MatSetValues().

    4760:    Collective on Mat

    4762:    Input Parameters:
    4763: +  mat - the matrix
    4764: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

    4766:    Notes:
    4767:    MatSetValues() generally caches the values.  The matrix is ready to
    4768:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
    4769:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
    4770:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
    4771:    using the matrix.

    4773:    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
    4774:    same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is
    4775:    a global collective operation requring all processes that share the matrix.

    4777:    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
    4778:    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
    4779:    before MAT_FINAL_ASSEMBLY so the space is not compressed out.

    4781:    Level: beginner

    4783:    Concepts: matrices^assembling

    4785: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
    4786: @*/
    4787: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
    4788: {

    4794:   MatCheckPreallocated(mat,1);
    4795:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
    4796:   if (mat->assembled) {
    4797:     mat->was_assembled = PETSC_TRUE;
    4798:     mat->assembled     = PETSC_FALSE;
    4799:   }
    4800:   if (!MatAssemblyEnd_InUse) {
    4801:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
    4802:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
    4803:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
    4804:   } else if (mat->ops->assemblybegin) {
    4805:     (*mat->ops->assemblybegin)(mat,type);
    4806:   }
    4807:   return(0);
    4808: }

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

    4816:    Not Collective

    4818:    Input Parameter:
    4819: .  mat - the matrix

    4821:    Output Parameter:
    4822: .  assembled - PETSC_TRUE or PETSC_FALSE

    4824:    Level: advanced

    4826:    Concepts: matrices^assembled?

    4828: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
    4829: @*/
    4830: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
    4831: {
    4836:   *assembled = mat->assembled;
    4837:   return(0);
    4838: }

    4842: /*
    4843:   MatViewFromOptions - Processes command line options to determine if/how a matrix is to be viewed. Called from higher level packages.

    4845:   Collective on Vec

    4847:   Input Parameters:
    4848: + mat   - the matrix
    4849: . prefix - prefix to use for viewing, or NULL to use prefix of 'rnd'
    4850: - optionname - option to activate viewing

    4852:   Level: intermediate

    4854: .keywords: Mat, view, options, database
    4855: .seealso: MatViewFromOptions()
    4856: */
    4857: PetscErrorCode MatViewFromOptions(Mat mat,const char prefix[],const char optionname[])
    4858: {
    4859:   PetscErrorCode    ierr;
    4860:   PetscViewer       viewer;
    4861:   PetscBool         flg;
    4862:   static PetscBool  incall = PETSC_FALSE;
    4863:   PetscViewerFormat format;

    4866:   if (incall) return(0);
    4867:   incall = PETSC_TRUE;
    4868:   if (prefix) {
    4869:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)mat),prefix,optionname,&viewer,&format,&flg);
    4870:   } else {
    4871:     PetscOptionsGetViewer(PetscObjectComm((PetscObject)mat),((PetscObject)mat)->prefix,optionname,&viewer,&format,&flg);
    4872:   }
    4873:   if (flg) {
    4874:     PetscViewerPushFormat(viewer,format);
    4875:     MatView(mat,viewer);
    4876:     PetscViewerPopFormat(viewer);
    4877:     PetscViewerDestroy(&viewer);
    4878:   }
    4879:   incall = PETSC_FALSE;
    4880:   return(0);
    4881: }

    4885: /*@
    4886:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
    4887:    be called after MatAssemblyBegin().

    4889:    Collective on Mat

    4891:    Input Parameters:
    4892: +  mat - the matrix
    4893: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

    4895:    Options Database Keys:
    4896: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
    4897: .  -mat_view ::ascii_info_detail - Prints more detailed info
    4898: .  -mat_view - Prints matrix in ASCII format
    4899: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
    4900: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
    4901: .  -display <name> - Sets display name (default is host)
    4902: .  -draw_pause <sec> - Sets number of seconds to pause after display
    4903: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
    4904: .  -viewer_socket_machine <machine>
    4905: .  -viewer_socket_port <port>
    4906: .  -mat_view binary - save matrix to file in binary format
    4907: -  -viewer_binary_filename <name>

    4909:    Notes:
    4910:    MatSetValues() generally caches the values.  The matrix is ready to
    4911:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
    4912:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
    4913:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
    4914:    using the matrix.

    4916:    Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
    4917:    out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
    4918:    before MAT_FINAL_ASSEMBLY so the space is not compressed out.

    4920:    Level: beginner

    4922: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
    4923: @*/
    4924: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
    4925: {
    4926:   PetscErrorCode  ierr;
    4927:   static PetscInt inassm = 0;
    4928:   PetscBool       flg    = PETSC_FALSE;

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

    4946:   /* Flush assembly is not a true assembly */
    4947:   if (type != MAT_FLUSH_ASSEMBLY) {
    4948:     mat->assembled = PETSC_TRUE; mat->num_ass++;
    4949:   }
    4950:   mat->insertmode = NOT_SET_VALUES;
    4951:   MatAssemblyEnd_InUse--;
    4952:   PetscObjectStateIncrease((PetscObject)mat);
    4953:   if (!mat->symmetric_eternal) {
    4954:     mat->symmetric_set              = PETSC_FALSE;
    4955:     mat->hermitian_set              = PETSC_FALSE;
    4956:     mat->structurally_symmetric_set = PETSC_FALSE;
    4957:   }
    4958: #if defined(PETSC_HAVE_CUSP)
    4959:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    4960:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    4961:   }
    4962: #endif
    4963:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
    4964:     if (mat->viewonassembly) {
    4965:       PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
    4966:       MatView(mat,mat->viewonassembly);
    4967:       PetscViewerPopFormat(mat->viewonassembly);
    4968:     }

    4970:     if (mat->checksymmetryonassembly) {
    4971:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
    4972:       if (flg) {
    4973:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %G)\n",mat->checksymmetrytol);
    4974:       } else {
    4975:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %G)\n",mat->checksymmetrytol);
    4976:       }
    4977:     }
    4978:     if (mat->nullsp && mat->checknullspaceonassembly) {
    4979:       MatNullSpaceTest(mat->nullsp,mat,NULL);
    4980:     }
    4981:   }
    4982:   inassm--;
    4983:   return(0);
    4984: }

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

    4995:    Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption

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

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

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

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

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

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

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

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

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

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

    5062:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
    5063:    other processors should be dropped, rather than stashed.
    5064:    This is useful if you know that the "owning" processor is also
    5065:    always generating the correct matrix entries, so that PETSc need
    5066:    not transfer duplicate entries generated on another processor.

    5068:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
    5069:    searches during matrix assembly. When this flag is set, the hash table
    5070:    is created during the first Matrix Assembly. This hash table is
    5071:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
    5072:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
    5073:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
    5074:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

    5093:    Level: intermediate

    5095:    Concepts: matrices^setting options

    5097: .seealso:  MatOption, Mat

    5099: @*/
    5100: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool flg)
    5101: {

    5110:   if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
    5111:   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()");

    5113:   switch (op) {
    5114:   case MAT_NO_OFF_PROC_ENTRIES:
    5115:     mat->nooffprocentries = flg;
    5116:     return(0);
    5117:     break;
    5118:   case MAT_NO_OFF_PROC_ZERO_ROWS:
    5119:     mat->nooffproczerorows = flg;
    5120:     return(0);
    5121:     break;
    5122:   case MAT_SPD:
    5123:     mat->spd_set = PETSC_TRUE;
    5124:     mat->spd     = flg;
    5125:     if (flg) {
    5126:       mat->symmetric                  = PETSC_TRUE;
    5127:       mat->structurally_symmetric     = PETSC_TRUE;
    5128:       mat->symmetric_set              = PETSC_TRUE;
    5129:       mat->structurally_symmetric_set = PETSC_TRUE;
    5130:     }
    5131:     break;
    5132:   case MAT_SYMMETRIC:
    5133:     mat->symmetric = flg;
    5134:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
    5135:     mat->symmetric_set              = PETSC_TRUE;
    5136:     mat->structurally_symmetric_set = flg;
    5137:     break;
    5138:   case MAT_HERMITIAN:
    5139:     mat->hermitian = flg;
    5140:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
    5141:     mat->hermitian_set              = PETSC_TRUE;
    5142:     mat->structurally_symmetric_set = flg;
    5143:     break;
    5144:   case MAT_STRUCTURALLY_SYMMETRIC:
    5145:     mat->structurally_symmetric     = flg;
    5146:     mat->structurally_symmetric_set = PETSC_TRUE;
    5147:     break;
    5148:   case MAT_SYMMETRY_ETERNAL:
    5149:     mat->symmetric_eternal = flg;
    5150:     break;
    5151:   default:
    5152:     break;
    5153:   }
    5154:   if (mat->ops->setoption) {
    5155:     (*mat->ops->setoption)(mat,op,flg);
    5156:   }
    5157:   return(0);
    5158: }

    5162: /*@
    5163:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
    5164:    this routine retains the old nonzero structure.

    5166:    Logically Collective on Mat

    5168:    Input Parameters:
    5169: .  mat - the matrix

    5171:    Level: intermediate

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

    5176:    Concepts: matrices^zeroing

    5178: .seealso: MatZeroRows()
    5179: @*/
    5180: PetscErrorCode  MatZeroEntries(Mat mat)
    5181: {

    5187:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    5188:   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");
    5189:   if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    5190:   MatCheckPreallocated(mat,1);

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

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

    5210:    Collective on Mat

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

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

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

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

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

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

    5237:    Level: intermediate

    5239:    Concepts: matrices^zeroing rows

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

    5251:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    5252:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    5253:   if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    5254:   MatCheckPreallocated(mat,1);

    5256:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
    5257:   if (mat->viewonassembly) {
    5258:     PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
    5259:     MatView(mat,mat->viewonassembly);
    5260:     PetscViewerPopFormat(mat->viewonassembly);
    5261:   }
    5262:   PetscObjectStateIncrease((PetscObject)mat);
    5263: #if defined(PETSC_HAVE_CUSP)
    5264:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5265:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5266:   }
    5267: #endif
    5268:   return(0);
    5269: }

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

    5277:    Collective on Mat

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

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

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

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

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

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

    5303:    Level: intermediate

    5305:    Concepts: matrices^zeroing rows

    5307: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
    5308: @*/
    5309: PetscErrorCode  MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    5310: {
    5312:   PetscInt       numRows;
    5313:   const PetscInt *rows;

    5320:   ISGetLocalSize(is,&numRows);
    5321:   ISGetIndices(is,&rows);
    5322:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
    5323:   ISRestoreIndices(is,&rows);
    5324:   return(0);
    5325: }

    5329: /*@C
    5330:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
    5331:    of a set of rows of a matrix.

    5333:    Collective on Mat

    5335:    Input Parameters:
    5336: +  mat - the matrix
    5337: .  numRows - the number of rows to remove
    5338: .  rows - the global row indices
    5339: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
    5340: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
    5341: -  b - optional vector of right hand side, that will be adjusted by provided solution

    5343:    Notes:
    5344:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5345:    but does not release memory.  For the dense and block diagonal
    5346:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5367:    Level: intermediate

    5369:    Concepts: matrices^zeroing rows

    5371: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5372: @*/
    5373: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
    5374: {

    5381:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    5382:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    5383:   if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    5384:   MatCheckPreallocated(mat,1);

    5386:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
    5387:   if (mat->viewonassembly) {
    5388:     PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
    5389:     MatView(mat,mat->viewonassembly);
    5390:     PetscViewerPopFormat(mat->viewonassembly);
    5391:   }
    5392:   PetscObjectStateIncrease((PetscObject)mat);
    5393: #if defined(PETSC_HAVE_CUSP)
    5394:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5395:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5396:   }
    5397: #endif
    5398:   return(0);
    5399: }

    5403: /*@C
    5404:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
    5405:    of a set of rows of a matrix.

    5407:    Collective on Mat

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

    5416:    Notes:
    5417:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5418:    but does not release memory.  For the dense and block diagonal
    5419:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5440:    Level: intermediate

    5442:    Concepts: matrices^zeroing rows

    5444: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5445: @*/
    5446: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    5447: {
    5448:   PetscInt       numRows;
    5449:   const PetscInt *rows;

    5456:   ISGetLocalSize(is,&numRows);
    5457:   ISGetIndices(is,&rows);
    5458:   MatZeroRows(mat,numRows,rows,diag,x,b);
    5459:   ISRestoreIndices(is,&rows);
    5460:   return(0);
    5461: }

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

    5469:    Collective on Mat

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

    5479:    Notes:
    5480:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5481:    but does not release memory.  For the dense and block diagonal
    5482:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5502:    In Fortran idxm and idxn should be declared as
    5503: $     MatStencil idxm(4,m)
    5504:    and the values inserted using
    5505: $    idxm(MatStencil_i,1) = i
    5506: $    idxm(MatStencil_j,1) = j
    5507: $    idxm(MatStencil_k,1) = k
    5508: $    idxm(MatStencil_c,1) = c
    5509:    etc

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

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

    5519:    Level: intermediate

    5521:    Concepts: matrices^zeroing rows

    5523: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5524: @*/
    5525: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
    5526: {
    5527:   PetscInt       dim     = mat->stencil.dim;
    5528:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
    5529:   PetscInt       *dims   = mat->stencil.dims+1;
    5530:   PetscInt       *starts = mat->stencil.starts;
    5531:   PetscInt       *dxm    = (PetscInt*) rows;
    5532:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;

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

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

    5571:    Collective on Mat

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

    5581:    Notes:
    5582:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5583:    but does not release memory.  For the dense and block diagonal
    5584:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5604:    In Fortran idxm and idxn should be declared as
    5605: $     MatStencil idxm(4,m)
    5606:    and the values inserted using
    5607: $    idxm(MatStencil_i,1) = i
    5608: $    idxm(MatStencil_j,1) = j
    5609: $    idxm(MatStencil_k,1) = k
    5610: $    idxm(MatStencil_c,1) = c
    5611:    etc

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

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

    5621:    Level: intermediate

    5623:    Concepts: matrices^zeroing rows

    5625: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5626: @*/
    5627: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
    5628: {
    5629:   PetscInt       dim     = mat->stencil.dim;
    5630:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
    5631:   PetscInt       *dims   = mat->stencil.dims+1;
    5632:   PetscInt       *starts = mat->stencil.starts;
    5633:   PetscInt       *dxm    = (PetscInt*) rows;
    5634:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;

    5642:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
    5643:   for (i = 0; i < numRows; ++i) {
    5644:     /* Skip unused dimensions (they are ordered k, j, i, c) */
    5645:     for (j = 0; j < 3-sdim; ++j) dxm++;
    5646:     /* Local index in X dir */
    5647:     tmp = *dxm++ - starts[0];
    5648:     /* Loop over remaining dimensions */
    5649:     for (j = 0; j < dim-1; ++j) {
    5650:       /* If nonlocal, set index to be negative */
    5651:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
    5652:       /* Update local index */
    5653:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
    5654:     }
    5655:     /* Skip component slot if necessary */
    5656:     if (mat->stencil.noc) dxm++;
    5657:     /* Local row number */
    5658:     if (tmp >= 0) {
    5659:       jdxm[numNewRows++] = tmp;
    5660:     }
    5661:   }
    5662:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
    5663:   PetscFree(jdxm);
    5664:   return(0);
    5665: }

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

    5673:    Collective on Mat

    5675:    Input Parameters:
    5676: +  mat - the matrix
    5677: .  numRows - the number of rows to remove
    5678: .  rows - the global row indices
    5679: .  diag - value put in all diagonals of eliminated rows
    5680: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
    5681: -  b - optional vector of right hand side, that will be adjusted by provided solution

    5683:    Notes:
    5684:    Before calling MatZeroRowsLocal(), the user must first set the
    5685:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

    5687:    For the AIJ matrix formats this removes the old nonzero structure,
    5688:    but does not release memory.  For the dense and block diagonal
    5689:    formats this does not alter the nonzero structure.

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

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

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

    5702:    Level: intermediate

    5704:    Concepts: matrices^zeroing

    5706: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    5707: @*/
    5708: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
    5709: {
    5711:   PetscMPIInt    size;

    5717:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    5718:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    5719:   MatCheckPreallocated(mat,1);

    5721:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
    5722:   if (mat->ops->zerorowslocal) {
    5723:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
    5724:   } else if (size == 1) {
    5725:     (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
    5726:   } else {
    5727:     IS             is, newis;
    5728:     const PetscInt *newRows;

    5730:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
    5731:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
    5732:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
    5733:     ISGetIndices(newis,&newRows);
    5734:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
    5735:     ISRestoreIndices(newis,&newRows);
    5736:     ISDestroy(&newis);
    5737:     ISDestroy(&is);
    5738:   }
    5739:   PetscObjectStateIncrease((PetscObject)mat);
    5740: #if defined(PETSC_HAVE_CUSP)
    5741:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5742:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5743:   }
    5744: #endif
    5745:   return(0);
    5746: }

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

    5754:    Collective on Mat

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

    5763:    Notes:
    5764:    Before calling MatZeroRowsLocalIS(), the user must first set the
    5765:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

    5767:    For the AIJ matrix formats this removes the old nonzero structure,
    5768:    but does not release memory.  For the dense and block diagonal
    5769:    formats this does not alter the nonzero structure.

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

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

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

    5782:    Level: intermediate

    5784:    Concepts: matrices^zeroing

    5786: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    5787: @*/
    5788: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    5789: {
    5791:   PetscInt       numRows;
    5792:   const PetscInt *rows;

    5798:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    5799:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    5800:   MatCheckPreallocated(mat,1);

    5802:   ISGetLocalSize(is,&numRows);
    5803:   ISGetIndices(is,&rows);
    5804:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
    5805:   ISRestoreIndices(is,&rows);
    5806:   return(0);
    5807: }

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

    5815:    Collective on Mat

    5817:    Input Parameters:
    5818: +  mat - the matrix
    5819: .  numRows - the number of rows to remove
    5820: .  rows - the global row indices
    5821: .  diag - value put in all diagonals of eliminated rows
    5822: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
    5823: -  b - optional vector of right hand side, that will be adjusted by provided solution

    5825:    Notes:
    5826:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
    5827:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

    5833:    Level: intermediate

    5835:    Concepts: matrices^zeroing

    5837: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    5838: @*/
    5839: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
    5840: {
    5842:   PetscMPIInt    size;

    5848:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    5849:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    5850:   MatCheckPreallocated(mat,1);

    5852:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
    5853:   if (size == 1) {
    5854:     (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
    5855:   } else {
    5856:     IS             is, newis;
    5857:     const PetscInt *newRows;

    5859:     if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
    5860:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
    5861:     ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
    5862:     ISGetIndices(newis,&newRows);
    5863:     (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
    5864:     ISRestoreIndices(newis,&newRows);
    5865:     ISDestroy(&newis);
    5866:     ISDestroy(&is);
    5867:   }
    5868:   PetscObjectStateIncrease((PetscObject)mat);
    5869: #if defined(PETSC_HAVE_CUSP)
    5870:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5871:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5872:   }
    5873: #endif
    5874:   return(0);
    5875: }

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

    5883:    Collective on Mat

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

    5892:    Notes:
    5893:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
    5894:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

    5900:    Level: intermediate

    5902:    Concepts: matrices^zeroing

    5904: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    5905: @*/
    5906: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    5907: {
    5909:   PetscInt       numRows;
    5910:   const PetscInt *rows;

    5916:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    5917:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    5918:   MatCheckPreallocated(mat,1);

    5920:   ISGetLocalSize(is,&numRows);
    5921:   ISGetIndices(is,&rows);
    5922:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
    5923:   ISRestoreIndices(is,&rows);
    5924:   return(0);
    5925: }

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

    5932:    Not Collective

    5934:    Input Parameter:
    5935: .  mat - the matrix

    5937:    Output Parameters:
    5938: +  m - the number of global rows
    5939: -  n - the number of global columns

    5941:    Note: both output parameters can be NULL on input.

    5943:    Level: beginner

    5945:    Concepts: matrices^size

    5947: .seealso: MatGetLocalSize()
    5948: @*/
    5949: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
    5950: {
    5953:   if (m) *m = mat->rmap->N;
    5954:   if (n) *n = mat->cmap->N;
    5955:   return(0);
    5956: }

    5960: /*@
    5961:    MatGetLocalSize - Returns the number of rows and columns in a matrix
    5962:    stored locally.  This information may be implementation dependent, so
    5963:    use with care.

    5965:    Not Collective

    5967:    Input Parameters:
    5968: .  mat - the matrix

    5970:    Output Parameters:
    5971: +  m - the number of local rows
    5972: -  n - the number of local columns

    5974:    Note: both output parameters can be NULL on input.

    5976:    Level: beginner

    5978:    Concepts: matrices^local size

    5980: .seealso: MatGetSize()
    5981: @*/
    5982: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
    5983: {
    5988:   if (m) *m = mat->rmap->n;
    5989:   if (n) *n = mat->cmap->n;
    5990:   return(0);
    5991: }

    5995: /*@
    5996:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
    5997:    this processor. (The columns of the "diagonal block")

    5999:    Not Collective, unless matrix has not been allocated, then collective on Mat

    6001:    Input Parameters:
    6002: .  mat - the matrix

    6004:    Output Parameters:
    6005: +  m - the global index of the first local column
    6006: -  n - one more than the global index of the last local column

    6008:    Notes: both output parameters can be NULL on input.

    6010:    Level: developer

    6012:    Concepts: matrices^column ownership

    6014: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

    6016: @*/
    6017: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
    6018: {
    6024:   MatCheckPreallocated(mat,1);
    6025:   if (m) *m = mat->cmap->rstart;
    6026:   if (n) *n = mat->cmap->rend;
    6027:   return(0);
    6028: }

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

    6038:    Not Collective

    6040:    Input Parameters:
    6041: .  mat - the matrix

    6043:    Output Parameters:
    6044: +  m - the global index of the first local row
    6045: -  n - one more than the global index of the last local row

    6047:    Note: Both output parameters can be NULL on input.
    6048: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
    6049: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
    6050: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

    6052:    Level: beginner

    6054:    Concepts: matrices^row ownership

    6056: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

    6058: @*/
    6059: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
    6060: {
    6066:   MatCheckPreallocated(mat,1);
    6067:   if (m) *m = mat->rmap->rstart;
    6068:   if (n) *n = mat->rmap->rend;
    6069:   return(0);
    6070: }

    6074: /*@C
    6075:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
    6076:    each process

    6078:    Not Collective, unless matrix has not been allocated, then collective on Mat

    6080:    Input Parameters:
    6081: .  mat - the matrix

    6083:    Output Parameters:
    6084: .  ranges - start of each processors portion plus one more then the total length at the end

    6086:    Level: beginner

    6088:    Concepts: matrices^row ownership

    6090: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

    6092: @*/
    6093: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
    6094: {

    6100:   MatCheckPreallocated(mat,1);
    6101:   PetscLayoutGetRanges(mat->rmap,ranges);
    6102:   return(0);
    6103: }

    6107: /*@C
    6108:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
    6109:    this processor. (The columns of the "diagonal blocks" for each process)

    6111:    Not Collective, unless matrix has not been allocated, then collective on Mat

    6113:    Input Parameters:
    6114: .  mat - the matrix

    6116:    Output Parameters:
    6117: .  ranges - start of each processors portion plus one more then the total length at the end

    6119:    Level: beginner

    6121:    Concepts: matrices^column ownership

    6123: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

    6125: @*/
    6126: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
    6127: {

    6133:   MatCheckPreallocated(mat,1);
    6134:   PetscLayoutGetRanges(mat->cmap,ranges);
    6135:   return(0);
    6136: }

    6140: /*@C
    6141:    MatGetOwnershipIS - Get row and column ownership as index sets

    6143:    Not Collective

    6145:    Input Arguments:
    6146: .  A - matrix of type Elemental

    6148:    Output Arguments:
    6149: +  rows - rows in which this process owns elements
    6150: .  cols - columns in which this process owns elements

    6152:    Level: intermediate

    6154: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
    6155: @*/
    6156: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
    6157: {
    6158:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

    6161:   MatCheckPreallocated(A,1);
    6162:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
    6163:   if (f) {
    6164:     (*f)(A,rows,cols);
    6165:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
    6166:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
    6167:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
    6168:   }
    6169:   return(0);
    6170: }

    6174: /*@C
    6175:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
    6176:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
    6177:    to complete the factorization.

    6179:    Collective on Mat

    6181:    Input Parameters:
    6182: +  mat - the matrix
    6183: .  row - row permutation
    6184: .  column - column permutation
    6185: -  info - structure containing
    6186: $      levels - number of levels of fill.
    6187: $      expected fill - as ratio of original fill.
    6188: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
    6189:                 missing diagonal entries)

    6191:    Output Parameters:
    6192: .  fact - new matrix that has been symbolically factored

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

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

    6202:    Level: developer

    6204:   Concepts: matrices^symbolic LU factorization
    6205:   Concepts: matrices^factorization
    6206:   Concepts: LU^symbolic factorization

    6208: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
    6209:           MatGetOrdering(), MatFactorInfo

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

    6214: @*/
    6215: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
    6216: {

    6226:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
    6227:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
    6228:   if (!(fact)->ops->ilufactorsymbolic) {
    6229:     const MatSolverPackage spackage;
    6230:     MatFactorGetSolverPackage(fact,&spackage);
    6231:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
    6232:   }
    6233:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6234:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6235:   MatCheckPreallocated(mat,2);

    6237:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
    6238:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
    6239:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
    6240:   return(0);
    6241: }

    6245: /*@C
    6246:    MatICCFactorSymbolic - Performs symbolic incomplete
    6247:    Cholesky factorization for a symmetric matrix.  Use
    6248:    MatCholeskyFactorNumeric() to complete the factorization.

    6250:    Collective on Mat

    6252:    Input Parameters:
    6253: +  mat - the matrix
    6254: .  perm - row and column permutation
    6255: -  info - structure containing
    6256: $      levels - number of levels of fill.
    6257: $      expected fill - as ratio of original fill.

    6259:    Output Parameter:
    6260: .  fact - the factored matrix

    6262:    Notes:
    6263:    Most users should employ the KSP interface for linear solvers
    6264:    instead of working directly with matrix algebra routines such as this.
    6265:    See, e.g., KSPCreate().

    6267:    Level: developer

    6269:   Concepts: matrices^symbolic incomplete Cholesky factorization
    6270:   Concepts: matrices^factorization
    6271:   Concepts: Cholsky^symbolic factorization

    6273: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

    6278: @*/
    6279: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
    6280: {

    6289:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6290:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
    6291:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
    6292:   if (!(fact)->ops->iccfactorsymbolic) {
    6293:     const MatSolverPackage spackage;
    6294:     MatFactorGetSolverPackage(fact,&spackage);
    6295:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
    6296:   }
    6297:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6298:   MatCheckPreallocated(mat,2);

    6300:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
    6301:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
    6302:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
    6303:   return(0);
    6304: }

    6308: /*@C
    6309:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
    6310:    points to an array of valid matrices, they may be reused to store the new
    6311:    submatrices.

    6313:    Collective on Mat

    6315:    Input Parameters:
    6316: +  mat - the matrix
    6317: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
    6318: .  irow, icol - index sets of rows and columns to extract (must be sorted)
    6319: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    6321:    Output Parameter:
    6322: .  submat - the array of submatrices

    6324:    Notes:
    6325:    MatGetSubMatrices() can extract ONLY sequential submatrices
    6326:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
    6327:    to extract a parallel submatrix.

    6329:    Currently both row and column indices must be sorted to guarantee
    6330:    correctness with all matrix types.

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

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

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

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

    6345:    For BAIJ matrices the index sets must respect the block structure, that is if they
    6346:    request one row/column in a block, they must request all rows/columns that are in
    6347:    that block. For example, if the block size is 2 you cannot request just row 0 and
    6348:    column 0.

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

    6354:    Level: advanced

    6356:    Concepts: matrices^accessing submatrices
    6357:    Concepts: submatrices

    6359: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
    6360: @*/
    6361: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
    6362: {
    6364:   PetscInt       i;
    6365:   PetscBool      eq;

    6370:   if (n) {
    6375:   }
    6377:   if (n && scall == MAT_REUSE_MATRIX) {
    6380:   }
    6381:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    6382:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6383:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6384:   MatCheckPreallocated(mat,1);

    6386:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
    6387:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
    6388:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
    6389:   for (i=0; i<n; i++) {
    6390:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
    6391:       ISEqual(irow[i],icol[i],&eq);
    6392:       if (eq) {
    6393:         if (mat->symmetric) {
    6394:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
    6395:         } else if (mat->hermitian) {
    6396:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
    6397:         } else if (mat->structurally_symmetric) {
    6398:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
    6399:         }
    6400:       }
    6401:     }
    6402:   }
    6403:   return(0);
    6404: }

    6408: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
    6409: {
    6411:   PetscInt       i;
    6412:   PetscBool      eq;

    6417:   if (n) {
    6422:   }
    6424:   if (n && scall == MAT_REUSE_MATRIX) {
    6427:   }
    6428:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    6429:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6430:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6431:   MatCheckPreallocated(mat,1);

    6433:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
    6434:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
    6435:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
    6436:   for (i=0; i<n; i++) {
    6437:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
    6438:       ISEqual(irow[i],icol[i],&eq);
    6439:       if (eq) {
    6440:         if (mat->symmetric) {
    6441:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
    6442:         } else if (mat->hermitian) {
    6443:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
    6444:         } else if (mat->structurally_symmetric) {
    6445:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
    6446:         }
    6447:       }
    6448:     }
    6449:   }
    6450:   return(0);
    6451: }

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

    6458:    Collective on Mat

    6460:    Input Parameters:
    6461: +  n - the number of local matrices
    6462: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
    6463:                        sequence of MatGetSubMatrices())

    6465:    Level: advanced

    6467:     Notes: Frees not only the matrices, but also the array that contains the matrices
    6468:            In Fortran will not free the array.

    6470: .seealso: MatGetSubMatrices()
    6471: @*/
    6472: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
    6473: {
    6475:   PetscInt       i;

    6478:   if (!*mat) return(0);
    6479:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
    6481:   for (i=0; i<n; i++) {
    6482:     MatDestroy(&(*mat)[i]);
    6483:   }
    6484:   /* memory is allocated even if n = 0 */
    6485:   PetscFree(*mat);
    6486:   *mat = NULL;
    6487:   return(0);
    6488: }

    6492: /*@C
    6493:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

    6495:    Collective on Mat

    6497:    Input Parameters:
    6498: .  mat - the matrix

    6500:    Output Parameter:
    6501: .  matstruct - the sequential matrix with the nonzero structure of mat

    6503:   Level: intermediate

    6505: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
    6506: @*/
    6507: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
    6508: {

    6516:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6517:   MatCheckPreallocated(mat,1);

    6519:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
    6520:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
    6521:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
    6522:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
    6523:   return(0);
    6524: }

    6528: /*@C
    6529:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

    6531:    Collective on Mat

    6533:    Input Parameters:
    6534: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
    6535:                        sequence of MatGetSequentialNonzeroStructure())

    6537:    Level: advanced

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

    6541: .seealso: MatGetSeqNonzeroStructure()
    6542: @*/
    6543: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
    6544: {

    6549:   MatDestroy(mat);
    6550:   return(0);
    6551: }

    6555: /*@
    6556:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
    6557:    replaces the index sets by larger ones that represent submatrices with
    6558:    additional overlap.

    6560:    Collective on Mat

    6562:    Input Parameters:
    6563: +  mat - the matrix
    6564: .  n   - the number of index sets
    6565: .  is  - the array of index sets (these index sets will changed during the call)
    6566: -  ov  - the additional overlap requested

    6568:    Level: developer

    6570:    Concepts: overlap
    6571:    Concepts: ASM^computing overlap

    6573: .seealso: MatGetSubMatrices()
    6574: @*/
    6575: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
    6576: {

    6582:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
    6583:   if (n) {
    6586:   }
    6587:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6588:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6589:   MatCheckPreallocated(mat,1);

    6591:   if (!ov) return(0);
    6592:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    6593:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
    6594:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
    6595:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
    6596:   return(0);
    6597: }

    6601: /*@
    6602:    MatGetBlockSize - Returns the matrix block size; useful especially for the
    6603:    block row and block diagonal formats.

    6605:    Not Collective

    6607:    Input Parameter:
    6608: .  mat - the matrix

    6610:    Output Parameter:
    6611: .  bs - block size

    6613:    Notes:
    6614:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

    6616:    Level: intermediate

    6618:    Concepts: matrices^block size

    6620: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
    6621: @*/
    6622: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
    6623: {
    6628:   MatCheckPreallocated(mat,1);
    6629:   *bs = mat->rmap->bs;
    6630:   return(0);
    6631: }

    6635: /*@
    6636:    MatGetBlockSizes - Returns the matrix block row and column sizes;
    6637:    useful especially for the block row and block diagonal formats.

    6639:    Not Collective

    6641:    Input Parameter:
    6642: .  mat - the matrix

    6644:    Output Parameter:
    6645: .  rbs - row block size
    6646: .  cbs - coumn block size

    6648:    Notes:
    6649:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

    6651:    Level: intermediate

    6653:    Concepts: matrices^block size

    6655: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
    6656: @*/
    6657: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
    6658: {
    6664:   MatCheckPreallocated(mat,1);
    6665:   if (rbs) *rbs = mat->rmap->bs;
    6666:   if (cbs) *cbs = mat->cmap->bs;
    6667:   return(0);
    6668: }

    6672: /*@
    6673:    MatSetBlockSize - Sets the matrix block size.

    6675:    Logically Collective on Mat

    6677:    Input Parameters:
    6678: +  mat - the matrix
    6679: -  bs - block size

    6681:    Notes:
    6682:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

    6684:    Level: intermediate

    6686:    Concepts: matrices^block size

    6688: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
    6689: @*/
    6690: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
    6691: {

    6697:   PetscLayoutSetBlockSize(mat->rmap,bs);
    6698:   PetscLayoutSetBlockSize(mat->cmap,bs);
    6699:   return(0);
    6700: }

    6704: /*@
    6705:    MatSetBlockSizes - Sets the matrix block row and column sizes.

    6707:    Logically Collective on Mat

    6709:    Input Parameters:
    6710: +  mat - the matrix
    6711: -  rbs - row block size
    6712: -  cbs - column block size

    6714:    Notes:
    6715:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

    6717:    Level: intermediate

    6719:    Concepts: matrices^block size

    6721: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
    6722: @*/
    6723: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
    6724: {

    6730:   PetscLayoutSetBlockSize(mat->rmap,rbs);
    6731:   PetscLayoutSetBlockSize(mat->cmap,cbs);
    6732:   return(0);
    6733: }

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

    6740:    Collective on Mat

    6742:     Input Parameters:
    6743: +   mat - the matrix
    6744: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
    6745: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
    6746: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
    6747:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    6748:                  always used.

    6750:     Output Parameters:
    6751: +   n - number of rows in the (possibly compressed) matrix
    6752: .   ia - the row pointers [of length n+1]
    6753: .   ja - the column indices
    6754: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
    6755:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

    6757:     Level: developer

    6759:     Notes: You CANNOT change any of the ia[] or ja[] values.

    6761:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

    6763:     Fortran Node

    6765:            In Fortran use
    6766: $           PetscInt ia(1), ja(1)
    6767: $           PetscOffset iia, jja
    6768: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
    6769: $
    6770: $          or
    6771: $
    6772: $           PetscScalar, pointer :: xx_v(:)
    6773: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)

    6776:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

    6778: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
    6779: @*/
    6780: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    6781: {

    6791:   MatCheckPreallocated(mat,1);
    6792:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
    6793:   else {
    6794:     *done = PETSC_TRUE;
    6795:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
    6796:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    6797:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
    6798:   }
    6799:   return(0);
    6800: }

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

    6807:     Collective on Mat

    6809:     Input Parameters:
    6810: +   mat - the matrix
    6811: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
    6812: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
    6813:                 symmetrized
    6814: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
    6815:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    6816:                  always used.

    6818:     Output Parameters:
    6819: +   n - number of columns in the (possibly compressed) matrix
    6820: .   ia - the column pointers
    6821: .   ja - the row indices
    6822: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

    6824:     Level: developer

    6826: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
    6827: @*/
    6828: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    6829: {

    6839:   MatCheckPreallocated(mat,1);
    6840:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
    6841:   else {
    6842:     *done = PETSC_TRUE;
    6843:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    6844:   }
    6845:   return(0);
    6846: }

    6850: /*@C
    6851:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
    6852:     MatGetRowIJ().

    6854:     Collective on Mat

    6856:     Input Parameters:
    6857: +   mat - the matrix
    6858: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
    6859: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
    6860:                 symmetrized
    6861: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
    6862:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    6863:                  always used.

    6865:     Output Parameters:
    6866: +   n - size of (possibly compressed) matrix
    6867: .   ia - the row pointers
    6868: .   ja - the column indices
    6869: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

    6871:     Level: developer

    6873: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
    6874: @*/
    6875: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    6876: {

    6885:   MatCheckPreallocated(mat,1);

    6887:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
    6888:   else {
    6889:     *done = PETSC_TRUE;
    6890:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    6891:     if (n)  *n = 0;
    6892:     if (ia) *ia = NULL;
    6893:     if (ja) *ja = NULL;
    6894:   }
    6895:   return(0);
    6896: }

    6900: /*@C
    6901:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
    6902:     MatGetColumnIJ().

    6904:     Collective on Mat

    6906:     Input Parameters:
    6907: +   mat - the matrix
    6908: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
    6909: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
    6910:                 symmetrized
    6911: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
    6912:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    6913:                  always used.

    6915:     Output Parameters:
    6916: +   n - size of (possibly compressed) matrix
    6917: .   ia - the column pointers
    6918: .   ja - the row indices
    6919: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

    6921:     Level: developer

    6923: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
    6924: @*/
    6925: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    6926: {

    6935:   MatCheckPreallocated(mat,1);

    6937:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
    6938:   else {
    6939:     *done = PETSC_TRUE;
    6940:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    6941:     if (n)  *n = 0;
    6942:     if (ia) *ia = NULL;
    6943:     if (ja) *ja = NULL;
    6944:   }
    6945:   return(0);
    6946: }

    6950: /*@C
    6951:     MatColoringPatch -Used inside matrix coloring routines that
    6952:     use MatGetRowIJ() and/or MatGetColumnIJ().

    6954:     Collective on Mat

    6956:     Input Parameters:
    6957: +   mat - the matrix
    6958: .   ncolors - max color value
    6959: .   n   - number of entries in colorarray
    6960: -   colorarray - array indicating color for each column

    6962:     Output Parameters:
    6963: .   iscoloring - coloring generated using colorarray information

    6965:     Level: developer

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

    6969: @*/
    6970: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
    6971: {

    6979:   MatCheckPreallocated(mat,1);

    6981:   if (!mat->ops->coloringpatch) {
    6982:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
    6983:   } else {
    6984:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
    6985:   }
    6986:   return(0);
    6987: }

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

    6995:    Logically Collective on Mat

    6997:    Input Parameter:
    6998: .  mat - the factored matrix to be reset

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

    7007:    Note that one can specify in-place ILU(0) factorization by calling
    7008: .vb
    7009:      PCType(pc,PCILU);
    7010:      PCFactorSeUseInPlace(pc);
    7011: .ve
    7012:    or by using the options -pc_type ilu -pc_factor_in_place

    7014:    In-place factorization ILU(0) can also be used as a local
    7015:    solver for the blocks within the block Jacobi or additive Schwarz
    7016:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion
    7017:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
    7018:    local solver options.

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

    7024:    Level: developer

    7026: .seealso: PCFactorSetUseInPlace()

    7028:    Concepts: matrices^unfactored

    7030: @*/
    7031: PetscErrorCode  MatSetUnfactored(Mat mat)
    7032: {

    7038:   MatCheckPreallocated(mat,1);
    7039:   mat->factortype = MAT_FACTOR_NONE;
    7040:   if (!mat->ops->setunfactored) return(0);
    7041:   (*mat->ops->setunfactored)(mat);
    7042:   return(0);
    7043: }

    7045: /*MC
    7046:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

    7048:     Synopsis:
    7049:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

    7051:     Not collective

    7053:     Input Parameter:
    7054: .   x - matrix

    7056:     Output Parameters:
    7057: +   xx_v - the Fortran90 pointer to the array
    7058: -   ierr - error code

    7060:     Example of Usage:
    7061: .vb
    7062:       PetscScalar, pointer xx_v(:,:)
    7063:       ....
    7064:       call MatDenseGetArrayF90(x,xx_v,ierr)
    7065:       a = xx_v(3)
    7066:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
    7067: .ve

    7069:     Level: advanced

    7071: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray()

    7073:     Concepts: matrices^accessing array

    7075: M*/

    7077: /*MC
    7078:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
    7079:     accessed with MatGetArrayF90().

    7081:     Synopsis:
    7082:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

    7084:     Not collective

    7086:     Input Parameters:
    7087: +   x - matrix
    7088: -   xx_v - the Fortran90 pointer to the array

    7090:     Output Parameter:
    7091: .   ierr - error code

    7093:     Example of Usage:
    7094: .vb
    7095:        PetscScalar, pointer xx_v(:)
    7096:        ....
    7097:        call MatDenseGetArrayF90(x,xx_v,ierr)
    7098:        a = xx_v(3)
    7099:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
    7100: .ve

    7102:     Level: advanced

    7104: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray()

    7106: M*/

    7111: /*@
    7112:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
    7113:                       as the original matrix.

    7115:     Collective on Mat

    7117:     Input Parameters:
    7118: +   mat - the original matrix
    7119: .   isrow - parallel IS containing the rows this processor should obtain
    7120: .   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.
    7121: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    7123:     Output Parameter:
    7124: .   newmat - the new submatrix, of the same type as the old

    7126:     Level: advanced

    7128:     Notes:
    7129:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

    7131:     The rows in isrow will be sorted into the same order as the original matrix on each process.

    7133:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
    7134:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
    7135:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
    7136:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
    7137:    you are finished using it.

    7139:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
    7140:     the input matrix.

    7142:     If iscol is NULL then all columns are obtained (not supported in Fortran).

    7144:    Example usage:
    7145:    Consider the following 8x8 matrix with 34 non-zero values, that is
    7146:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
    7147:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
    7148:    as follows:

    7150: .vb
    7151:             1  2  0  |  0  3  0  |  0  4
    7152:     Proc0   0  5  6  |  7  0  0  |  8  0
    7153:             9  0 10  | 11  0  0  | 12  0
    7154:     -------------------------------------
    7155:            13  0 14  | 15 16 17  |  0  0
    7156:     Proc1   0 18  0  | 19 20 21  |  0  0
    7157:             0  0  0  | 22 23  0  | 24  0
    7158:     -------------------------------------
    7159:     Proc2  25 26 27  |  0  0 28  | 29  0
    7160:            30  0  0  | 31 32 33  |  0 34
    7161: .ve

    7163:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

    7165: .vb
    7166:             2  0  |  0  3  0  |  0
    7167:     Proc0   5  6  |  7  0  0  |  8
    7168:     -------------------------------
    7169:     Proc1  18  0  | 19 20 21  |  0
    7170:     -------------------------------
    7171:     Proc2  26 27  |  0  0 28  | 29
    7172:             0  0  | 31 32 33  |  0
    7173: .ve

    7176:     Concepts: matrices^submatrices

    7178: .seealso: MatGetSubMatrices()
    7179: @*/
    7180: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
    7181: {
    7183:   PetscMPIInt    size;
    7184:   Mat            *local;
    7185:   IS             iscoltmp;

    7194:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    7195:   MatCheckPreallocated(mat,1);
    7196:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

    7198:   if (!iscol) {
    7199:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
    7200:   } else {
    7201:     iscoltmp = iscol;
    7202:   }

    7204:   /* if original matrix is on just one processor then use submatrix generated */
    7205:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
    7206:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
    7207:     if (!iscol) {ISDestroy(&iscoltmp);}
    7208:     return(0);
    7209:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
    7210:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
    7211:     *newmat = *local;
    7212:     PetscFree(local);
    7213:     if (!iscol) {ISDestroy(&iscoltmp);}
    7214:     return(0);
    7215:   } else if (!mat->ops->getsubmatrix) {
    7216:     /* Create a new matrix type that implements the operation using the full matrix */
    7217:     switch (cll) {
    7218:     case MAT_INITIAL_MATRIX:
    7219:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
    7220:       break;
    7221:     case MAT_REUSE_MATRIX:
    7222:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
    7223:       break;
    7224:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
    7225:     }
    7226:     if (!iscol) {ISDestroy(&iscoltmp);}
    7227:     return(0);
    7228:   }

    7230:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    7231:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
    7232:   if (!iscol) {ISDestroy(&iscoltmp);}
    7233:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
    7234:   return(0);
    7235: }

    7239: /*@
    7240:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
    7241:    used during the assembly process to store values that belong to
    7242:    other processors.

    7244:    Not Collective

    7246:    Input Parameters:
    7247: +  mat   - the matrix
    7248: .  size  - the initial size of the stash.
    7249: -  bsize - the initial size of the block-stash(if used).

    7251:    Options Database Keys:
    7252: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
    7253: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

    7255:    Level: intermediate

    7257:    Notes:
    7258:      The block-stash is used for values set with MatSetValuesBlocked() while
    7259:      the stash is used for values set with MatSetValues()

    7261:      Run with the option -info and look for output of the form
    7262:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
    7263:      to determine the appropriate value, MM, to use for size and
    7264:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
    7265:      to determine the value, BMM to use for bsize

    7267:    Concepts: stash^setting matrix size
    7268:    Concepts: matrices^stash

    7270: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

    7272: @*/
    7273: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
    7274: {

    7280:   MatStashSetInitialSize_Private(&mat->stash,size);
    7281:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
    7282:   return(0);
    7283: }

    7287: /*@
    7288:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
    7289:      the matrix

    7291:    Neighbor-wise Collective on Mat

    7293:    Input Parameters:
    7294: +  mat   - the matrix
    7295: .  x,y - the vectors
    7296: -  w - where the result is stored

    7298:    Level: intermediate

    7300:    Notes:
    7301:     w may be the same vector as y.

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

    7306:     Concepts: interpolation

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

    7310: @*/
    7311: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
    7312: {
    7314:   PetscInt       M,N,Ny;

    7322:   MatCheckPreallocated(A,1);
    7323:   MatGetSize(A,&M,&N);
    7324:   VecGetSize(y,&Ny);
    7325:   if (M == Ny) {
    7326:     MatMultAdd(A,x,y,w);
    7327:   } else {
    7328:     MatMultTransposeAdd(A,x,y,w);
    7329:   }
    7330:   return(0);
    7331: }

    7335: /*@
    7336:    MatInterpolate - y = A*x or A'*x depending on the shape of
    7337:      the matrix

    7339:    Neighbor-wise Collective on Mat

    7341:    Input Parameters:
    7342: +  mat   - the matrix
    7343: -  x,y - the vectors

    7345:    Level: intermediate

    7347:    Notes:
    7348:     This allows one to use either the restriction or interpolation (its transpose)
    7349:     matrix to do the interpolation

    7351:    Concepts: matrices^interpolation

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

    7355: @*/
    7356: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
    7357: {
    7359:   PetscInt       M,N,Ny;

    7366:   MatCheckPreallocated(A,1);
    7367:   MatGetSize(A,&M,&N);
    7368:   VecGetSize(y,&Ny);
    7369:   if (M == Ny) {
    7370:     MatMult(A,x,y);
    7371:   } else {
    7372:     MatMultTranspose(A,x,y);
    7373:   }
    7374:   return(0);
    7375: }

    7379: /*@
    7380:    MatRestrict - y = A*x or A'*x

    7382:    Neighbor-wise Collective on Mat

    7384:    Input Parameters:
    7385: +  mat   - the matrix
    7386: -  x,y - the vectors

    7388:    Level: intermediate

    7390:    Notes:
    7391:     This allows one to use either the restriction or interpolation (its transpose)
    7392:     matrix to do the restriction

    7394:    Concepts: matrices^restriction

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

    7398: @*/
    7399: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
    7400: {
    7402:   PetscInt       M,N,Ny;

    7409:   MatCheckPreallocated(A,1);

    7411:   MatGetSize(A,&M,&N);
    7412:   VecGetSize(y,&Ny);
    7413:   if (M == Ny) {
    7414:     MatMult(A,x,y);
    7415:   } else {
    7416:     MatMultTranspose(A,x,y);
    7417:   }
    7418:   return(0);
    7419: }

    7423: /*@
    7424:    MatGetNullSpace - retrieves the null space to a matrix.

    7426:    Logically Collective on Mat and MatNullSpace

    7428:    Input Parameters:
    7429: +  mat - the matrix
    7430: -  nullsp - the null space object

    7432:    Level: developer

    7434:    Notes:
    7435:       This null space is used by solvers. Overwrites any previous null space that may have been attached

    7437:    Concepts: null space^attaching to matrix

    7439: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
    7440: @*/
    7441: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
    7442: {
    7447:   *nullsp = mat->nullsp;
    7448:   return(0);
    7449: }

    7453: /*@
    7454:    MatSetNullSpace - attaches a null space to a matrix.
    7455:         This null space will be removed from the resulting vector whenever
    7456:         MatMult() is called

    7458:    Logically Collective on Mat and MatNullSpace

    7460:    Input Parameters:
    7461: +  mat - the matrix
    7462: -  nullsp - the null space object

    7464:    Level: advanced

    7466:    Notes:
    7467:       This null space is used by solvers. Overwrites any previous null space that may have been attached

    7469:    Concepts: null space^attaching to matrix

    7471: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
    7472: @*/
    7473: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
    7474: {

    7481:   MatCheckPreallocated(mat,1);
    7482:   PetscObjectReference((PetscObject)nullsp);
    7483:   MatNullSpaceDestroy(&mat->nullsp);

    7485:   mat->nullsp = nullsp;
    7486:   return(0);
    7487: }

    7491: /*@
    7492:    MatSetNearNullSpace - attaches a null space to a matrix.
    7493:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

    7495:    Logically Collective on Mat and MatNullSpace

    7497:    Input Parameters:
    7498: +  mat - the matrix
    7499: -  nullsp - the null space object

    7501:    Level: advanced

    7503:    Notes:
    7504:       Overwrites any previous near null space that may have been attached

    7506:    Concepts: null space^attaching to matrix

    7508: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
    7509: @*/
    7510: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
    7511: {

    7518:   MatCheckPreallocated(mat,1);
    7519:   PetscObjectReference((PetscObject)nullsp);
    7520:   MatNullSpaceDestroy(&mat->nearnullsp);

    7522:   mat->nearnullsp = nullsp;
    7523:   return(0);
    7524: }

    7528: /*@
    7529:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

    7531:    Not Collective

    7533:    Input Parameters:
    7534: .  mat - the matrix

    7536:    Output Parameters:
    7537: .  nullsp - the null space object, NULL if not set

    7539:    Level: developer

    7541:    Concepts: null space^attaching to matrix

    7543: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
    7544: @*/
    7545: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
    7546: {
    7551:   MatCheckPreallocated(mat,1);
    7552:   *nullsp = mat->nearnullsp;
    7553:   return(0);
    7554: }

    7558: /*@C
    7559:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

    7561:    Collective on Mat

    7563:    Input Parameters:
    7564: +  mat - the matrix
    7565: .  row - row/column permutation
    7566: .  fill - expected fill factor >= 1.0
    7567: -  level - level of fill, for ICC(k)

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

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

    7577:    Level: developer

    7579:    Concepts: matrices^incomplete Cholesky factorization
    7580:    Concepts: Cholesky factorization

    7582: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

    7587: @*/
    7588: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
    7589: {

    7597:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
    7598:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    7599:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    7600:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    7601:   MatCheckPreallocated(mat,1);
    7602:   (*mat->ops->iccfactor)(mat,row,info);
    7603:   PetscObjectStateIncrease((PetscObject)mat);
    7604:   return(0);
    7605: }

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

    7612:    Not Collective

    7614:    Input Parameters:
    7615: +  mat - the matrix
    7616: .  nl - leading dimension of v
    7617: -  v - the values compute with ADIFOR

    7619:    Level: developer

    7621:    Notes:
    7622:      Must call MatSetColoring() before using this routine. Also this matrix must already
    7623:      have its nonzero pattern determined.

    7625: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    7626:           MatSetValues(), MatSetColoring()
    7627: @*/
    7628: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
    7629: {

    7637:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
    7638:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    7639:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    7640:   (*mat->ops->setvaluesadifor)(mat,nl,v);
    7641:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    7642:   PetscObjectStateIncrease((PetscObject)mat);
    7643:   return(0);
    7644: }

    7648: /*@
    7649:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
    7650:          ghosted ones.

    7652:    Not Collective

    7654:    Input Parameters:
    7655: +  mat - the matrix
    7656: -  diag = the diagonal values, including ghost ones

    7658:    Level: developer

    7660:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

    7662: .seealso: MatDiagonalScale()
    7663: @*/
    7664: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
    7665: {
    7667:   PetscMPIInt    size;

    7674:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
    7675:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
    7676:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
    7677:   if (size == 1) {
    7678:     PetscInt n,m;
    7679:     VecGetSize(diag,&n);
    7680:     MatGetSize(mat,0,&m);
    7681:     if (m == n) {
    7682:       MatDiagonalScale(mat,0,diag);
    7683:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
    7684:   } else {
    7685:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
    7686:   }
    7687:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
    7688:   PetscObjectStateIncrease((PetscObject)mat);
    7689:   return(0);
    7690: }

    7694: /*@
    7695:    MatGetInertia - Gets the inertia from a factored matrix

    7697:    Collective on Mat

    7699:    Input Parameter:
    7700: .  mat - the matrix

    7702:    Output Parameters:
    7703: +   nneg - number of negative eigenvalues
    7704: .   nzero - number of zero eigenvalues
    7705: -   npos - number of positive eigenvalues

    7707:    Level: advanced

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

    7712: @*/
    7713: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
    7714: {

    7720:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    7721:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
    7722:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    7723:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
    7724:   return(0);
    7725: }

    7727: /* ----------------------------------------------------------------*/
    7730: /*@C
    7731:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

    7733:    Neighbor-wise Collective on Mat and Vecs

    7735:    Input Parameters:
    7736: +  mat - the factored matrix
    7737: -  b - the right-hand-side vectors

    7739:    Output Parameter:
    7740: .  x - the result vectors

    7742:    Notes:
    7743:    The vectors b and x cannot be the same.  I.e., one cannot
    7744:    call MatSolves(A,x,x).

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

    7751:    Level: developer

    7753:    Concepts: matrices^triangular solves

    7755: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
    7756: @*/
    7757: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
    7758: {

    7764:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    7765:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    7766:   if (!mat->rmap->N && !mat->cmap->N) return(0);

    7768:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    7769:   MatCheckPreallocated(mat,1);
    7770:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
    7771:   (*mat->ops->solves)(mat,b,x);
    7772:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
    7773:   return(0);
    7774: }

    7778: /*@
    7779:    MatIsSymmetric - Test whether a matrix is symmetric

    7781:    Collective on Mat

    7783:    Input Parameter:
    7784: +  A - the matrix to test
    7785: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

    7787:    Output Parameters:
    7788: .  flg - the result

    7790:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

    7792:    Level: intermediate

    7794:    Concepts: matrix^symmetry

    7796: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
    7797: @*/
    7798: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
    7799: {

    7806:   if (!A->symmetric_set) {
    7807:     if (!A->ops->issymmetric) {
    7808:       MatType mattype;
    7809:       MatGetType(A,&mattype);
    7810:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
    7811:     }
    7812:     (*A->ops->issymmetric)(A,tol,flg);
    7813:     if (!tol) {
    7814:       A->symmetric_set = PETSC_TRUE;
    7815:       A->symmetric     = *flg;
    7816:       if (A->symmetric) {
    7817:         A->structurally_symmetric_set = PETSC_TRUE;
    7818:         A->structurally_symmetric     = PETSC_TRUE;
    7819:       }
    7820:     }
    7821:   } else if (A->symmetric) {
    7822:     *flg = PETSC_TRUE;
    7823:   } else if (!tol) {
    7824:     *flg = PETSC_FALSE;
    7825:   } else {
    7826:     if (!A->ops->issymmetric) {
    7827:       MatType mattype;
    7828:       MatGetType(A,&mattype);
    7829:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
    7830:     }
    7831:     (*A->ops->issymmetric)(A,tol,flg);
    7832:   }
    7833:   return(0);
    7834: }

    7838: /*@
    7839:    MatIsHermitian - Test whether a matrix is Hermitian

    7841:    Collective on Mat

    7843:    Input Parameter:
    7844: +  A - the matrix to test
    7845: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

    7847:    Output Parameters:
    7848: .  flg - the result

    7850:    Level: intermediate

    7852:    Concepts: matrix^symmetry

    7854: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
    7855:           MatIsSymmetricKnown(), MatIsSymmetric()
    7856: @*/
    7857: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
    7858: {

    7865:   if (!A->hermitian_set) {
    7866:     if (!A->ops->ishermitian) {
    7867:       MatType mattype;
    7868:       MatGetType(A,&mattype);
    7869:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
    7870:     }
    7871:     (*A->ops->ishermitian)(A,tol,flg);
    7872:     if (!tol) {
    7873:       A->hermitian_set = PETSC_TRUE;
    7874:       A->hermitian     = *flg;
    7875:       if (A->hermitian) {
    7876:         A->structurally_symmetric_set = PETSC_TRUE;
    7877:         A->structurally_symmetric     = PETSC_TRUE;
    7878:       }
    7879:     }
    7880:   } else if (A->hermitian) {
    7881:     *flg = PETSC_TRUE;
    7882:   } else if (!tol) {
    7883:     *flg = PETSC_FALSE;
    7884:   } else {
    7885:     if (!A->ops->ishermitian) {
    7886:       MatType mattype;
    7887:       MatGetType(A,&mattype);
    7888:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
    7889:     }
    7890:     (*A->ops->ishermitian)(A,tol,flg);
    7891:   }
    7892:   return(0);
    7893: }

    7897: /*@
    7898:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

    7900:    Not Collective

    7902:    Input Parameter:
    7903: .  A - the matrix to check

    7905:    Output Parameters:
    7906: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
    7907: -  flg - the result

    7909:    Level: advanced

    7911:    Concepts: matrix^symmetry

    7913:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
    7914:          if you want it explicitly checked

    7916: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
    7917: @*/
    7918: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
    7919: {
    7924:   if (A->symmetric_set) {
    7925:     *set = PETSC_TRUE;
    7926:     *flg = A->symmetric;
    7927:   } else {
    7928:     *set = PETSC_FALSE;
    7929:   }
    7930:   return(0);
    7931: }

    7935: /*@
    7936:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

    7938:    Not Collective

    7940:    Input Parameter:
    7941: .  A - the matrix to check

    7943:    Output Parameters:
    7944: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
    7945: -  flg - the result

    7947:    Level: advanced

    7949:    Concepts: matrix^symmetry

    7951:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
    7952:          if you want it explicitly checked

    7954: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
    7955: @*/
    7956: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
    7957: {
    7962:   if (A->hermitian_set) {
    7963:     *set = PETSC_TRUE;
    7964:     *flg = A->hermitian;
    7965:   } else {
    7966:     *set = PETSC_FALSE;
    7967:   }
    7968:   return(0);
    7969: }

    7973: /*@
    7974:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

    7976:    Collective on Mat

    7978:    Input Parameter:
    7979: .  A - the matrix to test

    7981:    Output Parameters:
    7982: .  flg - the result

    7984:    Level: intermediate

    7986:    Concepts: matrix^symmetry

    7988: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
    7989: @*/
    7990: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
    7991: {

    7997:   if (!A->structurally_symmetric_set) {
    7998:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
    7999:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

    8001:     A->structurally_symmetric_set = PETSC_TRUE;
    8002:   }
    8003:   *flg = A->structurally_symmetric;
    8004:   return(0);
    8005: }

    8009: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
    8010: /*@
    8011:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
    8012:        to be communicated to other processors during the MatAssemblyBegin/End() process

    8014:     Not collective

    8016:    Input Parameter:
    8017: .   vec - the vector

    8019:    Output Parameters:
    8020: +   nstash   - the size of the stash
    8021: .   reallocs - the number of additional mallocs incurred.
    8022: .   bnstash   - the size of the block stash
    8023: -   breallocs - the number of additional mallocs incurred.in the block stash

    8025:    Level: advanced

    8027: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

    8029: @*/
    8030: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
    8031: {

    8035:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
    8036:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
    8037:   return(0);
    8038: }

    8042: /*@C
    8043:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
    8044:      parallel layout

    8046:    Collective on Mat

    8048:    Input Parameter:
    8049: .  mat - the matrix

    8051:    Output Parameter:
    8052: +   right - (optional) vector that the matrix can be multiplied against
    8053: -   left - (optional) vector that the matrix vector product can be stored in

    8055:   Level: advanced

    8057: .seealso: MatCreate()
    8058: @*/
    8059: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
    8060: {

    8066:   MatCheckPreallocated(mat,1);
    8067:   if (mat->ops->getvecs) {
    8068:     (*mat->ops->getvecs)(mat,right,left);
    8069:   } else {
    8070:     PetscMPIInt size;
    8071:     MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
    8072:     if (right) {
    8073:       VecCreate(PetscObjectComm((PetscObject)mat),right);
    8074:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
    8075:       VecSetBlockSize(*right,mat->rmap->bs);
    8076:       VecSetType(*right,VECSTANDARD);
    8077:       PetscLayoutReference(mat->cmap,&(*right)->map);
    8078:     }
    8079:     if (left) {
    8080:       VecCreate(PetscObjectComm((PetscObject)mat),left);
    8081:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
    8082:       VecSetBlockSize(*left,mat->rmap->bs);
    8083:       VecSetType(*left,VECSTANDARD);
    8084:       PetscLayoutReference(mat->rmap,&(*left)->map);
    8085:     }
    8086:   }
    8087:   return(0);
    8088: }

    8092: /*@C
    8093:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
    8094:      with default values.

    8096:    Not Collective

    8098:    Input Parameters:
    8099: .    info - the MatFactorInfo data structure

    8102:    Notes: The solvers are generally used through the KSP and PC objects, for example
    8103:           PCLU, PCILU, PCCHOLESKY, PCICC

    8105:    Level: developer

    8107: .seealso: MatFactorInfo

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

    8112: @*/

    8114: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
    8115: {

    8119:   PetscMemzero(info,sizeof(MatFactorInfo));
    8120:   return(0);
    8121: }

    8125: /*@
    8126:    MatPtAP - Creates the matrix product C = P^T * A * P

    8128:    Neighbor-wise Collective on Mat

    8130:    Input Parameters:
    8131: +  A - the matrix
    8132: .  P - the projection matrix
    8133: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    8134: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

    8136:    Output Parameters:
    8137: .  C - the product matrix

    8139:    Notes:
    8140:    C will be created and must be destroyed by the user with MatDestroy().

    8142:    This routine is currently only implemented for pairs of AIJ matrices and classes
    8143:    which inherit from AIJ.

    8145:    Level: intermediate

    8147: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
    8148: @*/
    8149: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
    8150: {
    8152:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    8153:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
    8154:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
    8155:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

    8158:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
    8159:   PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

    8163:   MatCheckPreallocated(A,1);
    8164:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8165:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8168:   MatCheckPreallocated(P,2);
    8169:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8170:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    8172:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
    8173:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

    8175:   if (scall == MAT_REUSE_MATRIX) {
    8178:     if (viatranspose || viamatmatmatmult) {
    8179:       Mat Pt;
    8180:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
    8181:       if (viamatmatmatmult) {
    8182:         MatMatMatMult(Pt,A,P,scall,fill,C);
    8183:       } else {
    8184:         Mat AP;
    8185:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
    8186:         MatMatMult(Pt,AP,scall,fill,C);
    8187:         MatDestroy(&AP);
    8188:       }
    8189:       MatDestroy(&Pt);
    8190:     } else {
    8191:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
    8192:       (*(*C)->ops->ptapnumeric)(A,P,*C);
    8193:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
    8194:     }
    8195:     return(0);
    8196:   }

    8198:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    8199:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

    8201:   fA = A->ops->ptap;
    8202:   fP = P->ops->ptap;
    8203:   if (fP == fA) {
    8204:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
    8205:     ptap = fA;
    8206:   } else {
    8207:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
    8208:     char ptapname[256];
    8209:     PetscStrcpy(ptapname,"MatPtAP_");
    8210:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
    8211:     PetscStrcat(ptapname,"_");
    8212:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
    8213:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
    8214:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
    8215:     if (!ptap) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s",((PetscObject)A)->type_name,((PetscObject)P)->type_name);
    8216:   }

    8218:   if (viatranspose || viamatmatmatmult) {
    8219:     Mat Pt;
    8220:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
    8221:     if (viamatmatmatmult) {
    8222:       MatMatMatMult(Pt,A,P,scall,fill,C);
    8223:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
    8224:     } else {
    8225:       Mat AP;
    8226:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
    8227:       MatMatMult(Pt,AP,scall,fill,C);
    8228:       MatDestroy(&AP);
    8229:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
    8230:     }
    8231:     MatDestroy(&Pt);
    8232:   } else {
    8233:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
    8234:     (*ptap)(A,P,scall,fill,C);
    8235:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
    8236:   }
    8237:   return(0);
    8238: }

    8242: /*@
    8243:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

    8245:    Neighbor-wise Collective on Mat

    8247:    Input Parameters:
    8248: +  A - the matrix
    8249: -  P - the projection matrix

    8251:    Output Parameters:
    8252: .  C - the product matrix

    8254:    Notes:
    8255:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
    8256:    the user using MatDeatroy().

    8258:    This routine is currently only implemented for pairs of AIJ matrices and classes
    8259:    which inherit from AIJ.  C will be of type MATAIJ.

    8261:    Level: intermediate

    8263: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
    8264: @*/
    8265: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
    8266: {

    8272:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8273:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8276:   MatCheckPreallocated(P,2);
    8277:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8278:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8281:   MatCheckPreallocated(C,3);
    8282:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8283:   if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
    8284:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
    8285:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
    8286:   if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
    8287:   MatCheckPreallocated(A,1);

    8289:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
    8290:   (*C->ops->ptapnumeric)(A,P,C);
    8291:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
    8292:   return(0);
    8293: }

    8297: /*@
    8298:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

    8300:    Neighbor-wise Collective on Mat

    8302:    Input Parameters:
    8303: +  A - the matrix
    8304: -  P - the projection matrix

    8306:    Output Parameters:
    8307: .  C - the (i,j) structure of the product matrix

    8309:    Notes:
    8310:    C will be created and must be destroyed by the user with MatDestroy().

    8312:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
    8313:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
    8314:    this (i,j) structure by calling MatPtAPNumeric().

    8316:    Level: intermediate

    8318: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
    8319: @*/
    8320: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
    8321: {

    8327:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8328:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8329:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
    8332:   MatCheckPreallocated(P,2);
    8333:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8334:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    8337:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
    8338:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
    8339:   MatCheckPreallocated(A,1);
    8340:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
    8341:   (*A->ops->ptapsymbolic)(A,P,fill,C);
    8342:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

    8344:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
    8345:   return(0);
    8346: }

    8350: /*@
    8351:    MatRARt - Creates the matrix product C = R * A * R^T

    8353:    Neighbor-wise Collective on Mat

    8355:    Input Parameters:
    8356: +  A - the matrix
    8357: .  R - the projection matrix
    8358: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    8359: -  fill - expected fill as ratio of nnz(C)/nnz(A)

    8361:    Output Parameters:
    8362: .  C - the product matrix

    8364:    Notes:
    8365:    C will be created and must be destroyed by the user with MatDestroy().

    8367:    This routine is currently only implemented for pairs of AIJ matrices and classes
    8368:    which inherit from AIJ.

    8370:    Level: intermediate

    8372: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
    8373: @*/
    8374: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
    8375: {

    8381:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8382:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8385:   MatCheckPreallocated(R,2);
    8386:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8387:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8389:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
    8390:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
    8391:   MatCheckPreallocated(A,1);

    8393:   if (!A->ops->rart) {
    8394:     MatType mattype;
    8395:     MatGetType(A,&mattype);
    8396:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
    8397:   }
    8398:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
    8399:   (*A->ops->rart)(A,R,scall,fill,C);
    8400:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
    8401:   return(0);
    8402: }

    8406: /*@
    8407:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

    8409:    Neighbor-wise Collective on Mat

    8411:    Input Parameters:
    8412: +  A - the matrix
    8413: -  R - the projection matrix

    8415:    Output Parameters:
    8416: .  C - the product matrix

    8418:    Notes:
    8419:    C must have been created by calling MatRARtSymbolic and must be destroyed by
    8420:    the user using MatDeatroy().

    8422:    This routine is currently only implemented for pairs of AIJ matrices and classes
    8423:    which inherit from AIJ.  C will be of type MATAIJ.

    8425:    Level: intermediate

    8427: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
    8428: @*/
    8429: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
    8430: {

    8436:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8437:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8440:   MatCheckPreallocated(R,2);
    8441:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8442:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8445:   MatCheckPreallocated(C,3);
    8446:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8447:   if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
    8448:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
    8449:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
    8450:   if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
    8451:   MatCheckPreallocated(A,1);

    8453:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
    8454:   (*A->ops->rartnumeric)(A,R,C);
    8455:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
    8456:   return(0);
    8457: }

    8461: /*@
    8462:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

    8464:    Neighbor-wise Collective on Mat

    8466:    Input Parameters:
    8467: +  A - the matrix
    8468: -  R - the projection matrix

    8470:    Output Parameters:
    8471: .  C - the (i,j) structure of the product matrix

    8473:    Notes:
    8474:    C will be created and must be destroyed by the user with MatDestroy().

    8476:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
    8477:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
    8478:    this (i,j) structure by calling MatRARtNumeric().

    8480:    Level: intermediate

    8482: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
    8483: @*/
    8484: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
    8485: {

    8491:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8492:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8493:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
    8496:   MatCheckPreallocated(R,2);
    8497:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8498:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    8501:   if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
    8502:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
    8503:   MatCheckPreallocated(A,1);
    8504:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
    8505:   (*A->ops->rartsymbolic)(A,R,fill,C);
    8506:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

    8508:   MatSetBlockSize(*C,A->rmap->bs);
    8509:   return(0);
    8510: }

    8514: /*@
    8515:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

    8517:    Neighbor-wise Collective on Mat

    8519:    Input Parameters:
    8520: +  A - the left matrix
    8521: .  B - the right matrix
    8522: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    8523: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
    8524:           if the result is a dense matrix this is irrelevent

    8526:    Output Parameters:
    8527: .  C - the product matrix

    8529:    Notes:
    8530:    Unless scall is MAT_REUSE_MATRIX C will be created.

    8532:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

    8534:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    8535:    actually needed.

    8537:    If you have many matrices with the same non-zero structure to multiply, you
    8538:    should either
    8539: $   1) use MAT_REUSE_MATRIX in all calls but the first or
    8540: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

    8542:    Level: intermediate

    8544: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
    8545: @*/
    8546: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
    8547: {
    8549:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    8550:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
    8551:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

    8556:   MatCheckPreallocated(A,1);
    8557:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8558:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8561:   MatCheckPreallocated(B,2);
    8562:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8563:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8565:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
    8566:   if (scall == MAT_REUSE_MATRIX) {
    8569:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
    8570:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
    8571:     (*(*C)->ops->matmultnumeric)(A,B,*C);
    8572:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
    8573:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
    8574:     return(0);
    8575:   }
    8576:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    8577:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

    8579:   fA = A->ops->matmult;
    8580:   fB = B->ops->matmult;
    8581:   if (fB == fA) {
    8582:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
    8583:     mult = fB;
    8584:   } else {
    8585:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
    8586:     char multname[256];
    8587:     PetscStrcpy(multname,"MatMatMult_");
    8588:     PetscStrcat(multname,((PetscObject)A)->type_name);
    8589:     PetscStrcat(multname,"_");
    8590:     PetscStrcat(multname,((PetscObject)B)->type_name);
    8591:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
    8592:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
    8593:     if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
    8594:   }
    8595:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
    8596:   (*mult)(A,B,scall,fill,C);
    8597:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
    8598:   return(0);
    8599: }

    8603: /*@
    8604:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
    8605:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

    8607:    Neighbor-wise Collective on Mat

    8609:    Input Parameters:
    8610: +  A - the left matrix
    8611: .  B - the right matrix
    8612: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
    8613:       if C is a dense matrix this is irrelevent

    8615:    Output Parameters:
    8616: .  C - the product matrix

    8618:    Notes:
    8619:    Unless scall is MAT_REUSE_MATRIX C will be created.

    8621:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    8622:    actually needed.

    8624:    This routine is currently implemented for
    8625:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
    8626:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
    8627:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

    8629:    Level: intermediate

    8631:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
    8632:      We should incorporate them into PETSc.

    8634: .seealso: MatMatMult(), MatMatMultNumeric()
    8635: @*/
    8636: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
    8637: {
    8639:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
    8640:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
    8641:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

    8646:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8647:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    8651:   MatCheckPreallocated(B,2);
    8652:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8653:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    8656:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
    8657:   if (fill == PETSC_DEFAULT) fill = 2.0;
    8658:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
    8659:   MatCheckPreallocated(A,1);

    8661:   Asymbolic = A->ops->matmultsymbolic;
    8662:   Bsymbolic = B->ops->matmultsymbolic;
    8663:   if (Asymbolic == Bsymbolic) {
    8664:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
    8665:     symbolic = Bsymbolic;
    8666:   } else { /* dispatch based on the type of A and B */
    8667:     char symbolicname[256];
    8668:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
    8669:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
    8670:     PetscStrcat(symbolicname,"_");
    8671:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
    8672:     PetscStrcat(symbolicname,"_C");
    8673:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
    8674:     if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
    8675:   }
    8676:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
    8677:   (*symbolic)(A,B,fill,C);
    8678:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
    8679:   return(0);
    8680: }

    8684: /*@
    8685:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
    8686:    Call this routine after first calling MatMatMultSymbolic().

    8688:    Neighbor-wise Collective on Mat

    8690:    Input Parameters:
    8691: +  A - the left matrix
    8692: -  B - the right matrix

    8694:    Output Parameters:
    8695: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

    8697:    Notes:
    8698:    C must have been created with MatMatMultSymbolic().

    8700:    This routine is currently implemented for
    8701:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
    8702:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
    8703:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

    8705:    Level: intermediate

    8707: .seealso: MatMatMult(), MatMatMultSymbolic()
    8708: @*/
    8709: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
    8710: {

    8714:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
    8715:   return(0);
    8716: }

    8720: /*@
    8721:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

    8723:    Neighbor-wise Collective on Mat

    8725:    Input Parameters:
    8726: +  A - the left matrix
    8727: .  B - the right matrix
    8728: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    8729: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

    8731:    Output Parameters:
    8732: .  C - the product matrix

    8734:    Notes:
    8735:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

    8737:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

    8739:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    8740:    actually needed.

    8742:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

    8744:    Level: intermediate

    8746: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
    8747: @*/
    8748: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
    8749: {
    8751:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    8752:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

    8757:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8758:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8761:   MatCheckPreallocated(B,2);
    8762:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8763:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8765:   if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
    8766:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    8767:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
    8768:   MatCheckPreallocated(A,1);

    8770:   fA = A->ops->mattransposemult;
    8771:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
    8772:   fB = B->ops->mattransposemult;
    8773:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
    8774:   if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

    8776:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
    8777:   if (scall == MAT_INITIAL_MATRIX) {
    8778:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
    8779:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
    8780:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
    8781:   }
    8782:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
    8783:   (*A->ops->mattransposemultnumeric)(A,B,*C);
    8784:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
    8785:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
    8786:   return(0);
    8787: }

    8791: /*@
    8792:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

    8794:    Neighbor-wise Collective on Mat

    8796:    Input Parameters:
    8797: +  A - the left matrix
    8798: .  B - the right matrix
    8799: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    8800: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

    8802:    Output Parameters:
    8803: .  C - the product matrix

    8805:    Notes:
    8806:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

    8808:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

    8810:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    8811:    actually needed.

    8813:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
    8814:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

    8816:    Level: intermediate

    8818: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
    8819: @*/
    8820: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
    8821: {
    8823:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    8824:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
    8825:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

    8830:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8831:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8834:   MatCheckPreallocated(B,2);
    8835:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8836:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8838:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
    8839:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    8840:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
    8841:   MatCheckPreallocated(A,1);

    8843:   fA = A->ops->transposematmult;
    8844:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
    8845:   fB = B->ops->transposematmult;
    8846:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
    8847:   if (fB==fA) {
    8848:     transposematmult = fA;
    8849:   }
    8850:   if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
    8851:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
    8852:   (*transposematmult)(A,B,scall,fill,C);
    8853:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
    8854:   return(0);
    8855: }

    8859: /*@
    8860:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

    8862:    Neighbor-wise Collective on Mat

    8864:    Input Parameters:
    8865: +  A - the left matrix
    8866: .  B - the middle matrix
    8867: .  C - the right matrix
    8868: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    8869: -  fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate
    8870:           if the result is a dense matrix this is irrelevent

    8872:    Output Parameters:
    8873: .  D - the product matrix

    8875:    Notes:
    8876:    Unless scall is MAT_REUSE_MATRIX D will be created.

    8878:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

    8880:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    8881:    actually needed.

    8883:    If you have many matrices with the same non-zero structure to multiply, you
    8884:    should either
    8885: $   1) use MAT_REUSE_MATRIX in all calls but the first or
    8886: $   2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed

    8888:    Level: intermediate

    8890: .seealso: MatMatMult, MatPtAP()
    8891: @*/
    8892: PetscErrorCode  MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
    8893: {
    8895:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
    8896:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
    8897:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
    8898:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

    8903:   MatCheckPreallocated(A,1);
    8904:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8905:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8908:   MatCheckPreallocated(B,2);
    8909:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8910:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8913:   MatCheckPreallocated(C,3);
    8914:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8915:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8916:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
    8917:   if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N);
    8918:   if (scall == MAT_REUSE_MATRIX) {
    8921:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
    8922:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
    8923:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
    8924:     return(0);
    8925:   }
    8926:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    8927:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);

    8929:   fA = A->ops->matmatmult;
    8930:   fB = B->ops->matmatmult;
    8931:   fC = C->ops->matmatmult;
    8932:   if (fA == fB && fA == fC) {
    8933:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
    8934:     mult = fA;
    8935:   } else {
    8936:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
    8937:     char multname[256];
    8938:     PetscStrcpy(multname,"MatMatMatMult_");
    8939:     PetscStrcat(multname,((PetscObject)A)->type_name);
    8940:     PetscStrcat(multname,"_");
    8941:     PetscStrcat(multname,((PetscObject)B)->type_name);
    8942:     PetscStrcat(multname,"_");
    8943:     PetscStrcat(multname,((PetscObject)C)->type_name);
    8944:     PetscStrcat(multname,"_C");
    8945:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
    8946:     if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);
    8947:   }
    8948:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
    8949:   (*mult)(A,B,C,scall,fill,D);
    8950:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
    8951:   return(0);
    8952: }

    8956: /*@C
    8957:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

    8959:    Collective on Mat

    8961:    Input Parameters:
    8962: +  mat - the matrix
    8963: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
    8964: .  subcomm - MPI communicator split from the communicator where mat resides in
    8965: .  mlocal_red - number of local rows of the redundant matrix
    8966: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    8968:    Output Parameter:
    8969: .  matredundant - redundant matrix

    8971:    Notes:
    8972:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
    8973:    original matrix has not changed from that last call to MatGetRedundantMatrix().

    8975:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
    8976:    calling it.

    8978:    Only MPIAIJ matrix is supported.

    8980:    Level: advanced

    8982:    Concepts: subcommunicator
    8983:    Concepts: duplicate matrix

    8985: .seealso: MatDestroy()
    8986: @*/
    8987: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
    8988: {

    8993:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
    8996:   }
    8997:   if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    8998:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8999:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9000:   MatCheckPreallocated(mat,1);

    9002:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
    9003:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
    9004:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
    9005:   return(0);
    9006: }

    9010: /*@C
    9011:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
    9012:    a given 'mat' object. Each submatrix can span multiple procs.

    9014:    Collective on Mat

    9016:    Input Parameters:
    9017: +  mat - the matrix
    9018: .  subcomm - the subcommunicator obtained by com_split(comm)
    9019: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    9021:    Output Parameter:
    9022: .  subMat - 'parallel submatrices each spans a given subcomm

    9024:   Notes:
    9025:   The submatrix partition across processors is dictated by 'subComm' a
    9026:   communicator obtained by com_split(comm). The comm_split
    9027:   is not restriced to be grouped with consecutive original ranks.

    9029:   Due the comm_split() usage, the parallel layout of the submatrices
    9030:   map directly to the layout of the original matrix [wrt the local
    9031:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
    9032:   into the 'DiagonalMat' of the subMat, hence it is used directly from
    9033:   the subMat. However the offDiagMat looses some columns - and this is
    9034:   reconstructed with MatSetValues()

    9036:   Level: advanced

    9038:   Concepts: subcommunicator
    9039:   Concepts: submatrices

    9041: .seealso: MatGetSubMatrices()
    9042: @*/
    9043: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
    9044: {
    9046:   PetscMPIInt    commsize,subCommSize;

    9049:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
    9050:   MPI_Comm_size(subComm,&subCommSize);
    9051:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

    9053:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
    9054:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
    9055:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
    9056:   return(0);
    9057: }

    9061: /*@
    9062:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

    9064:    Not Collective

    9066:    Input Arguments:
    9067:    mat - matrix to extract local submatrix from
    9068:    isrow - local row indices for submatrix
    9069:    iscol - local column indices for submatrix

    9071:    Output Arguments:
    9072:    submat - the submatrix

    9074:    Level: intermediate

    9076:    Notes:
    9077:    The submat should be returned with MatRestoreLocalSubMatrix().

    9079:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
    9080:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

    9082:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
    9083:    MatSetValuesBlockedLocal() will also be implemented.

    9085: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
    9086: @*/
    9087: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
    9088: {

    9098:   if (mat->ops->getlocalsubmatrix) {
    9099:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
    9100:   } else {
    9101:     MatCreateLocalRef(mat,isrow,iscol,submat);
    9102:   }
    9103:   return(0);
    9104: }

    9108: /*@
    9109:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

    9111:    Not Collective

    9113:    Input Arguments:
    9114:    mat - matrix to extract local submatrix from
    9115:    isrow - local row indices for submatrix
    9116:    iscol - local column indices for submatrix
    9117:    submat - the submatrix

    9119:    Level: intermediate

    9121: .seealso: MatGetLocalSubMatrix()
    9122: @*/
    9123: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
    9124: {

    9133:   if (*submat) {
    9135:   }

    9137:   if (mat->ops->restorelocalsubmatrix) {
    9138:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
    9139:   } else {
    9140:     MatDestroy(submat);
    9141:   }
    9142:   *submat = NULL;
    9143:   return(0);
    9144: }

    9146: /* --------------------------------------------------------*/
    9149: /*@
    9150:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

    9152:    Collective on Mat

    9154:    Input Parameter:
    9155: .  mat - the matrix

    9157:    Output Parameter:
    9158: .  is - if any rows have zero diagonals this contains the list of them

    9160:    Level: developer

    9162:    Concepts: matrix-vector product

    9164: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    9165: @*/
    9166: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
    9167: {

    9173:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9174:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    9176:   if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
    9177:   (*mat->ops->findzerodiagonals)(mat,is);
    9178:   return(0);
    9179: }

    9183: /*@C
    9184:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

    9186:   Collective on Mat

    9188:   Input Parameters:
    9189: . mat - the matrix

    9191:   Output Parameters:
    9192: . values - the block inverses in column major order (FORTRAN-like)

    9194:    Note:
    9195:    This routine is not available from Fortran.

    9197:   Level: advanced
    9198: @*/
    9199: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
    9200: {

    9205:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9206:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9207:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
    9208:   (*mat->ops->invertblockdiagonal)(mat,values);
    9209:   return(0);
    9210: }

    9214: /*@C
    9215:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
    9216:     via MatTransposeColoringCreate().

    9218:     Collective on MatTransposeColoring

    9220:     Input Parameter:
    9221: .   c - coloring context

    9223:     Level: intermediate

    9225: .seealso: MatTransposeColoringCreate()
    9226: @*/
    9227: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
    9228: {
    9229:   PetscErrorCode       ierr;
    9230:   MatTransposeColoring matcolor=*c;

    9233:   if (!matcolor) return(0);
    9234:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

    9236:   PetscFree(matcolor->ncolumns);
    9237:   PetscFree(matcolor->nrows);
    9238:   PetscFree(matcolor->colorforrow);
    9239:   PetscFree2(matcolor->rows,matcolor->columnsforspidx);
    9240:   PetscFree(matcolor->colorforcol);
    9241:   PetscFree(matcolor->columns);
    9242:   PetscHeaderDestroy(c);
    9243:   return(0);
    9244: }

    9248: /*@C
    9249:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
    9250:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
    9251:     MatTransposeColoring to sparse B.

    9253:     Collective on MatTransposeColoring

    9255:     Input Parameters:
    9256: +   B - sparse matrix B
    9257: .   Btdense - symbolic dense matrix B^T
    9258: -   coloring - coloring context created with MatTransposeColoringCreate()

    9260:     Output Parameter:
    9261: .   Btdense - dense matrix B^T

    9263:     Options Database Keys:
    9264: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
    9265: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
    9266: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

    9268:     Level: intermediate

    9270: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

    9272: .keywords: coloring
    9273: @*/
    9274: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
    9275: {

    9283:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
    9284:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
    9285:   return(0);
    9286: }

    9290: /*@C
    9291:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
    9292:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
    9293:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
    9294:     Csp from Cden.

    9296:     Collective on MatTransposeColoring

    9298:     Input Parameters:
    9299: +   coloring - coloring context created with MatTransposeColoringCreate()
    9300: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

    9302:     Output Parameter:
    9303: .   Csp - sparse matrix

    9305:     Options Database Keys:
    9306: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
    9307: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
    9308: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

    9310:     Level: intermediate

    9312: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

    9314: .keywords: coloring
    9315: @*/
    9316: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
    9317: {

    9325:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
    9326:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
    9327:   return(0);
    9328: }

    9332: /*@C
    9333:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

    9335:    Collective on Mat

    9337:    Input Parameters:
    9338: +  mat - the matrix product C
    9339: -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()

    9341:     Output Parameter:
    9342: .   color - the new coloring context

    9344:     Level: intermediate

    9346: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
    9347:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
    9348: @*/
    9349: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
    9350: {
    9351:   MatTransposeColoring c;
    9352:   MPI_Comm             comm;
    9353:   PetscErrorCode       ierr;

    9356:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
    9357:   PetscObjectGetComm((PetscObject)mat,&comm);
    9358:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

    9360:   c->ctype = iscoloring->ctype;
    9361:   if (mat->ops->transposecoloringcreate) {
    9362:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
    9363:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

    9365:   *color = c;
    9366:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
    9367:   return(0);
    9368: }