Actual source code: matrix.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      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>
      8: #include <petsc/private/isimpl.h>

     10: /* Logging support */
     11: PetscClassId MAT_CLASSID;
     12: PetscClassId MAT_COLORING_CLASSID;
     13: PetscClassId MAT_FDCOLORING_CLASSID;
     14: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;

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

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

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

     47:    Logically Collective on Vec

     49:    Input Parameters:
     50: +  x  - the vector
     51: -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
     52:           it will create one internally.

     54:    Output Parameter:
     55: .  x  - the vector

     57:    Example of Usage:
     58: .vb
     59:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
     60:      VecSetRandom(x,rctx);
     61:      PetscRandomDestroy(rctx);
     62: .ve

     64:    Level: intermediate

     66:    Concepts: vector^setting to random
     67:    Concepts: random^vector

     69: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
     70: @*/
     71: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
     72: {
     74:   PetscRandom    randObj = NULL;

     81:   if (!rctx) {
     82:     MPI_Comm comm;
     83:     PetscObjectGetComm((PetscObject)x,&comm);
     84:     PetscRandomCreate(comm,&randObj);
     85:     PetscRandomSetFromOptions(randObj);
     86:     rctx = randObj;
     87:   }

     89:   PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
     90:   (*x->ops->setrandom)(x,rctx);
     91:   PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);

     93:   x->assembled = PETSC_TRUE;
     94:   PetscRandomDestroy(&randObj);
     95:   return(0);
     96: }

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

    104:   Input Parameter:
    105: .    A  - the matrix

    107:   Output Parameter:
    108: .    keptrows - the rows that are not completely zero

    110:   Level: intermediate

    112:  @*/
    113: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
    114: {

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

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

    131:    Not Collective

    133:    Input Parameters:
    134: .   A - the matrix

    136:    Output Parameters:
    137: .   a - the diagonal part (which is a SEQUENTIAL matrix)

    139:    Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
    140:           Use caution, as the reference count on the returned matrix is not incremented and it is used as
    141:           part of the containing MPI Mat's normal operation.

    143:    Level: advanced

    145: @*/
    146: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
    147: {
    148:   PetscErrorCode ierr,(*f)(Mat,Mat*);
    149:   PetscMPIInt    size;

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

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

    176:    Collective on Mat

    178:    Input Parameters:
    179: .  mat - the matrix

    181:    Output Parameter:
    182: .   trace - the sum of the diagonal entries

    184:    Level: advanced

    186: @*/
    187: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
    188: {
    190:   Vec            diag;

    193:   MatCreateVecs(mat,&diag,NULL);
    194:   MatGetDiagonal(mat,diag);
    195:   VecSum(diag,trace);
    196:   VecDestroy(&diag);
    197:   return(0);
    198: }

    202: /*@
    203:    MatRealPart - Zeros out the imaginary part of the matrix

    205:    Logically Collective on Mat

    207:    Input Parameters:
    208: .  mat - the matrix

    210:    Level: advanced

    213: .seealso: MatImaginaryPart()
    214: @*/
    215: PetscErrorCode MatRealPart(Mat mat)
    216: {

    222:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    223:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    224:   if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    225:   MatCheckPreallocated(mat,1);
    226:   (*mat->ops->realpart)(mat);
    227: #if defined(PETSC_HAVE_CUSP)
    228:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    229:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    230:   }
    231: #elif defined(PETSC_HAVE_VIENNACL)
    232:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    233:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    234:   }
    235: #elif defined(PETSC_HAVE_VECCUDA)
    236:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    237:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    238:   }
    239: #endif
    240:   return(0);
    241: }

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

    248:    Collective on Mat

    250:    Input Parameter:
    251: .  mat - the matrix

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

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

    259:    Level: advanced

    261: @*/
    262: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
    263: {

    269:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    270:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    271:   if (!mat->ops->getghosts) {
    272:     if (nghosts) *nghosts = 0;
    273:     if (ghosts) *ghosts = 0;
    274:   } else {
    275:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
    276:   }
    277:   return(0);
    278: }

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

    286:    Logically Collective on Mat

    288:    Input Parameters:
    289: .  mat - the matrix

    291:    Level: advanced

    294: .seealso: MatRealPart()
    295: @*/
    296: PetscErrorCode MatImaginaryPart(Mat mat)
    297: {

    303:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    304:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    305:   if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    306:   MatCheckPreallocated(mat,1);
    307:   (*mat->ops->imaginarypart)(mat);
    308: #if defined(PETSC_HAVE_CUSP)
    309:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    310:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    311:   }
    312: #elif defined(PETSC_HAVE_VIENNACL)
    313:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    314:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    315:   }
    316: #elif defined(PETSC_HAVE_VECCUDA)
    317:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    318:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    319:   }
    320: #endif
    321:   return(0);
    322: }

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

    329:    Collective on Mat

    331:    Input Parameter:
    332: .  mat - the matrix

    334:    Output Parameters:
    335: +  missing - is any diagonal missing
    336: -  dd - first diagonal entry that is missing (optional)

    338:    Level: advanced

    341: .seealso: MatRealPart()
    342: @*/
    343: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
    344: {

    350:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    351:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    352:   if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    353:   (*mat->ops->missingdiagonal)(mat,missing,dd);
    354:   return(0);
    355: }

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

    364:    Not Collective

    366:    Input Parameters:
    367: +  mat - the matrix
    368: -  row - the row to get

    370:    Output Parameters:
    371: +  ncols -  if not NULL, the number of nonzeros in the row
    372: .  cols - if not NULL, the column numbers
    373: -  vals - if not NULL, the values

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

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

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

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

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

    397:    Fortran Notes:
    398:    The calling sequence from Fortran is
    399: .vb
    400:    MatGetRow(matrix,row,ncols,cols,values,ierr)
    401:          Mat     matrix (input)
    402:          integer row    (input)
    403:          integer ncols  (output)
    404:          integer cols(maxcols) (output)
    405:          double precision (or double complex) values(maxcols) output
    406: .ve
    407:    where maxcols >= maximum nonzeros in any row of the matrix.

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

    414:    Level: advanced

    416:    Concepts: matrices^row access

    418: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
    419: @*/
    420: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
    421: {
    423:   PetscInt       incols;

    428:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    429:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    430:   if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    431:   MatCheckPreallocated(mat,1);
    432:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
    433:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
    434:   if (ncols) *ncols = incols;
    435:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
    436:   return(0);
    437: }

    441: /*@
    442:    MatConjugate - replaces the matrix values with their complex conjugates

    444:    Logically Collective on Mat

    446:    Input Parameters:
    447: .  mat - the matrix

    449:    Level: advanced

    451: .seealso:  VecConjugate()
    452: @*/
    453: PetscErrorCode MatConjugate(Mat mat)
    454: {
    455: #if defined(PETSC_USE_COMPLEX)

    460:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    461:   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");
    462:   (*mat->ops->conjugate)(mat);
    463: #if defined(PETSC_HAVE_CUSP)
    464:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    465:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    466:   }
    467: #elif defined(PETSC_HAVE_VIENNACL)
    468:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    469:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    470:   }
    471: #elif defined(PETSC_HAVE_VECCUDA)
    472:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    473:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    474:   }
    475: #endif
    476:   return(0);
    477: #else
    478:   return 0;
    479: #endif
    480: }

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

    487:    Not Collective

    489:    Input Parameters:
    490: +  mat - the matrix
    491: .  row - the row to get
    492: .  ncols, cols - the number of nonzeros and their columns
    493: -  vals - if nonzero the column values

    495:    Notes:
    496:    This routine should be called after you have finished examining the entries.

    498:    This routine zeros out ncols, cols, and vals. This is to prevent accidental
    499:    us of the array after it has been restored. If you pass NULL, it will
    500:    not zero the pointers.  Use of cols or vals after MatRestoreRow is invalid.

    502:    Fortran Notes:
    503:    The calling sequence from Fortran is
    504: .vb
    505:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
    506:       Mat     matrix (input)
    507:       integer row    (input)
    508:       integer ncols  (output)
    509:       integer cols(maxcols) (output)
    510:       double precision (or double complex) values(maxcols) output
    511: .ve
    512:    Where maxcols >= maximum nonzeros in any row of the matrix.

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

    517:    Level: advanced

    519: .seealso:  MatGetRow()
    520: @*/
    521: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
    522: {

    528:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    529:   if (!mat->ops->restorerow) return(0);
    530:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
    531:   if (ncols) *ncols = 0;
    532:   if (cols)  *cols = NULL;
    533:   if (vals)  *vals = NULL;
    534:   return(0);
    535: }

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

    543:    Not Collective

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

    548:    Notes:
    549:    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.

    551:    Level: advanced

    553:    Concepts: matrices^row access

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

    564:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    565:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    566:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    567:   MatCheckPreallocated(mat,1);
    568:   (*mat->ops->getrowuppertriangular)(mat);
    569:   return(0);
    570: }

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

    577:    Not Collective

    579:    Input Parameters:
    580: +  mat - the matrix

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

    586:    Level: advanced

    588: .seealso:  MatGetRowUpperTriangular()
    589: @*/
    590: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
    591: {

    596:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    597:   if (!mat->ops->restorerowuppertriangular) return(0);
    598:   (*mat->ops->restorerowuppertriangular)(mat);
    599:   return(0);
    600: }

    604: /*@C
    605:    MatSetOptionsPrefix - Sets the prefix used for searching for all
    606:    Mat options in the database.

    608:    Logically Collective on Mat

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

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

    618:    Level: advanced

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

    622: .seealso: MatSetFromOptions()
    623: @*/
    624: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
    625: {

    630:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
    631:   return(0);
    632: }

    636: /*@C
    637:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all
    638:    Mat options in the database.

    640:    Logically Collective on Mat

    642:    Input Parameters:
    643: +  A - the Mat context
    644: -  prefix - the prefix to prepend to all option names

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

    650:    Level: advanced

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

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

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

    668: /*@C
    669:    MatGetOptionsPrefix - Sets the prefix used for searching for all
    670:    Mat options in the database.

    672:    Not Collective

    674:    Input Parameter:
    675: .  A - the Mat context

    677:    Output Parameter:
    678: .  prefix - pointer to the prefix string used

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

    683:    Level: advanced

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

    687: .seealso: MatAppendOptionsPrefix()
    688: @*/
    689: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
    690: {

    695:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
    696:   return(0);
    697: }

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

    704:    Collective on Mat

    706:    Input Parameters:
    707: .  A - the Mat context

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

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

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

    716:    Level: beginner

    718: .keywords: Mat, setup

    720: .seealso: MatCreate(), MatDestroy()
    721: @*/
    722: PetscErrorCode MatSetUp(Mat A)
    723: {
    724:   PetscMPIInt    size;

    729:   if (!((PetscObject)A)->type_name) {
    730:     MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
    731:     if (size == 1) {
    732:       MatSetType(A, MATSEQAIJ);
    733:     } else {
    734:       MatSetType(A, MATMPIAIJ);
    735:     }
    736:   }
    737:   if (!A->preallocated && A->ops->setup) {
    738:     PetscInfo(A,"Warning not preallocating matrix storage\n");
    739:     (*A->ops->setup)(A);
    740:   }
    741:   A->preallocated = PETSC_TRUE;
    742:   return(0);
    743: }

    745: #if defined(PETSC_HAVE_SAWS)
    746: #include <petscviewersaws.h>
    747: #endif
    750: /*@C
    751:    MatView - Visualizes a matrix object.

    753:    Collective on Mat

    755:    Input Parameters:
    756: +  mat - the matrix
    757: -  viewer - visualization context

    759:   Notes:
    760:   The available visualization contexts include
    761: +    PETSC_VIEWER_STDOUT_SELF - for sequential matrices
    762: .    PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
    763: .    PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
    764: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

    766:    The user can open alternative visualization contexts with
    767: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
    768: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
    769:          specified file; corresponding input uses MatLoad()
    770: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to
    771:          an X window display
    772: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
    773:          Currently only the sequential dense and AIJ
    774:          matrix types support the Socket viewer.

    776:    The user can call PetscViewerPushFormat() to specify the output
    777:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
    778:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
    779: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
    780: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
    781: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
    782: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
    783:          format common among all matrix types
    784: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
    785:          format (which is in many cases the same as the default)
    786: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
    787:          size and structure (not the matrix entries)
    788: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
    789:          the matrix structure

    791:    Options Database Keys:
    792: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
    793: .  -mat_view ::ascii_info_detail - Prints more detailed info
    794: .  -mat_view - Prints matrix in ASCII format
    795: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
    796: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
    797: .  -display <name> - Sets display name (default is host)
    798: .  -draw_pause <sec> - Sets number of seconds to pause after display
    799: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 11 Using MATLAB with PETSc for details)
    800: .  -viewer_socket_machine <machine> -
    801: .  -viewer_socket_port <port> -
    802: .  -mat_view binary - save matrix to file in binary format
    803: -  -viewer_binary_filename <name> -
    804:    Level: beginner

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

    809:       See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
    810:       viewer is used.

    812:       One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
    813:       And then use the following mouse functions:
    814:           left mouse: zoom in
    815:           middle mouse: zoom out
    816:           right mouse: continue with the simulation

    818:    Concepts: matrices^viewing
    819:    Concepts: matrices^plotting
    820:    Concepts: matrices^printing

    822: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
    823:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
    824: @*/
    825: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
    826: {
    827:   PetscErrorCode    ierr;
    828:   PetscInt          rows,cols,rbs,cbs;
    829:   PetscBool         iascii,ibinary;
    830:   PetscViewerFormat format;
    831: #if defined(PETSC_HAVE_SAWS)
    832:   PetscBool         issaws;
    833: #endif

    838:   if (!viewer) {
    839:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
    840:   }
    843:   MatCheckPreallocated(mat,1);
    844:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
    845:   if (ibinary) {
    846:     PetscBool mpiio;
    847:     PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
    848:     if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
    849:   }

    851:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
    852:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    853:   PetscViewerGetFormat(viewer,&format);
    854:   if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
    855:     SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
    856:   }

    858: #if defined(PETSC_HAVE_SAWS)
    859:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
    860: #endif
    861:   if (iascii) {
    862:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
    863:     PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
    864:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    865:       PetscViewerASCIIPushTab(viewer);
    866:       MatGetSize(mat,&rows,&cols);
    867:       MatGetBlockSizes(mat,&rbs,&cbs);
    868:       if (rbs != 1 || cbs != 1) {
    869:         if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
    870:         else            {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
    871:       } else {
    872:         PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
    873:       }
    874:       if (mat->factortype) {
    875:         const MatSolverPackage solver;
    876:         MatFactorGetSolverPackage(mat,&solver);
    877:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
    878:       }
    879:       if (mat->ops->getinfo) {
    880:         MatInfo info;
    881:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
    882:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
    883:         PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
    884:       }
    885:       if (mat->nullsp) {PetscViewerASCIIPrintf(viewer,"  has attached null space\n");}
    886:       if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer,"  has attached near null space\n");}
    887:     }
    888: #if defined(PETSC_HAVE_SAWS)
    889:   } else if (issaws) {
    890:     PetscMPIInt rank;

    892:     PetscObjectName((PetscObject)mat);
    893:     MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
    894:     if (!((PetscObject)mat)->amsmem && !rank) {
    895:       PetscObjectViewSAWs((PetscObject)mat,viewer);
    896:     }
    897: #endif
    898:   }
    899:   if (mat->ops->view) {
    900:     PetscViewerASCIIPushTab(viewer);
    901:     (*mat->ops->view)(mat,viewer);
    902:     PetscViewerASCIIPopTab(viewer);
    903:   }
    904:   if (iascii) {
    905:     if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
    906:     PetscViewerGetFormat(viewer,&format);
    907:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
    908:       PetscViewerASCIIPopTab(viewer);
    909:     }
    910:   }
    911:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
    912:   return(0);
    913: }

    915: #if defined(PETSC_USE_DEBUG)
    916: #include <../src/sys/totalview/tv_data_display.h>
    917: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
    918: {
    919:   TV_add_row("Local rows", "int", &mat->rmap->n);
    920:   TV_add_row("Local columns", "int", &mat->cmap->n);
    921:   TV_add_row("Global rows", "int", &mat->rmap->N);
    922:   TV_add_row("Global columns", "int", &mat->cmap->N);
    923:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
    924:   return TV_format_OK;
    925: }
    926: #endif

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

    936:    Collective on PetscViewer

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

    943:    Options Database Keys:
    944:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
    945:    block size
    946: .    -matload_block_size <bs>

    948:    Level: beginner

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

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

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

    963:    In parallel, each processor can load a subset of rows (or the
    964:    entire matrix).  This routine is especially useful when a large
    965:    matrix is stored on disk and only part of it is desired on each
    966:    processor.  For example, a parallel solver may access only some of
    967:    the rows from each processor.  The algorithm used here reads
    968:    relatively small blocks of data rather than reading the entire
    969:    matrix and then subsetting it.

    971:    Notes for advanced users:
    972:    Most users should not need to know the details of the binary storage
    973:    format, since MatLoad() and MatView() completely hide these details.
    974:    But for anyone who's interested, the standard binary matrix storage
    975:    format is

    977: $    int    MAT_FILE_CLASSID
    978: $    int    number of rows
    979: $    int    number of columns
    980: $    int    total number of nonzeros
    981: $    int    *number nonzeros in each row
    982: $    int    *column indices of all nonzeros (starting index is zero)
    983: $    PetscScalar *values of all nonzeros

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

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

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

    995:  @*/
    996: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
    997: {
    999:   PetscBool      isbinary,flg;

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

    1007:   if (!((PetscObject)newmat)->type_name) {
    1008:     MatSetType(newmat,MATAIJ);
    1009:   }

    1011:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
    1012:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
    1013:   (*newmat->ops->load)(newmat,viewer);
    1014:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

    1016:   flg  = PETSC_FALSE;
    1017:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
    1018:   if (flg) {
    1019:     MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
    1020:     MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
    1021:   }
    1022:   flg  = PETSC_FALSE;
    1023:   PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
    1024:   if (flg) {
    1025:     MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
    1026:   }
    1027:   return(0);
    1028: }

    1032: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
    1033: {
    1035:   Mat_Redundant  *redund = *redundant;
    1036:   PetscInt       i;

    1039:   if (redund){
    1040:     if (redund->matseq) { /* via MatGetSubMatrices()  */
    1041:       ISDestroy(&redund->isrow);
    1042:       ISDestroy(&redund->iscol);
    1043:       MatDestroy(&redund->matseq[0]);
    1044:       PetscFree(redund->matseq);
    1045:     } else {
    1046:       PetscFree2(redund->send_rank,redund->recv_rank);
    1047:       PetscFree(redund->sbuf_j);
    1048:       PetscFree(redund->sbuf_a);
    1049:       for (i=0; i<redund->nrecvs; i++) {
    1050:         PetscFree(redund->rbuf_j[i]);
    1051:         PetscFree(redund->rbuf_a[i]);
    1052:       }
    1053:       PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
    1054:     }

    1056:     if (redund->subcomm) {
    1057:       PetscCommDestroy(&redund->subcomm);
    1058:     }
    1059:     PetscFree(redund);
    1060:   }
    1061:   return(0);
    1062: }

    1066: /*@
    1067:    MatDestroy - Frees space taken by a matrix.

    1069:    Collective on Mat

    1071:    Input Parameter:
    1072: .  A - the matrix

    1074:    Level: beginner

    1076: @*/
    1077: PetscErrorCode MatDestroy(Mat *A)
    1078: {

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

    1086:   /* if memory was published with SAWs then destroy it */
    1087:   PetscObjectSAWsViewOff((PetscObject)*A);
    1088:   if ((*A)->ops->destroy) {
    1089:     (*(*A)->ops->destroy)(*A);
    1090:   }

    1092:   PetscFree((*A)->solvertype);
    1093:   MatDestroy_Redundant(&(*A)->redundant);
    1094:   MatNullSpaceDestroy(&(*A)->nullsp);
    1095:   MatNullSpaceDestroy(&(*A)->transnullsp);
    1096:   MatNullSpaceDestroy(&(*A)->nearnullsp);
    1097:   PetscLayoutDestroy(&(*A)->rmap);
    1098:   PetscLayoutDestroy(&(*A)->cmap);
    1099:   PetscHeaderDestroy(A);
    1100:   return(0);
    1101: }

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

    1110:    Not Collective

    1112:    Input Parameters:
    1113: +  mat - the matrix
    1114: .  v - a logically two-dimensional array of values
    1115: .  m, idxm - the number of rows and their global indices
    1116: .  n, idxn - the number of columns and their global indices
    1117: -  addv - either ADD_VALUES or INSERT_VALUES, where
    1118:    ADD_VALUES adds values to any existing entries, and
    1119:    INSERT_VALUES replaces existing entries with new values

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

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

    1127:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
    1128:    options cannot be mixed without intervening calls to the assembly
    1129:    routines.

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

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

    1139:    Efficiency Alert:
    1140:    The routine MatSetValuesBlocked() may offer much better efficiency
    1141:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

    1143:    Level: beginner

    1145:    Concepts: matrices^putting entries in

    1147: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    1148:           InsertMode, INSERT_VALUES, ADD_VALUES
    1149: @*/
    1150: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
    1151: {
    1153: #if defined(PETSC_USE_DEBUG)
    1154:   PetscInt       i,j;
    1155: #endif

    1160:   if (!m || !n) return(0); /* no values to insert */
    1164:   MatCheckPreallocated(mat,1);
    1165:   if (mat->insertmode == NOT_SET_VALUES) {
    1166:     mat->insertmode = addv;
    1167:   }
    1168: #if defined(PETSC_USE_DEBUG)
    1169:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
    1170:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    1171:   if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);

    1173:   for (i=0; i<m; i++) {
    1174:     for (j=0; j<n; j++) {
    1175:       if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
    1176: #if defined(PETSC_USE_COMPLEX)
    1177:         SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
    1178: #else
    1179:         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
    1180: #endif
    1181:     }
    1182:   }
    1183: #endif

    1185:   if (mat->assembled) {
    1186:     mat->was_assembled = PETSC_TRUE;
    1187:     mat->assembled     = PETSC_FALSE;
    1188:   }
    1189:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    1190:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
    1191:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    1192: #if defined(PETSC_HAVE_CUSP)
    1193:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    1194:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    1195:   }
    1196: #elif defined(PETSC_HAVE_VIENNACL)
    1197:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    1198:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    1199:   }
    1200: #elif defined(PETSC_HAVE_VECCUDA)
    1201:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    1202:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    1203:   }
    1204: #endif
    1205:   return(0);
    1206: }

    1211: /*@
    1212:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
    1213:         values into a matrix

    1215:    Not Collective

    1217:    Input Parameters:
    1218: +  mat - the matrix
    1219: .  row - the (block) row to set
    1220: -  v - a logically two-dimensional array of values

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

    1225:    All the nonzeros in the row must be provided

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

    1229:    The row must belong to this process

    1231:    Level: intermediate

    1233:    Concepts: matrices^putting entries in

    1235: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    1236:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
    1237: @*/
    1238: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
    1239: {
    1241:   PetscInt       globalrow;

    1247:   ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
    1248:   MatSetValuesRow(mat,globalrow,v);
    1249: #if defined(PETSC_HAVE_CUSP)
    1250:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    1251:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    1252:   }
    1253: #elif defined(PETSC_HAVE_VIENNACL)
    1254:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    1255:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    1256:   }
    1257: #elif defined(PETSC_HAVE_VECCUDA)
    1258:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    1259:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    1260:   }
    1261: #endif
    1262:   return(0);
    1263: }

    1267: /*@
    1268:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
    1269:         values into a matrix

    1271:    Not Collective

    1273:    Input Parameters:
    1274: +  mat - the matrix
    1275: .  row - the (block) row to set
    1276: -  v - a logically two-dimensional array of values

    1278:    Notes:
    1279:    The values, v, are column-oriented for the block version.

    1281:    All the nonzeros in the row must be provided

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

    1285:    The row must belong to this process

    1287:    Level: advanced

    1289:    Concepts: matrices^putting entries in

    1291: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    1292:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
    1293: @*/
    1294: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
    1295: {

    1301:   MatCheckPreallocated(mat,1);
    1303: #if defined(PETSC_USE_DEBUG)
    1304:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
    1305:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    1306: #endif
    1307:   mat->insertmode = INSERT_VALUES;

    1309:   if (mat->assembled) {
    1310:     mat->was_assembled = PETSC_TRUE;
    1311:     mat->assembled     = PETSC_FALSE;
    1312:   }
    1313:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    1314:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    1315:   (*mat->ops->setvaluesrow)(mat,row,v);
    1316:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    1317: #if defined(PETSC_HAVE_CUSP)
    1318:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    1319:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    1320:   }
    1321: #elif defined(PETSC_HAVE_VIENNACL)
    1322:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    1323:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    1324:   }
    1325: #elif defined(PETSC_HAVE_VECCUDA)
    1326:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    1327:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    1328:   }
    1329: #endif
    1330:   return(0);
    1331: }

    1335: /*@
    1336:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
    1337:      Using structured grid indexing

    1339:    Not Collective

    1341:    Input Parameters:
    1342: +  mat - the matrix
    1343: .  m - number of rows being entered
    1344: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
    1345: .  n - number of columns being entered
    1346: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
    1347: .  v - a logically two-dimensional array of values
    1348: -  addv - either ADD_VALUES or INSERT_VALUES, where
    1349:    ADD_VALUES adds values to any existing entries, and
    1350:    INSERT_VALUES replaces existing entries with new values

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

    1355:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
    1356:    options cannot be mixed without intervening calls to the assembly
    1357:    routines.

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

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

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

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

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

    1375:    In Fortran idxm and idxn should be declared as
    1376: $     MatStencil idxm(4,m),idxn(4,n)
    1377:    and the values inserted using
    1378: $    idxm(MatStencil_i,1) = i
    1379: $    idxm(MatStencil_j,1) = j
    1380: $    idxm(MatStencil_k,1) = k
    1381: $    idxm(MatStencil_c,1) = c
    1382:    etc

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

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

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

    1395:    Efficiency Alert:
    1396:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
    1397:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

    1399:    Level: beginner

    1401:    Concepts: matrices^putting entries in

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

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

    1421:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
    1422:     jdxm = buf; jdxn = buf+m;
    1423:   } else {
    1424:     PetscMalloc2(m,&bufm,n,&bufn);
    1425:     jdxm = bufm; jdxn = bufn;
    1426:   }
    1427:   for (i=0; i<m; i++) {
    1428:     for (j=0; j<3-sdim; j++) dxm++;
    1429:     tmp = *dxm++ - starts[0];
    1430:     for (j=0; j<dim-1; j++) {
    1431:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
    1432:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
    1433:     }
    1434:     if (mat->stencil.noc) dxm++;
    1435:     jdxm[i] = tmp;
    1436:   }
    1437:   for (i=0; i<n; i++) {
    1438:     for (j=0; j<3-sdim; j++) dxn++;
    1439:     tmp = *dxn++ - starts[0];
    1440:     for (j=0; j<dim-1; j++) {
    1441:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
    1442:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
    1443:     }
    1444:     if (mat->stencil.noc) dxn++;
    1445:     jdxn[i] = tmp;
    1446:   }
    1447:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
    1448:   PetscFree2(bufm,bufn);
    1449:   return(0);
    1450: }

    1454: /*@
    1455:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
    1456:      Using structured grid indexing

    1458:    Not Collective

    1460:    Input Parameters:
    1461: +  mat - the matrix
    1462: .  m - number of rows being entered
    1463: .  idxm - grid coordinates for matrix rows being entered
    1464: .  n - number of columns being entered
    1465: .  idxn - grid coordinates for matrix columns being entered
    1466: .  v - a logically two-dimensional array of values
    1467: -  addv - either ADD_VALUES or INSERT_VALUES, where
    1468:    ADD_VALUES adds values to any existing entries, and
    1469:    INSERT_VALUES replaces existing entries with new values

    1471:    Notes:
    1472:    By default the values, v, are row-oriented and unsorted.
    1473:    See MatSetOption() for other options.

    1475:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
    1476:    options cannot be mixed without intervening calls to the assembly
    1477:    routines.

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

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

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

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

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

    1495:    In Fortran idxm and idxn should be declared as
    1496: $     MatStencil idxm(4,m),idxn(4,n)
    1497:    and the values inserted using
    1498: $    idxm(MatStencil_i,1) = i
    1499: $    idxm(MatStencil_j,1) = j
    1500: $    idxm(MatStencil_k,1) = k
    1501:    etc

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

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

    1511:    Level: beginner

    1513:    Concepts: matrices^putting entries in

    1515: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
    1516:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
    1517:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
    1518: @*/
    1519: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
    1520: {
    1522:   PetscInt       buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
    1523:   PetscInt       j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
    1524:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

    1534:   if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
    1535:     jdxm = buf; jdxn = buf+m;
    1536:   } else {
    1537:     PetscMalloc2(m,&bufm,n,&bufn);
    1538:     jdxm = bufm; jdxn = bufn;
    1539:   }
    1540:   for (i=0; i<m; i++) {
    1541:     for (j=0; j<3-sdim; j++) dxm++;
    1542:     tmp = *dxm++ - starts[0];
    1543:     for (j=0; j<sdim-1; j++) {
    1544:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
    1545:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
    1546:     }
    1547:     dxm++;
    1548:     jdxm[i] = tmp;
    1549:   }
    1550:   for (i=0; i<n; i++) {
    1551:     for (j=0; j<3-sdim; j++) dxn++;
    1552:     tmp = *dxn++ - starts[0];
    1553:     for (j=0; j<sdim-1; j++) {
    1554:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
    1555:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
    1556:     }
    1557:     dxn++;
    1558:     jdxn[i] = tmp;
    1559:   }
    1560:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
    1561:   PetscFree2(bufm,bufn);
    1562: #if defined(PETSC_HAVE_CUSP)
    1563:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    1564:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    1565:   }
    1566: #elif defined(PETSC_HAVE_VIENNACL)
    1567:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    1568:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    1569:   }
    1570: #elif defined(PETSC_HAVE_VECCUDA)
    1571:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    1572:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    1573:   }
    1574: #endif
    1575:   return(0);
    1576: }

    1580: /*@
    1581:    MatSetStencil - Sets the grid information for setting values into a matrix via
    1582:         MatSetValuesStencil()

    1584:    Not Collective

    1586:    Input Parameters:
    1587: +  mat - the matrix
    1588: .  dim - dimension of the grid 1, 2, or 3
    1589: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
    1590: .  starts - starting point of ghost nodes on your processor in x, y, and z direction
    1591: -  dof - number of degrees of freedom per node

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

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

    1600:    Level: beginner

    1602:    Concepts: matrices^putting entries in

    1604: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
    1605:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
    1606: @*/
    1607: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
    1608: {
    1609:   PetscInt i;

    1616:   mat->stencil.dim = dim + (dof > 1);
    1617:   for (i=0; i<dim; i++) {
    1618:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
    1619:     mat->stencil.starts[i] = starts[dim-i-1];
    1620:   }
    1621:   mat->stencil.dims[dim]   = dof;
    1622:   mat->stencil.starts[dim] = 0;
    1623:   mat->stencil.noc         = (PetscBool)(dof == 1);
    1624:   return(0);
    1625: }

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

    1632:    Not Collective

    1634:    Input Parameters:
    1635: +  mat - the matrix
    1636: .  v - a logically two-dimensional array of values
    1637: .  m, idxm - the number of block rows and their global block indices
    1638: .  n, idxn - the number of block columns and their global block indices
    1639: -  addv - either ADD_VALUES or INSERT_VALUES, where
    1640:    ADD_VALUES adds values to any existing entries, and
    1641:    INSERT_VALUES replaces existing entries with new values

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

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

    1653:    Note that you must call MatSetBlockSize() when constructing this matrix (before
    1654:    preallocating it).

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

    1659:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
    1660:    options cannot be mixed without intervening calls to the assembly
    1661:    routines.

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

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

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

    1677:    Example:
    1678: $   Suppose m=n=2 and block size(bs) = 2 The array is
    1679: $
    1680: $   1  2  | 3  4
    1681: $   5  6  | 7  8
    1682: $   - - - | - - -
    1683: $   9  10 | 11 12
    1684: $   13 14 | 15 16
    1685: $
    1686: $   v[] should be passed in like
    1687: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
    1688: $
    1689: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
    1690: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

    1692:    Level: intermediate

    1694:    Concepts: matrices^putting entries in blocked

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

    1705:   if (!m || !n) return(0); /* no values to insert */
    1709:   MatCheckPreallocated(mat,1);
    1710:   if (mat->insertmode == NOT_SET_VALUES) {
    1711:     mat->insertmode = addv;
    1712:   }
    1713: #if defined(PETSC_USE_DEBUG)
    1714:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
    1715:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    1716:   if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    1717: #endif

    1719:   if (mat->assembled) {
    1720:     mat->was_assembled = PETSC_TRUE;
    1721:     mat->assembled     = PETSC_FALSE;
    1722:   }
    1723:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    1724:   if (mat->ops->setvaluesblocked) {
    1725:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
    1726:   } else {
    1727:     PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
    1728:     PetscInt i,j,bs,cbs;
    1729:     MatGetBlockSizes(mat,&bs,&cbs);
    1730:     if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
    1731:       iidxm = buf; iidxn = buf + m*bs;
    1732:     } else {
    1733:       PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
    1734:       iidxm = bufr; iidxn = bufc;
    1735:     }
    1736:     for (i=0; i<m; i++) {
    1737:       for (j=0; j<bs; j++) {
    1738:         iidxm[i*bs+j] = bs*idxm[i] + j;
    1739:       }
    1740:     }
    1741:     for (i=0; i<n; i++) {
    1742:       for (j=0; j<cbs; j++) {
    1743:         iidxn[i*cbs+j] = cbs*idxn[i] + j;
    1744:       }
    1745:     }
    1746:     MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
    1747:     PetscFree2(bufr,bufc);
    1748:   }
    1749:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    1750: #if defined(PETSC_HAVE_CUSP)
    1751:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    1752:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    1753:   }
    1754: #elif defined(PETSC_HAVE_VIENNACL)
    1755:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    1756:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    1757:   }
    1758: #elif defined(PETSC_HAVE_VECCUDA)
    1759:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    1760:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    1761:   }
    1762: #endif
    1763:   return(0);
    1764: }

    1768: /*@
    1769:    MatGetValues - Gets a block of values from a matrix.

    1771:    Not Collective; currently only returns a local block

    1773:    Input Parameters:
    1774: +  mat - the matrix
    1775: .  v - a logically two-dimensional array for storing the values
    1776: .  m, idxm - the number of rows and their global indices
    1777: -  n, idxn - the number of columns and their global indices

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

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

    1787:    MatGetValues() requires that the matrix has been assembled
    1788:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
    1789:    MatSetValues() and MatGetValues() CANNOT be made in succession
    1790:    without intermediate matrix assembly.

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

    1795:    Level: advanced

    1797:    Concepts: matrices^accessing values

    1799: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
    1800: @*/
    1801: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
    1802: {

    1808:   if (!m || !n) return(0);
    1812:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    1813:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    1814:   if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    1815:   MatCheckPreallocated(mat,1);

    1817:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
    1818:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
    1819:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
    1820:   return(0);
    1821: }

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

    1829:   Not Collective

    1831:   Input Parameters:
    1832: + mat - the matrix
    1833: . nb - the number of blocks
    1834: . bs - the number of rows (and columns) in each block
    1835: . rows - a concatenation of the rows for each block
    1836: - v - a concatenation of logically two-dimensional arrays of values

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

    1841:   Level: advanced

    1843:   Concepts: matrices^putting entries in

    1845: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    1846:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
    1847: @*/
    1848: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
    1849: {

    1857: #if defined(PETSC_USE_DEBUG)
    1858:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    1859: #endif

    1861:   PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
    1862:   if (mat->ops->setvaluesbatch) {
    1863:     (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
    1864:   } else {
    1865:     PetscInt b;
    1866:     for (b = 0; b < nb; ++b) {
    1867:       MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
    1868:     }
    1869:   }
    1870:   PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
    1871:   return(0);
    1872: }

    1876: /*@
    1877:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
    1878:    the routine MatSetValuesLocal() to allow users to insert matrix entries
    1879:    using a local (per-processor) numbering.

    1881:    Not Collective

    1883:    Input Parameters:
    1884: +  x - the matrix
    1885: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()   or ISLocalToGlobalMappingCreateIS()
    1886: - cmapping - column mapping

    1888:    Level: intermediate

    1890:    Concepts: matrices^local to global mapping
    1891:    Concepts: local to global mapping^for matrices

    1893: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
    1894: @*/
    1895: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
    1896: {

    1905:   if (x->ops->setlocaltoglobalmapping) {
    1906:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
    1907:   } else {
    1908:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
    1909:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
    1910:   }
    1911:   return(0);
    1912: }

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

    1920:    Not Collective

    1922:    Input Parameters:
    1923: .  A - the matrix

    1925:    Output Parameters:
    1926: + rmapping - row mapping
    1927: - cmapping - column mapping

    1929:    Level: advanced

    1931:    Concepts: matrices^local to global mapping
    1932:    Concepts: local to global mapping^for matrices

    1934: .seealso:  MatSetValuesLocal()
    1935: @*/
    1936: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
    1937: {
    1943:   if (rmapping) *rmapping = A->rmap->mapping;
    1944:   if (cmapping) *cmapping = A->cmap->mapping;
    1945:   return(0);
    1946: }

    1950: /*@
    1951:    MatGetLayouts - Gets the PetscLayout objects for rows and columns

    1953:    Not Collective

    1955:    Input Parameters:
    1956: .  A - the matrix

    1958:    Output Parameters:
    1959: + rmap - row layout
    1960: - cmap - column layout

    1962:    Level: advanced

    1964: .seealso:  MatCreateVecs(), MatGetLocalToGlobalMapping()
    1965: @*/
    1966: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
    1967: {
    1973:   if (rmap) *rmap = A->rmap;
    1974:   if (cmap) *cmap = A->cmap;
    1975:   return(0);
    1976: }

    1980: /*@
    1981:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
    1982:    using a local ordering of the nodes.

    1984:    Not Collective

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

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

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

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

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

    2008:    Level: intermediate

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

    2012: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
    2013:            MatSetValueLocal()
    2014: @*/
    2015: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
    2016: {

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

    2036:   if (mat->assembled) {
    2037:     mat->was_assembled = PETSC_TRUE;
    2038:     mat->assembled     = PETSC_FALSE;
    2039:   }
    2040:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    2041:   if (mat->ops->setvalueslocal) {
    2042:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
    2043:   } else {
    2044:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
    2045:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
    2046:       irowm = buf; icolm = buf+nrow;
    2047:     } else {
    2048:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
    2049:       irowm = bufr; icolm = bufc;
    2050:     }
    2051:     ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
    2052:     ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
    2053:     MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
    2054:     PetscFree2(bufr,bufc);
    2055:   }
    2056:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    2057: #if defined(PETSC_HAVE_CUSP)
    2058:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    2059:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    2060:   }
    2061: #elif defined(PETSC_HAVE_VIENNACL)
    2062:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    2063:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    2064:   }
    2065: #elif defined(PETSC_HAVE_VECCUDA)
    2066:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    2067:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    2068:   }
    2069: #endif
    2070:   return(0);
    2071: }

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

    2079:    Not Collective

    2081:    Input Parameters:
    2082: +  x - the matrix
    2083: .  nrow, irow - number of rows and their local indices
    2084: .  ncol, icol - number of columns and their local indices
    2085: .  y -  a logically two-dimensional array of values
    2086: -  addv - either INSERT_VALUES or ADD_VALUES, where
    2087:    ADD_VALUES adds values to any existing entries, and
    2088:    INSERT_VALUES replaces existing entries with new values

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

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

    2097:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
    2098:    options cannot be mixed without intervening calls to the assembly
    2099:    routines.

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

    2104:    Level: intermediate

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

    2108: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
    2109:            MatSetValuesLocal(),  MatSetValuesBlocked()
    2110: @*/
    2111: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
    2112: {

    2118:   MatCheckPreallocated(mat,1);
    2119:   if (!nrow || !ncol) return(0); /* no values to insert */
    2123:   if (mat->insertmode == NOT_SET_VALUES) {
    2124:     mat->insertmode = addv;
    2125:   }
    2126: #if defined(PETSC_USE_DEBUG)
    2127:   else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
    2128:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2129:   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);
    2130: #endif

    2132:   if (mat->assembled) {
    2133:     mat->was_assembled = PETSC_TRUE;
    2134:     mat->assembled     = PETSC_FALSE;
    2135:   }
    2136:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    2137:   if (mat->ops->setvaluesblockedlocal) {
    2138:     (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
    2139:   } else {
    2140:     PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
    2141:     if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
    2142:       irowm = buf; icolm = buf + nrow;
    2143:     } else {
    2144:       PetscMalloc2(nrow,&bufr,ncol,&bufc);
    2145:       irowm = bufr; icolm = bufc;
    2146:     }
    2147:     ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
    2148:     ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
    2149:     MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
    2150:     PetscFree2(bufr,bufc);
    2151:   }
    2152:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    2153: #if defined(PETSC_HAVE_CUSP)
    2154:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    2155:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    2156:   }
    2157: #elif defined(PETSC_HAVE_VIENNACL)
    2158:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    2159:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    2160:   }
    2161: #elif defined(PETSC_HAVE_VECCUDA)
    2162:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    2163:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    2164:   }
    2165: #endif
    2166:   return(0);
    2167: }

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

    2174:    Collective on Mat and Vec

    2176:    Input Parameters:
    2177: +  mat - the matrix
    2178: -  x   - the vector to be multiplied

    2180:    Output Parameters:
    2181: .  y - the result

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

    2187:    Level: developer

    2189:    Concepts: matrix-vector product

    2191: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2192: @*/
    2193: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
    2194: {

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

    2208:   if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
    2209:   (*mat->ops->multdiagonalblock)(mat,x,y);
    2210:   PetscObjectStateIncrease((PetscObject)y);
    2211:   return(0);
    2212: }

    2214: /* --------------------------------------------------------*/
    2217: /*@
    2218:    MatMult - Computes the matrix-vector product, y = Ax.

    2220:    Neighbor-wise Collective on Mat and Vec

    2222:    Input Parameters:
    2223: +  mat - the matrix
    2224: -  x   - the vector to be multiplied

    2226:    Output Parameters:
    2227: .  y - the result

    2229:    Notes:
    2230:    The vectors x and y cannot be the same.  I.e., one cannot
    2231:    call MatMult(A,y,y).

    2233:    Level: beginner

    2235:    Concepts: matrix-vector product

    2237: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2238: @*/
    2239: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
    2240: {

    2248:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2249:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2250:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2251: #if !defined(PETSC_HAVE_CONSTRAINTS)
    2252:   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);
    2253:   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);
    2254:   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);
    2255: #endif
    2256:   VecLocked(y,3);
    2257:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
    2258:   MatCheckPreallocated(mat,1);

    2260:   VecLockPush(x);
    2261:   if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
    2262:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
    2263:   (*mat->ops->mult)(mat,x,y);
    2264:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);
    2265:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
    2266:   VecLockPop(x);
    2267:   return(0);
    2268: }

    2272: /*@
    2273:    MatMultTranspose - Computes matrix transpose times a vector.

    2275:    Neighbor-wise Collective on Mat and Vec

    2277:    Input Parameters:
    2278: +  mat - the matrix
    2279: -  x   - the vector to be multilplied

    2281:    Output Parameters:
    2282: .  y - the result

    2284:    Notes:
    2285:    The vectors x and y cannot be the same.  I.e., one cannot
    2286:    call MatMultTranspose(A,y,y).

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

    2291:    Level: beginner

    2293:    Concepts: matrix vector product^transpose

    2295: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
    2296: @*/
    2297: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
    2298: {

    2307:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2308:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2309:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2310: #if !defined(PETSC_HAVE_CONSTRAINTS)
    2311:   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);
    2312:   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);
    2313: #endif
    2314:   if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
    2315:   MatCheckPreallocated(mat,1);

    2317:   if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
    2318:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
    2319:   VecLockPush(x);
    2320:   (*mat->ops->multtranspose)(mat,x,y);
    2321:   VecLockPop(x);
    2322:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
    2323:   PetscObjectStateIncrease((PetscObject)y);
    2324:   if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
    2325:   return(0);
    2326: }

    2330: /*@
    2331:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

    2333:    Neighbor-wise Collective on Mat and Vec

    2335:    Input Parameters:
    2336: +  mat - the matrix
    2337: -  x   - the vector to be multilplied

    2339:    Output Parameters:
    2340: .  y - the result

    2342:    Notes:
    2343:    The vectors x and y cannot be the same.  I.e., one cannot
    2344:    call MatMultHermitianTranspose(A,y,y).

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

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

    2350:    Level: beginner

    2352:    Concepts: matrix vector product^transpose

    2354: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
    2355: @*/
    2356: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
    2357: {
    2359:   Vec            w;

    2367:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2368:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2369:   if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2370: #if !defined(PETSC_HAVE_CONSTRAINTS)
    2371:   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);
    2372:   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);
    2373: #endif
    2374:   MatCheckPreallocated(mat,1);

    2376:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
    2377:   if (mat->ops->multhermitiantranspose) {
    2378:     VecLockPush(x);
    2379:     (*mat->ops->multhermitiantranspose)(mat,x,y);
    2380:     VecLockPop(x);
    2381:   } else {
    2382:     VecDuplicate(x,&w);
    2383:     VecCopy(x,w);
    2384:     VecConjugate(w);
    2385:     MatMultTranspose(mat,w,y);
    2386:     VecDestroy(&w);
    2387:     VecConjugate(y);
    2388:   }
    2389:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
    2390:   PetscObjectStateIncrease((PetscObject)y);
    2391:   return(0);
    2392: }

    2396: /*@
    2397:     MatMultAdd -  Computes v3 = v2 + A * v1.

    2399:     Neighbor-wise Collective on Mat and Vec

    2401:     Input Parameters:
    2402: +   mat - the matrix
    2403: -   v1, v2 - the vectors

    2405:     Output Parameters:
    2406: .   v3 - the result

    2408:     Notes:
    2409:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
    2410:     call MatMultAdd(A,v1,v2,v1).

    2412:     Level: beginner

    2414:     Concepts: matrix vector product^addition

    2416: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
    2417: @*/
    2418: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
    2419: {

    2429:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2430:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2431:   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);
    2432:   /* 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);
    2433:      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); */
    2434:   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);
    2435:   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);
    2436:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
    2437:   MatCheckPreallocated(mat,1);

    2439:   if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
    2440:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
    2441:   VecLockPush(v1);
    2442:   (*mat->ops->multadd)(mat,v1,v2,v3);
    2443:   VecLockPop(v1);
    2444:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
    2445:   PetscObjectStateIncrease((PetscObject)v3);
    2446:   return(0);
    2447: }

    2451: /*@
    2452:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

    2454:    Neighbor-wise Collective on Mat and Vec

    2456:    Input Parameters:
    2457: +  mat - the matrix
    2458: -  v1, v2 - the vectors

    2460:    Output Parameters:
    2461: .  v3 - the result

    2463:    Notes:
    2464:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
    2465:    call MatMultTransposeAdd(A,v1,v2,v1).

    2467:    Level: beginner

    2469:    Concepts: matrix vector product^transpose and addition

    2471: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
    2472: @*/
    2473: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
    2474: {

    2484:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2485:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2486:   if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2487:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
    2488:   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);
    2489:   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);
    2490:   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);
    2491:   MatCheckPreallocated(mat,1);

    2493:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
    2494:   VecLockPush(v1);
    2495:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
    2496:   VecLockPop(v1);
    2497:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
    2498:   PetscObjectStateIncrease((PetscObject)v3);
    2499:   return(0);
    2500: }

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

    2507:    Neighbor-wise Collective on Mat and Vec

    2509:    Input Parameters:
    2510: +  mat - the matrix
    2511: -  v1, v2 - the vectors

    2513:    Output Parameters:
    2514: .  v3 - the result

    2516:    Notes:
    2517:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
    2518:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

    2520:    Level: beginner

    2522:    Concepts: matrix vector product^transpose and addition

    2524: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
    2525: @*/
    2526: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
    2527: {

    2537:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2538:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2539:   if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
    2540:   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);
    2541:   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);
    2542:   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);
    2543:   MatCheckPreallocated(mat,1);

    2545:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
    2546:   VecLockPush(v1);
    2547:   if (mat->ops->multhermitiantransposeadd) {
    2548:     (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
    2549:    } else {
    2550:     Vec w,z;
    2551:     VecDuplicate(v1,&w);
    2552:     VecCopy(v1,w);
    2553:     VecConjugate(w);
    2554:     VecDuplicate(v3,&z);
    2555:     MatMultTranspose(mat,w,z);
    2556:     VecDestroy(&w);
    2557:     VecConjugate(z);
    2558:     VecWAXPY(v3,1.0,v2,z);
    2559:     VecDestroy(&z);
    2560:   }
    2561:   VecLockPop(v1);
    2562:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
    2563:   PetscObjectStateIncrease((PetscObject)v3);
    2564:   return(0);
    2565: }

    2569: /*@
    2570:    MatMultConstrained - The inner multiplication routine for a
    2571:    constrained matrix P^T A P.

    2573:    Neighbor-wise Collective on Mat and Vec

    2575:    Input Parameters:
    2576: +  mat - the matrix
    2577: -  x   - the vector to be multilplied

    2579:    Output Parameters:
    2580: .  y - the result

    2582:    Notes:
    2583:    The vectors x and y cannot be the same.  I.e., one cannot
    2584:    call MatMult(A,y,y).

    2586:    Level: beginner

    2588: .keywords: matrix, multiply, matrix-vector product, constraint
    2589: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2590: @*/
    2591: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
    2592: {

    2599:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2600:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2601:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2602:   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);
    2603:   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);
    2604:   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);

    2606:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
    2607:   VecLockPush(x);
    2608:   (*mat->ops->multconstrained)(mat,x,y);
    2609:   VecLockPop(x);
    2610:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
    2611:   PetscObjectStateIncrease((PetscObject)y);
    2612:   return(0);
    2613: }

    2617: /*@
    2618:    MatMultTransposeConstrained - The inner multiplication routine for a
    2619:    constrained matrix P^T A^T P.

    2621:    Neighbor-wise Collective on Mat and Vec

    2623:    Input Parameters:
    2624: +  mat - the matrix
    2625: -  x   - the vector to be multilplied

    2627:    Output Parameters:
    2628: .  y - the result

    2630:    Notes:
    2631:    The vectors x and y cannot be the same.  I.e., one cannot
    2632:    call MatMult(A,y,y).

    2634:    Level: beginner

    2636: .keywords: matrix, multiply, matrix-vector product, constraint
    2637: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    2638: @*/
    2639: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
    2640: {

    2647:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2648:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2649:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
    2650:   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);
    2651:   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);

    2653:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
    2654:   (*mat->ops->multtransposeconstrained)(mat,x,y);
    2655:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
    2656:   PetscObjectStateIncrease((PetscObject)y);
    2657:   return(0);
    2658: }

    2662: /*@C
    2663:    MatGetFactorType - gets the type of factorization it is

    2665:    Note Collective
    2666:    as the flag

    2668:    Input Parameters:
    2669: .  mat - the matrix

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

    2674:     Level: intermediate

    2676: .seealso:    MatFactorType, MatGetFactor()
    2677: @*/
    2678: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
    2679: {
    2683:   *t = mat->factortype;
    2684:   return(0);
    2685: }

    2687: /* ------------------------------------------------------------*/
    2690: /*@C
    2691:    MatGetInfo - Returns information about matrix storage (number of
    2692:    nonzeros, memory, etc.).

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

    2696:    Input Parameters:
    2697: .  mat - the matrix

    2699:    Output Parameters:
    2700: +  flag - flag indicating the type of parameters to be returned
    2701:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
    2702:    MAT_GLOBAL_SUM - sum over all processors)
    2703: -  info - matrix information context

    2705:    Notes:
    2706:    The MatInfo context contains a variety of matrix data, including
    2707:    number of nonzeros allocated and used, number of mallocs during
    2708:    matrix assembly, etc.  Additional information for factored matrices
    2709:    is provided (such as the fill ratio, number of mallocs during
    2710:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
    2711:    when using the runtime options
    2712: $       -info -mat_view ::ascii_info

    2714:    Example for C/C++ Users:
    2715:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
    2716:    data within the MatInfo context.  For example,
    2717: .vb
    2718:       MatInfo info;
    2719:       Mat     A;
    2720:       double  mal, nz_a, nz_u;

    2722:       MatGetInfo(A,MAT_LOCAL,&info);
    2723:       mal  = info.mallocs;
    2724:       nz_a = info.nz_allocated;
    2725: .ve

    2727:    Example for Fortran Users:
    2728:    Fortran users should declare info as a double precision
    2729:    array of dimension MAT_INFO_SIZE, and then extract the parameters
    2730:    of interest.  See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
    2731:    a complete list of parameter names.
    2732: .vb
    2733:       double  precision info(MAT_INFO_SIZE)
    2734:       double  precision mal, nz_a
    2735:       Mat     A
    2736:       integer ierr

    2738:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
    2739:       mal = info(MAT_INFO_MALLOCS)
    2740:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
    2741: .ve

    2743:     Level: intermediate

    2745:     Concepts: matrices^getting information on

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

    2750: .seealso: MatStashGetInfo()

    2752: @*/
    2753: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
    2754: {

    2761:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2762:   MatCheckPreallocated(mat,1);
    2763:   (*mat->ops->getinfo)(mat,flag,info);
    2764:   return(0);
    2765: }

    2767: /* ----------------------------------------------------------*/

    2771: /*@C
    2772:    MatLUFactor - Performs in-place LU factorization of matrix.

    2774:    Collective on Mat

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

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

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

    2793:    Level: developer

    2795:    Concepts: matrices^LU factorization

    2797: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
    2798:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

    2803: @*/
    2804: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
    2805: {
    2807:   MatFactorInfo  tinfo;

    2815:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2816:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2817:   if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    2818:   MatCheckPreallocated(mat,1);
    2819:   if (!info) {
    2820:     MatFactorInfoInitialize(&tinfo);
    2821:     info = &tinfo;
    2822:   }

    2824:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
    2825:   (*mat->ops->lufactor)(mat,row,col,info);
    2826:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
    2827:   PetscObjectStateIncrease((PetscObject)mat);
    2828:   return(0);
    2829: }

    2833: /*@C
    2834:    MatILUFactor - Performs in-place ILU factorization of matrix.

    2836:    Collective on Mat

    2838:    Input Parameters:
    2839: +  mat - the matrix
    2840: .  row - row permutation
    2841: .  col - column permutation
    2842: -  info - structure containing
    2843: $      levels - number of levels of fill.
    2844: $      expected fill - as ratio of original fill.
    2845: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
    2846:                 missing diagonal entries)

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

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

    2856:    Level: developer

    2858:    Concepts: matrices^ILU factorization

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

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

    2865: @*/
    2866: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
    2867: {

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

    2882:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
    2883:   (*mat->ops->ilufactor)(mat,row,col,info);
    2884:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
    2885:   PetscObjectStateIncrease((PetscObject)mat);
    2886:   return(0);
    2887: }

    2891: /*@C
    2892:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
    2893:    Call this routine before calling MatLUFactorNumeric().

    2895:    Collective on Mat

    2897:    Input Parameters:
    2898: +  fact - the factor matrix obtained with MatGetFactor()
    2899: .  mat - the matrix
    2900: .  row, col - row and column permutations
    2901: -  info - options for factorization, includes
    2902: $          fill - expected fill as ratio of original fill.
    2903: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
    2904: $                   Run with the option -info to determine an optimal value to use

    2907:    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.

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

    2913:    Level: developer

    2915:    Concepts: matrices^LU symbolic factorization

    2917: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()

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

    2922: @*/
    2923: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
    2924: {

    2934:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2935:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    2936:   if (!(fact)->ops->lufactorsymbolic) {
    2937:     const MatSolverPackage spackage;
    2938:     MatFactorGetSolverPackage(fact,&spackage);
    2939:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
    2940:   }
    2941:   MatCheckPreallocated(mat,2);

    2943:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
    2944:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
    2945:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
    2946:   PetscObjectStateIncrease((PetscObject)fact);
    2947:   return(0);
    2948: }

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

    2956:    Collective on Mat

    2958:    Input Parameters:
    2959: +  fact - the factor matrix obtained with MatGetFactor()
    2960: .  mat - the matrix
    2961: -  info - options for factorization

    2963:    Notes:
    2964:    See MatLUFactor() for in-place factorization.  See
    2965:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.

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

    2971:    Level: developer

    2973:    Concepts: matrices^LU numeric factorization

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

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

    2980: @*/
    2981: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
    2982: {

    2990:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    2991:   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);

    2993:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
    2994:   MatCheckPreallocated(mat,2);
    2995:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
    2996:   (fact->ops->lufactornumeric)(fact,mat,info);
    2997:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
    2998:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
    2999:   PetscObjectStateIncrease((PetscObject)fact);
    3000:   return(0);
    3001: }

    3005: /*@C
    3006:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
    3007:    symmetric matrix.

    3009:    Collective on Mat

    3011:    Input Parameters:
    3012: +  mat - the matrix
    3013: .  perm - row and column permutations
    3014: -  f - expected fill as ratio of original fill

    3016:    Notes:
    3017:    See MatLUFactor() for the nonsymmetric case.  See also
    3018:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

    3024:    Level: developer

    3026:    Concepts: matrices^Cholesky factorization

    3028: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
    3029:           MatGetOrdering()

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

    3034: @*/
    3035: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
    3036: {

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

    3050:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
    3051:   (*mat->ops->choleskyfactor)(mat,perm,info);
    3052:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
    3053:   PetscObjectStateIncrease((PetscObject)mat);
    3054:   return(0);
    3055: }

    3059: /*@C
    3060:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
    3061:    of a symmetric matrix.

    3063:    Collective on Mat

    3065:    Input Parameters:
    3066: +  fact - the factor matrix obtained with MatGetFactor()
    3067: .  mat - the matrix
    3068: .  perm - row and column permutations
    3069: -  info - options for factorization, includes
    3070: $          fill - expected fill as ratio of original fill.
    3071: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
    3072: $                   Run with the option -info to determine an optimal value to use

    3074:    Notes:
    3075:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
    3076:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

    3082:    Level: developer

    3084:    Concepts: matrices^Cholesky symbolic factorization

    3086: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
    3087:           MatGetOrdering()

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

    3092: @*/
    3093: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
    3094: {

    3103:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
    3104:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3105:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3106:   if (!(fact)->ops->choleskyfactorsymbolic) {
    3107:     const MatSolverPackage spackage;
    3108:     MatFactorGetSolverPackage(fact,&spackage);
    3109:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
    3110:   }
    3111:   MatCheckPreallocated(mat,2);

    3113:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
    3114:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
    3115:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
    3116:   PetscObjectStateIncrease((PetscObject)fact);
    3117:   return(0);
    3118: }

    3122: /*@C
    3123:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
    3124:    of a symmetric matrix. Call this routine after first calling
    3125:    MatCholeskyFactorSymbolic().

    3127:    Collective on Mat

    3129:    Input Parameters:
    3130: +  fact - the factor matrix obtained with MatGetFactor()
    3131: .  mat - the initial matrix
    3132: .  info - options for factorization
    3133: -  fact - the symbolic factor of mat

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

    3141:    Level: developer

    3143:    Concepts: matrices^Cholesky numeric factorization

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

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

    3150: @*/
    3151: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
    3152: {

    3160:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3161:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
    3162:   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);
    3163:   MatCheckPreallocated(mat,2);

    3165:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
    3166:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
    3167:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
    3168:   MatViewFromOptions(fact,NULL,"-mat_factor_view");
    3169:   PetscObjectStateIncrease((PetscObject)fact);
    3170:   return(0);
    3171: }

    3173: /* ----------------------------------------------------------------*/
    3176: /*@
    3177:    MatSolve - Solves A x = b, given a factored matrix.

    3179:    Neighbor-wise Collective on Mat and Vec

    3181:    Input Parameters:
    3182: +  mat - the factored matrix
    3183: -  b - the right-hand-side vector

    3185:    Output Parameter:
    3186: .  x - the result vector

    3188:    Notes:
    3189:    The vectors b and x cannot be the same.  I.e., one cannot
    3190:    call MatSolve(A,x,x).

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

    3197:    Level: developer

    3199:    Concepts: matrices^triangular solves

    3201: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
    3202: @*/
    3203: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
    3204: {

    3214:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3215:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3216:   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);
    3217:   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);
    3218:   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);
    3219:   if (!mat->rmap->N && !mat->cmap->N) return(0);
    3220:   if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3221:   MatCheckPreallocated(mat,1);

    3223:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
    3224:   if (mat->errortype) {
    3225:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
    3226:     VecSetInf(x);
    3227:   } else {
    3228:     (*mat->ops->solve)(mat,b,x);
    3229:   }
    3230:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
    3231:   PetscObjectStateIncrease((PetscObject)x);
    3232:   return(0);
    3233: }

    3237: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
    3238: {
    3240:   Vec            b,x;
    3241:   PetscInt       m,N,i;
    3242:   PetscScalar    *bb,*xx;
    3243:   PetscBool      flg;

    3246:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
    3247:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
    3248:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
    3249:   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

    3251:   MatDenseGetArray(B,&bb);
    3252:   MatDenseGetArray(X,&xx);
    3253:   MatGetLocalSize(B,&m,NULL);  /* number local rows */
    3254:   MatGetSize(B,NULL,&N);       /* total columns in dense matrix */
    3255:   MatCreateVecs(A,&x,&b);
    3256:   for (i=0; i<N; i++) {
    3257:     VecPlaceArray(b,bb + i*m);
    3258:     VecPlaceArray(x,xx + i*m);
    3259:     MatSolve(A,b,x);
    3260:     VecResetArray(x);
    3261:     VecResetArray(b);
    3262:   }
    3263:   VecDestroy(&b);
    3264:   VecDestroy(&x);
    3265:   MatDenseRestoreArray(B,&bb);
    3266:   MatDenseRestoreArray(X,&xx);
    3267:   return(0);
    3268: }

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

    3275:    Neighbor-wise Collective on Mat

    3277:    Input Parameters:
    3278: +  A - the factored matrix
    3279: -  B - the right-hand-side matrix  (dense matrix)

    3281:    Output Parameter:
    3282: .  X - the result matrix (dense matrix)

    3284:    Notes:
    3285:    The matrices b and x cannot be the same.  I.e., one cannot
    3286:    call MatMatSolve(A,x,x).

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

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

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

    3299:    Level: developer

    3301:    Concepts: matrices^triangular solves

    3303: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
    3304: @*/
    3305: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
    3306: {

    3316:   if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
    3317:   if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3318:   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);
    3319:   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);
    3320:   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);
    3321:   if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
    3322:   if (!A->rmap->N && !A->cmap->N) return(0);
    3323:   MatCheckPreallocated(A,1);

    3325:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
    3326:   if (!A->ops->matsolve) {
    3327:     PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
    3328:     MatMatSolve_Basic(A,B,X);
    3329:   } else {
    3330:     (*A->ops->matsolve)(A,B,X);
    3331:   }
    3332:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
    3333:   PetscObjectStateIncrease((PetscObject)X);
    3334:   return(0);
    3335: }

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

    3344:    Neighbor-wise Collective on Mat and Vec

    3346:    Input Parameters:
    3347: +  mat - the factored matrix
    3348: -  b - the right-hand-side vector

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

    3353:    Notes:
    3354:    MatSolve() should be used for most applications, as it performs
    3355:    a forward solve followed by a backward solve.

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

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

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

    3370:    Level: developer

    3372:    Concepts: matrices^forward solves

    3374: .seealso: MatSolve(), MatBackwardSolve()
    3375: @*/
    3376: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
    3377: {

    3387:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3388:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3389:   if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3390:   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);
    3391:   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);
    3392:   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);
    3393:   MatCheckPreallocated(mat,1);
    3394:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
    3395:   (*mat->ops->forwardsolve)(mat,b,x);
    3396:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
    3397:   PetscObjectStateIncrease((PetscObject)x);
    3398:   return(0);
    3399: }

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

    3407:    Neighbor-wise Collective on Mat and Vec

    3409:    Input Parameters:
    3410: +  mat - the factored matrix
    3411: -  b - the right-hand-side vector

    3413:    Output Parameter:
    3414: .  x - the result vector

    3416:    Notes:
    3417:    MatSolve() should be used for most applications, as it performs
    3418:    a forward solve followed by a backward solve.

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

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

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

    3433:    Level: developer

    3435:    Concepts: matrices^backward solves

    3437: .seealso: MatSolve(), MatForwardSolve()
    3438: @*/
    3439: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
    3440: {

    3450:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3451:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3452:   if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3453:   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);
    3454:   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);
    3455:   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);
    3456:   MatCheckPreallocated(mat,1);

    3458:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
    3459:   (*mat->ops->backwardsolve)(mat,b,x);
    3460:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
    3461:   PetscObjectStateIncrease((PetscObject)x);
    3462:   return(0);
    3463: }

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

    3470:    Neighbor-wise Collective on Mat and Vec

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

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

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

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

    3488:    Level: developer

    3490:    Concepts: matrices^triangular solves

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

    3509:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3510:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3511:   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);
    3512:   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);
    3513:   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);
    3514:   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);
    3515:   if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
    3516:   MatCheckPreallocated(mat,1);

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

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

    3545:    Neighbor-wise Collective on Mat and Vec

    3547:    Input Parameters:
    3548: +  mat - the factored matrix
    3549: -  b - the right-hand-side vector

    3551:    Output Parameter:
    3552: .  x - the result vector

    3554:    Notes:
    3555:    The vectors b and x cannot be the same.  I.e., one cannot
    3556:    call MatSolveTranspose(A,x,x).

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

    3562:    Level: developer

    3564:    Concepts: matrices^triangular solves

    3566: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
    3567: @*/
    3568: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
    3569: {

    3579:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3580:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3581:   if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
    3582:   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);
    3583:   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);
    3584:   MatCheckPreallocated(mat,1);
    3585:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
    3586:   if (mat->errortype) {
    3587:     PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
    3588:     VecSetInf(x);
    3589:   } else {
    3590:     (*mat->ops->solvetranspose)(mat,b,x);
    3591:   }
    3592:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
    3593:   PetscObjectStateIncrease((PetscObject)x);
    3594:   return(0);
    3595: }

    3599: /*@
    3600:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
    3601:                       factored matrix.

    3603:    Neighbor-wise Collective on Mat and Vec

    3605:    Input Parameters:
    3606: +  mat - the factored matrix
    3607: .  b - the right-hand-side vector
    3608: -  y - the vector to be added to

    3610:    Output Parameter:
    3611: .  x - the result vector

    3613:    Notes:
    3614:    The vectors b and x cannot be the same.  I.e., one cannot
    3615:    call MatSolveTransposeAdd(A,x,y,x).

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

    3621:    Level: developer

    3623:    Concepts: matrices^triangular solves

    3625: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
    3626: @*/
    3627: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
    3628: {
    3629:   PetscScalar    one = 1.0;
    3631:   Vec            tmp;

    3642:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    3643:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    3644:   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);
    3645:   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);
    3646:   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);
    3647:   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);
    3648:   MatCheckPreallocated(mat,1);

    3650:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
    3651:   if (mat->ops->solvetransposeadd) {
    3652:     if (mat->errortype) {
    3653:       PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
    3654:       VecSetInf(x);
    3655:     } else {
    3656:       (*mat->ops->solvetransposeadd)(mat,b,y,x);
    3657:     }
    3658:   } else {
    3659:     /* do the solve then the add manually */
    3660:     if (x != y) {
    3661:       MatSolveTranspose(mat,b,x);
    3662:       VecAXPY(x,one,y);
    3663:     } else {
    3664:       VecDuplicate(x,&tmp);
    3665:       PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
    3666:       VecCopy(x,tmp);
    3667:       MatSolveTranspose(mat,b,x);
    3668:       VecAXPY(x,one,tmp);
    3669:       VecDestroy(&tmp);
    3670:     }
    3671:   }
    3672:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
    3673:   PetscObjectStateIncrease((PetscObject)x);
    3674:   return(0);
    3675: }
    3676: /* ----------------------------------------------------------------*/

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

    3683:    Neighbor-wise Collective on Mat and Vec

    3685:    Input Parameters:
    3686: +  mat - the matrix
    3687: .  b - the right hand side
    3688: .  omega - the relaxation factor
    3689: .  flag - flag indicating the type of SOR (see below)
    3690: .  shift -  diagonal shift
    3691: .  its - the number of iterations
    3692: -  lits - the number of local iterations

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

    3697:    SOR Flags:
    3698: .     SOR_FORWARD_SWEEP - forward SOR
    3699: .     SOR_BACKWARD_SWEEP - backward SOR
    3700: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
    3701: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR
    3702: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
    3703: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
    3704: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
    3705:          upper/lower triangular part of matrix to
    3706:          vector (with omega)
    3707: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

    3709:    Notes:
    3710:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
    3711:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
    3712:    on each processor.

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

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

    3719:    Notes for Advanced Users:
    3720:    The flags are implemented as bitwise inclusive or operations.
    3721:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
    3722:    to specify a zero initial guess for SSOR.

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

    3728:    Vectors x and b CANNOT be the same

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

    3732:    Level: developer

    3734:    Concepts: matrices^relaxation
    3735:    Concepts: matrices^SOR
    3736:    Concepts: matrices^Gauss-Seidel

    3738: @*/
    3739: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
    3740: {

    3750:   if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    3751:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3752:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3753:   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);
    3754:   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);
    3755:   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);
    3756:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
    3757:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
    3758:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

    3760:   MatCheckPreallocated(mat,1);
    3761:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
    3762:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
    3763:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
    3764:   PetscObjectStateIncrease((PetscObject)x);
    3765:   return(0);
    3766: }

    3770: /*
    3771:       Default matrix copy routine.
    3772: */
    3773: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
    3774: {
    3775:   PetscErrorCode    ierr;
    3776:   PetscInt          i,rstart = 0,rend = 0,nz;
    3777:   const PetscInt    *cwork;
    3778:   const PetscScalar *vwork;

    3781:   if (B->assembled) {
    3782:     MatZeroEntries(B);
    3783:   }
    3784:   MatGetOwnershipRange(A,&rstart,&rend);
    3785:   for (i=rstart; i<rend; i++) {
    3786:     MatGetRow(A,i,&nz,&cwork,&vwork);
    3787:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
    3788:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
    3789:   }
    3790:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
    3791:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
    3792:   PetscObjectStateIncrease((PetscObject)B);
    3793:   return(0);
    3794: }

    3798: /*@
    3799:    MatCopy - Copys a matrix to another matrix.

    3801:    Collective on Mat

    3803:    Input Parameters:
    3804: +  A - the matrix
    3805: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

    3807:    Output Parameter:
    3808: .  B - where the copy is put

    3810:    Notes:
    3811:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the
    3812:    same nonzero pattern or the routine will crash.

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

    3818:    Level: intermediate

    3820:    Concepts: matrices^copying

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

    3824: @*/
    3825: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
    3826: {
    3828:   PetscInt       i;

    3836:   MatCheckPreallocated(B,2);
    3837:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3838:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3839:   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);
    3840:   MatCheckPreallocated(A,1);

    3842:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
    3843:   if (A->ops->copy) {
    3844:     (*A->ops->copy)(A,B,str);
    3845:   } else { /* generic conversion */
    3846:     MatCopy_Basic(A,B,str);
    3847:   }

    3849:   B->stencil.dim = A->stencil.dim;
    3850:   B->stencil.noc = A->stencil.noc;
    3851:   for (i=0; i<=A->stencil.dim; i++) {
    3852:     B->stencil.dims[i]   = A->stencil.dims[i];
    3853:     B->stencil.starts[i] = A->stencil.starts[i];
    3854:   }

    3856:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
    3857:   PetscObjectStateIncrease((PetscObject)B);
    3858:   return(0);
    3859: }

    3863: /*@C
    3864:    MatConvert - Converts a matrix to another matrix, either of the same
    3865:    or different type.

    3867:    Collective on Mat

    3869:    Input Parameters:
    3870: +  mat - the matrix
    3871: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
    3872:    same type as the original matrix.
    3873: -  reuse - denotes if the destination matrix is to be created or reused.
    3874:    Use MAT_INPLACE_MATRIX for inplace conversion, otherwise use
    3875:    MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX.

    3877:    Output Parameter:
    3878: .  M - pointer to place new matrix

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

    3885:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
    3886:    the MPI communicator of the generated matrix is always the same as the communicator
    3887:    of the input matrix.

    3889:    Level: intermediate

    3891:    Concepts: matrices^converting between storage formats

    3893: .seealso: MatCopy(), MatDuplicate()
    3894: @*/
    3895: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
    3896: {
    3898:   PetscBool      sametype,issame,flg;
    3899:   char           convname[256],mtype[256];
    3900:   Mat            B;

    3906:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    3907:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    3908:   MatCheckPreallocated(mat,1);
    3909:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

    3911:   PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
    3912:   if (flg) {
    3913:     newtype = mtype;
    3914:   }
    3915:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
    3916:   PetscStrcmp(newtype,"same",&issame);
    3917:   if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");

    3919:   if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) return(0);

    3921:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
    3922:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
    3923:   } else {
    3924:     PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
    3925:     const char     *prefix[3] = {"seq","mpi",""};
    3926:     PetscInt       i;
    3927:     /*
    3928:        Order of precedence:
    3929:        1) See if a specialized converter is known to the current matrix.
    3930:        2) See if a specialized converter is known to the desired matrix class.
    3931:        3) See if a good general converter is registered for the desired class
    3932:           (as of 6/27/03 only MATMPIADJ falls into this category).
    3933:        4) See if a good general converter is known for the current matrix.
    3934:        5) Use a really basic converter.
    3935:     */

    3937:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
    3938:     for (i=0; i<3; i++) {
    3939:       PetscStrcpy(convname,"MatConvert_");
    3940:       PetscStrcat(convname,((PetscObject)mat)->type_name);
    3941:       PetscStrcat(convname,"_");
    3942:       PetscStrcat(convname,prefix[i]);
    3943:       PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
    3944:       PetscStrcat(convname,"_C");
    3945:       PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
    3946:       if (conv) goto foundconv;
    3947:     }

    3949:     /* 2)  See if a specialized converter is known to the desired matrix class. */
    3950:     MatCreate(PetscObjectComm((PetscObject)mat),&B);
    3951:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
    3952:     MatSetType(B,newtype);
    3953:     for (i=0; i<3; i++) {
    3954:       PetscStrcpy(convname,"MatConvert_");
    3955:       PetscStrcat(convname,((PetscObject)mat)->type_name);
    3956:       PetscStrcat(convname,"_");
    3957:       PetscStrcat(convname,prefix[i]);
    3958:       PetscStrcat(convname,newtype);
    3959:       PetscStrcat(convname,"_C");
    3960:       PetscObjectQueryFunction((PetscObject)B,convname,&conv);
    3961:       if (conv) {
    3962:         MatDestroy(&B);
    3963:         goto foundconv;
    3964:       }
    3965:     }

    3967:     /* 3) See if a good general converter is registered for the desired class */
    3968:     conv = B->ops->convertfrom;
    3969:     MatDestroy(&B);
    3970:     if (conv) goto foundconv;

    3972:     /* 4) See if a good general converter is known for the current matrix */
    3973:     if (mat->ops->convert) {
    3974:       conv = mat->ops->convert;
    3975:     }
    3976:     if (conv) goto foundconv;

    3978:     /* 5) Use a really basic converter. */
    3979:     conv = MatConvert_Basic;

    3981: foundconv:
    3982:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
    3983:     (*conv)(mat,newtype,reuse,M);
    3984:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
    3985:   }
    3986:   PetscObjectStateIncrease((PetscObject)*M);

    3988:   /* Copy Mat options */
    3989:   if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
    3990:   if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
    3991:   return(0);
    3992: }

    3996: /*@C
    3997:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

    3999:    Not Collective

    4001:    Input Parameter:
    4002: .  mat - the matrix, must be a factored matrix

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

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

    4011:    Level: intermediate

    4013: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
    4014: @*/
    4015: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
    4016: {
    4017:   PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);

    4022:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
    4023:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
    4024:   if (!conv) {
    4025:     *type = MATSOLVERPETSC;
    4026:   } else {
    4027:     (*conv)(mat,type);
    4028:   }
    4029:   return(0);
    4030: }

    4032: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
    4033: struct _MatSolverPackageForSpecifcType {
    4034:   MatType                        mtype;
    4035:   PetscErrorCode                 (*getfactor[4])(Mat,MatFactorType,Mat*);
    4036:   MatSolverPackageForSpecifcType next;
    4037: };

    4039: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
    4040: struct _MatSolverPackageHolder {
    4041:   char                           *name;
    4042:   MatSolverPackageForSpecifcType handlers;
    4043:   MatSolverPackageHolder         next;
    4044: };

    4046: static MatSolverPackageHolder MatSolverPackageHolders = NULL;

    4050: /*@C
    4051:    MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type

    4053:    Input Parameters:
    4054: +    package - name of the package, for example petsc or superlu
    4055: .    mtype - the matrix type that works with this package
    4056: .    ftype - the type of factorization supported by the package
    4057: -    getfactor - routine that will create the factored matrix ready to be used

    4059:     Level: intermediate

    4061: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
    4062: @*/
    4063: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
    4064: {
    4065:   PetscErrorCode                 ierr;
    4066:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
    4067:   PetscBool                      flg;
    4068:   MatSolverPackageForSpecifcType inext,iprev = NULL;

    4071:   if (!next) {
    4072:     PetscNew(&MatSolverPackageHolders);
    4073:     PetscStrallocpy(package,&MatSolverPackageHolders->name);
    4074:     PetscNew(&MatSolverPackageHolders->handlers);
    4075:     PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
    4076:     MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
    4077:     return(0);
    4078:   }
    4079:   while (next) {
    4080:     PetscStrcasecmp(package,next->name,&flg);
    4081:     if (flg) {
    4082:       inext = next->handlers;
    4083:       while (inext) {
    4084:         PetscStrcasecmp(mtype,inext->mtype,&flg);
    4085:         if (flg) {
    4086:           inext->getfactor[(int)ftype-1] = getfactor;
    4087:           return(0);
    4088:         }
    4089:         iprev = inext;
    4090:         inext = inext->next;
    4091:       }
    4092:       PetscNew(&iprev->next);
    4093:       PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
    4094:       iprev->next->getfactor[(int)ftype-1] = getfactor;
    4095:       return(0);
    4096:     }
    4097:     prev = next;
    4098:     next = next->next;
    4099:   }
    4100:   PetscNew(&prev->next);
    4101:   PetscStrallocpy(package,&prev->next->name);
    4102:   PetscNew(&prev->next->handlers);
    4103:   PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
    4104:   prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
    4105:   return(0);
    4106: }

    4110: /*@C
    4111:    MatSolvePackageGet - Get's the function that creates the factor matrix if it exist

    4113:    Input Parameters:
    4114: +    package - name of the package, for example petsc or superlu
    4115: .    ftype - the type of factorization supported by the package
    4116: -    mtype - the matrix type that works with this package

    4118:    Output Parameters:
    4119: +   foundpackage - PETSC_TRUE if the package was registered
    4120: .   foundmtype - PETSC_TRUE if the package supports the requested mtype
    4121: -   getfactor - routine that will create the factored matrix ready to be used or NULL if not found

    4123:     Level: intermediate

    4125: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
    4126: @*/
    4127: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
    4128: {
    4129:   PetscErrorCode                 ierr;
    4130:   MatSolverPackageHolder         next = MatSolverPackageHolders;
    4131:   PetscBool                      flg;
    4132:   MatSolverPackageForSpecifcType inext;

    4135:   if (foundpackage) *foundpackage = PETSC_FALSE;
    4136:   if (foundmtype)   *foundmtype   = PETSC_FALSE;
    4137:   if (getfactor)    *getfactor    = NULL;

    4139:   if (package) {
    4140:     while (next) {
    4141:       PetscStrcasecmp(package,next->name,&flg);
    4142:       if (flg) {
    4143:         if (foundpackage) *foundpackage = PETSC_TRUE;
    4144:         inext = next->handlers;
    4145:         while (inext) {
    4146:           PetscStrcasecmp(mtype,inext->mtype,&flg);
    4147:           if (flg) {
    4148:             if (foundmtype) *foundmtype = PETSC_TRUE;
    4149:             if (getfactor)  *getfactor  = inext->getfactor[(int)ftype-1];
    4150:             return(0);
    4151:           }
    4152:           inext = inext->next;
    4153:         }
    4154:       }
    4155:       next = next->next;
    4156:     }
    4157:   } else {
    4158:     while (next) {
    4159:       inext = next->handlers;
    4160:       while (inext) {
    4161:         PetscStrcasecmp(mtype,inext->mtype,&flg);
    4162:         if (flg && inext->getfactor[(int)ftype-1]) {
    4163:           if (foundpackage) *foundpackage = PETSC_TRUE;
    4164:           if (foundmtype)   *foundmtype   = PETSC_TRUE;
    4165:           if (getfactor)    *getfactor    = inext->getfactor[(int)ftype-1];
    4166:           return(0);
    4167:         }
    4168:         inext = inext->next;
    4169:       }
    4170:       next = next->next;
    4171:     }
    4172:   }
    4173:   return(0);
    4174: }

    4178: PetscErrorCode MatSolverPackageDestroy(void)
    4179: {
    4180:   PetscErrorCode                 ierr;
    4181:   MatSolverPackageHolder         next = MatSolverPackageHolders,prev;
    4182:   MatSolverPackageForSpecifcType inext,iprev;

    4185:   while (next) {
    4186:     PetscFree(next->name);
    4187:     inext = next->handlers;
    4188:     while (inext) {
    4189:       PetscFree(inext->mtype);
    4190:       iprev = inext;
    4191:       inext = inext->next;
    4192:       PetscFree(iprev);
    4193:     }
    4194:     prev = next;
    4195:     next = next->next;
    4196:     PetscFree(prev);
    4197:   }
    4198:   MatSolverPackageHolders = NULL;
    4199:   return(0);
    4200: }

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

    4207:    Collective on Mat

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

    4214:    Output Parameters:
    4215: .  f - the factor matrix used with MatXXFactorSymbolic() calls

    4217:    Notes:
    4218:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
    4219:      such as pastix, superlu, mumps etc.

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

    4223:    Level: intermediate

    4225: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
    4226: @*/
    4227: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
    4228: {
    4229:   PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
    4230:   PetscBool      foundpackage,foundmtype;

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

    4239:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
    4240:   if (!foundpackage) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
    4241:   if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
    4242:   if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for  matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);

    4244:   (*conv)(mat,ftype,f);
    4245:   return(0);
    4246: }

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

    4253:    Not Collective

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

    4260:    Output Parameter:
    4261: .    flg - PETSC_TRUE if the factorization is available

    4263:    Notes:
    4264:       Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
    4265:      such as pastix, superlu, mumps etc.

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

    4269:    Level: intermediate

    4271: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
    4272: @*/
    4273: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
    4274: {
    4275:   PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);

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

    4284:   *flg = PETSC_FALSE;
    4285:   MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
    4286:   if (gconv) {
    4287:     *flg = PETSC_TRUE;
    4288:   }
    4289:   return(0);
    4290: }

    4292: #include <petscdmtypes.h>

    4296: /*@
    4297:    MatDuplicate - Duplicates a matrix including the non-zero structure.

    4299:    Collective on Mat

    4301:    Input Parameters:
    4302: +  mat - the matrix
    4303: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
    4304:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

    4306:    Output Parameter:
    4307: .  M - pointer to place new matrix

    4309:    Level: intermediate

    4311:    Concepts: matrices^duplicating

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

    4315: .seealso: MatCopy(), MatConvert()
    4316: @*/
    4317: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
    4318: {
    4320:   Mat            B;
    4321:   PetscInt       i;
    4322:   DM             dm;

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

    4332:   *M = 0;
    4333:   if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
    4334:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
    4335:   (*mat->ops->duplicate)(mat,op,M);
    4336:   B    = *M;

    4338:   B->stencil.dim = mat->stencil.dim;
    4339:   B->stencil.noc = mat->stencil.noc;
    4340:   for (i=0; i<=mat->stencil.dim; i++) {
    4341:     B->stencil.dims[i]   = mat->stencil.dims[i];
    4342:     B->stencil.starts[i] = mat->stencil.starts[i];
    4343:   }

    4345:   B->nooffproczerorows = mat->nooffproczerorows;
    4346:   B->nooffprocentries  = mat->nooffprocentries;

    4348:   PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
    4349:   if (dm) {
    4350:     PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
    4351:   }
    4352:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
    4353:   PetscObjectStateIncrease((PetscObject)B);
    4354:   return(0);
    4355: }

    4359: /*@
    4360:    MatGetDiagonal - Gets the diagonal of a matrix.

    4362:    Logically Collective on Mat and Vec

    4364:    Input Parameters:
    4365: +  mat - the matrix
    4366: -  v - the vector for storing the diagonal

    4368:    Output Parameter:
    4369: .  v - the diagonal of the matrix

    4371:    Level: intermediate

    4373:    Note:
    4374:    Currently only correct in parallel for square matrices.

    4376:    Concepts: matrices^accessing diagonals

    4378: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
    4379: @*/
    4380: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
    4381: {

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

    4392:   (*mat->ops->getdiagonal)(mat,v);
    4393:   PetscObjectStateIncrease((PetscObject)v);
    4394:   return(0);
    4395: }

    4399: /*@C
    4400:    MatGetRowMin - Gets the minimum value (of the real part) of each
    4401:         row of the matrix

    4403:    Logically Collective on Mat and Vec

    4405:    Input Parameters:
    4406: .  mat - the matrix

    4408:    Output Parameter:
    4409: +  v - the vector for storing the maximums
    4410: -  idx - the indices of the column found for each row (optional)

    4412:    Level: intermediate

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

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

    4419:    Concepts: matrices^getting row maximums

    4421: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
    4422:           MatGetRowMax()
    4423: @*/
    4424: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
    4425: {

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

    4436:   (*mat->ops->getrowmin)(mat,v,idx);
    4437:   PetscObjectStateIncrease((PetscObject)v);
    4438:   return(0);
    4439: }

    4443: /*@C
    4444:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
    4445:         row of the matrix

    4447:    Logically Collective on Mat and Vec

    4449:    Input Parameters:
    4450: .  mat - the matrix

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

    4456:    Level: intermediate

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

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

    4463:    Concepts: matrices^getting row maximums

    4465: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
    4466: @*/
    4467: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
    4468: {

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

    4480:   (*mat->ops->getrowminabs)(mat,v,idx);
    4481:   PetscObjectStateIncrease((PetscObject)v);
    4482:   return(0);
    4483: }

    4487: /*@C
    4488:    MatGetRowMax - Gets the maximum value (of the real part) of each
    4489:         row of the matrix

    4491:    Logically Collective on Mat and Vec

    4493:    Input Parameters:
    4494: .  mat - the matrix

    4496:    Output Parameter:
    4497: +  v - the vector for storing the maximums
    4498: -  idx - the indices of the column found for each row (optional)

    4500:    Level: intermediate

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

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

    4507:    Concepts: matrices^getting row maximums

    4509: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
    4510: @*/
    4511: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
    4512: {

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

    4523:   (*mat->ops->getrowmax)(mat,v,idx);
    4524:   PetscObjectStateIncrease((PetscObject)v);
    4525:   return(0);
    4526: }

    4530: /*@C
    4531:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
    4532:         row of the matrix

    4534:    Logically Collective on Mat and Vec

    4536:    Input Parameters:
    4537: .  mat - the matrix

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

    4543:    Level: intermediate

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

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

    4550:    Concepts: matrices^getting row maximums

    4552: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
    4553: @*/
    4554: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
    4555: {

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

    4567:   (*mat->ops->getrowmaxabs)(mat,v,idx);
    4568:   PetscObjectStateIncrease((PetscObject)v);
    4569:   return(0);
    4570: }

    4574: /*@
    4575:    MatGetRowSum - Gets the sum of each row of the matrix

    4577:    Logically Collective on Mat and Vec

    4579:    Input Parameters:
    4580: .  mat - the matrix

    4582:    Output Parameter:
    4583: .  v - the vector for storing the sum of rows

    4585:    Level: intermediate

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

    4589:    Concepts: matrices^getting row sums

    4591: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
    4592: @*/
    4593: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
    4594: {
    4595:   PetscInt       start = 0, end = 0, row;
    4596:   PetscScalar    *array;

    4603:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4604:   MatCheckPreallocated(mat,1);
    4605:   MatGetOwnershipRange(mat, &start, &end);
    4606:   VecGetArray(v, &array);
    4607:   for (row = start; row < end; ++row) {
    4608:     PetscInt          ncols, col;
    4609:     const PetscInt    *cols;
    4610:     const PetscScalar *vals;

    4612:     array[row - start] = 0.0;

    4614:     MatGetRow(mat, row, &ncols, &cols, &vals);
    4615:     for (col = 0; col < ncols; col++) {
    4616:       array[row - start] += vals[col];
    4617:     }
    4618:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
    4619:   }
    4620:   VecRestoreArray(v, &array);
    4621:   PetscObjectStateIncrease((PetscObject) v);
    4622:   return(0);
    4623: }

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

    4630:    Collective on Mat

    4632:    Input Parameter:
    4633: +  mat - the matrix to transpose
    4634: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    4636:    Output Parameters:
    4637: .  B - the transpose

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

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

    4644:    Level: intermediate

    4646:    Concepts: matrices^transposing

    4648: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
    4649: @*/
    4650: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
    4651: {

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

    4662:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
    4663:   (*mat->ops->transpose)(mat,reuse,B);
    4664:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
    4665:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
    4666:   return(0);
    4667: }

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

    4675:    Collective on Mat

    4677:    Input Parameter:
    4678: +  A - the matrix to test
    4679: -  B - the matrix to test against, this can equal the first parameter

    4681:    Output Parameters:
    4682: .  flg - the result

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

    4689:    Level: intermediate

    4691:    Concepts: matrices^transposing, matrix^symmetry

    4693: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
    4694: @*/
    4695: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
    4696: {
    4697:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

    4703:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
    4704:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
    4705:   *flg = PETSC_FALSE;
    4706:   if (f && g) {
    4707:     if (f == g) {
    4708:       (*f)(A,B,tol,flg);
    4709:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
    4710:   } else {
    4711:     MatType mattype;
    4712:     if (!f) {
    4713:       MatGetType(A,&mattype);
    4714:     } else {
    4715:       MatGetType(B,&mattype);
    4716:     }
    4717:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
    4718:   }
    4719:   return(0);
    4720: }

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

    4727:    Collective on Mat

    4729:    Input Parameter:
    4730: +  mat - the matrix to transpose and complex conjugate
    4731: -  reuse - store the transpose matrix in the provided B

    4733:    Output Parameters:
    4734: .  B - the Hermitian

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

    4739:    Level: intermediate

    4741:    Concepts: matrices^transposing, complex conjugatex

    4743: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
    4744: @*/
    4745: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
    4746: {

    4750:   MatTranspose(mat,reuse,B);
    4751: #if defined(PETSC_USE_COMPLEX)
    4752:   MatConjugate(*B);
    4753: #endif
    4754:   return(0);
    4755: }

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

    4762:    Collective on Mat

    4764:    Input Parameter:
    4765: +  A - the matrix to test
    4766: -  B - the matrix to test against, this can equal the first parameter

    4768:    Output Parameters:
    4769: .  flg - the result

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

    4776:    Level: intermediate

    4778:    Concepts: matrices^transposing, matrix^symmetry

    4780: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
    4781: @*/
    4782: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
    4783: {
    4784:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);

    4790:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
    4791:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
    4792:   if (f && g) {
    4793:     if (f==g) {
    4794:       (*f)(A,B,tol,flg);
    4795:     } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
    4796:   }
    4797:   return(0);
    4798: }

    4802: /*@
    4803:    MatPermute - Creates a new matrix with rows and columns permuted from the
    4804:    original.

    4806:    Collective on Mat

    4808:    Input Parameters:
    4809: +  mat - the matrix to permute
    4810: .  row - row permutation, each processor supplies only the permutation for its rows
    4811: -  col - column permutation, each processor supplies only the permutation for its columns

    4813:    Output Parameters:
    4814: .  B - the permuted matrix

    4816:    Level: advanced

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

    4822:    Concepts: matrices^permuting

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

    4826: @*/
    4827: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
    4828: {

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

    4842:   (*mat->ops->permute)(mat,row,col,B);
    4843:   PetscObjectStateIncrease((PetscObject)*B);
    4844:   return(0);
    4845: }

    4849: /*@
    4850:    MatEqual - Compares two matrices.

    4852:    Collective on Mat

    4854:    Input Parameters:
    4855: +  A - the first matrix
    4856: -  B - the second matrix

    4858:    Output Parameter:
    4859: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

    4861:    Level: intermediate

    4863:    Concepts: matrices^equality between
    4864: @*/
    4865: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool  *flg)
    4866: {

    4876:   MatCheckPreallocated(B,2);
    4877:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4878:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    4879:   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);
    4880:   if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
    4881:   if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
    4882:   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);
    4883:   MatCheckPreallocated(A,1);

    4885:   (*A->ops->equal)(A,B,flg);
    4886:   return(0);
    4887: }

    4891: /*@
    4892:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
    4893:    matrices that are stored as vectors.  Either of the two scaling
    4894:    matrices can be NULL.

    4896:    Collective on Mat

    4898:    Input Parameters:
    4899: +  mat - the matrix to be scaled
    4900: .  l - the left scaling vector (or NULL)
    4901: -  r - the right scaling vector (or NULL)

    4903:    Notes:
    4904:    MatDiagonalScale() computes A = LAR, where
    4905:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
    4906:    The L scales the rows of the matrix, the R scales the columns of the matrix.

    4908:    Level: intermediate

    4910:    Concepts: matrices^diagonal scaling
    4911:    Concepts: diagonal scaling of matrices

    4913: .seealso: MatScale()
    4914: @*/
    4915: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
    4916: {

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

    4929:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
    4930:   (*mat->ops->diagonalscale)(mat,l,r);
    4931:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
    4932:   PetscObjectStateIncrease((PetscObject)mat);
    4933: #if defined(PETSC_HAVE_CUSP)
    4934:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    4935:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    4936:   }
    4937: #elif defined(PETSC_HAVE_VIENNACL)
    4938:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    4939:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    4940:   }
    4941: #elif defined(PETSC_HAVE_VECCUDA)
    4942:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    4943:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    4944:   }
    4945: #endif
    4946:   return(0);
    4947: }

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

    4954:     Logically Collective on Mat

    4956:     Input Parameters:
    4957: +   mat - the matrix to be scaled
    4958: -   a  - the scaling value

    4960:     Output Parameter:
    4961: .   mat - the scaled matrix

    4963:     Level: intermediate

    4965:     Concepts: matrices^scaling all entries

    4967: .seealso: MatDiagonalScale()
    4968: @*/
    4969: PetscErrorCode MatScale(Mat mat,PetscScalar a)
    4970: {

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

    4982:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
    4983:   if (a != (PetscScalar)1.0) {
    4984:     (*mat->ops->scale)(mat,a);
    4985:     PetscObjectStateIncrease((PetscObject)mat);
    4986:   }
    4987:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
    4988: #if defined(PETSC_HAVE_CUSP)
    4989:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    4990:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    4991:   }
    4992: #elif defined(PETSC_HAVE_VIENNACL)
    4993:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    4994:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    4995:   }
    4996: #elif defined(PETSC_HAVE_VECCUDA)
    4997:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    4998:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    4999:   }
    5000: #endif
    5001:   return(0);
    5002: }

    5006: /*@
    5007:    MatNorm - Calculates various norms of a matrix.

    5009:    Collective on Mat

    5011:    Input Parameters:
    5012: +  mat - the matrix
    5013: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

    5015:    Output Parameters:
    5016: .  nrm - the resulting norm

    5018:    Level: intermediate

    5020:    Concepts: matrices^norm
    5021:    Concepts: norm^of matrix
    5022: @*/
    5023: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
    5024: {

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

    5037:   (*mat->ops->norm)(mat,type,nrm);
    5038:   return(0);
    5039: }

    5041: /*
    5042:      This variable is used to prevent counting of MatAssemblyBegin() that
    5043:    are called from within a MatAssemblyEnd().
    5044: */
    5045: static PetscInt MatAssemblyEnd_InUse = 0;
    5048: /*@
    5049:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
    5050:    be called after completing all calls to MatSetValues().

    5052:    Collective on Mat

    5054:    Input Parameters:
    5055: +  mat - the matrix
    5056: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

    5058:    Notes:
    5059:    MatSetValues() generally caches the values.  The matrix is ready to
    5060:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
    5061:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
    5062:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
    5063:    using the matrix.

    5065:    ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
    5066:    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
    5067:    a global collective operation requring all processes that share the matrix.

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

    5073:    Level: beginner

    5075:    Concepts: matrices^assembling

    5077: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
    5078: @*/
    5079: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
    5080: {

    5086:   MatCheckPreallocated(mat,1);
    5087:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
    5088:   if (mat->assembled) {
    5089:     mat->was_assembled = PETSC_TRUE;
    5090:     mat->assembled     = PETSC_FALSE;
    5091:   }
    5092:   if (!MatAssemblyEnd_InUse) {
    5093:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
    5094:     if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
    5095:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
    5096:   } else if (mat->ops->assemblybegin) {
    5097:     (*mat->ops->assemblybegin)(mat,type);
    5098:   }
    5099:   return(0);
    5100: }

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

    5108:    Not Collective

    5110:    Input Parameter:
    5111: .  mat - the matrix

    5113:    Output Parameter:
    5114: .  assembled - PETSC_TRUE or PETSC_FALSE

    5116:    Level: advanced

    5118:    Concepts: matrices^assembled?

    5120: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
    5121: @*/
    5122: PetscErrorCode MatAssembled(Mat mat,PetscBool  *assembled)
    5123: {
    5128:   *assembled = mat->assembled;
    5129:   return(0);
    5130: }

    5134: /*@
    5135:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
    5136:    be called after MatAssemblyBegin().

    5138:    Collective on Mat

    5140:    Input Parameters:
    5141: +  mat - the matrix
    5142: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

    5144:    Options Database Keys:
    5145: +  -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
    5146: .  -mat_view ::ascii_info_detail - Prints more detailed info
    5147: .  -mat_view - Prints matrix in ASCII format
    5148: .  -mat_view ::ascii_matlab - Prints matrix in Matlab format
    5149: .  -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
    5150: .  -display <name> - Sets display name (default is host)
    5151: .  -draw_pause <sec> - Sets number of seconds to pause after display
    5152: .  -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
    5153: .  -viewer_socket_machine <machine> - Machine to use for socket
    5154: .  -viewer_socket_port <port> - Port number to use for socket
    5155: -  -mat_view binary:filename[:append] - Save matrix to file in binary format

    5157:    Notes:
    5158:    MatSetValues() generally caches the values.  The matrix is ready to
    5159:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
    5160:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
    5161:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
    5162:    using the matrix.

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

    5168:    Level: beginner

    5170: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
    5171: @*/
    5172: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
    5173: {
    5174:   PetscErrorCode  ierr;
    5175:   static PetscInt inassm = 0;
    5176:   PetscBool       flg    = PETSC_FALSE;

    5182:   inassm++;
    5183:   MatAssemblyEnd_InUse++;
    5184:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
    5185:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
    5186:     if (mat->ops->assemblyend) {
    5187:       (*mat->ops->assemblyend)(mat,type);
    5188:     }
    5189:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
    5190:   } else if (mat->ops->assemblyend) {
    5191:     (*mat->ops->assemblyend)(mat,type);
    5192:   }

    5194:   /* Flush assembly is not a true assembly */
    5195:   if (type != MAT_FLUSH_ASSEMBLY) {
    5196:     mat->assembled = PETSC_TRUE; mat->num_ass++;
    5197:   }
    5198:   mat->insertmode = NOT_SET_VALUES;
    5199:   MatAssemblyEnd_InUse--;
    5200:   PetscObjectStateIncrease((PetscObject)mat);
    5201:   if (!mat->symmetric_eternal) {
    5202:     mat->symmetric_set              = PETSC_FALSE;
    5203:     mat->hermitian_set              = PETSC_FALSE;
    5204:     mat->structurally_symmetric_set = PETSC_FALSE;
    5205:   }
    5206: #if defined(PETSC_HAVE_CUSP)
    5207:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5208:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5209:   }
    5210: #elif defined(PETSC_HAVE_VIENNACL)
    5211:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    5212:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    5213:   }
    5214: #elif defined(PETSC_HAVE_VECCUDA)
    5215:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    5216:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    5217:   }
    5218: #endif
    5219:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
    5220:     MatViewFromOptions(mat,NULL,"-mat_view");

    5222:     if (mat->checksymmetryonassembly) {
    5223:       MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
    5224:       if (flg) {
    5225:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
    5226:       } else {
    5227:         PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
    5228:       }
    5229:     }
    5230:     if (mat->nullsp && mat->checknullspaceonassembly) {
    5231:       MatNullSpaceTest(mat->nullsp,mat,NULL);
    5232:     }
    5233:   }
    5234:   inassm--;
    5235:   return(0);
    5236: }

    5240: /*@
    5241:    MatSetOption - Sets a parameter option for a matrix. Some options
    5242:    may be specific to certain storage formats.  Some options
    5243:    determine how values will be inserted (or added). Sorted,
    5244:    row-oriented input will generally assemble the fastest. The default
    5245:    is row-oriented.

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

    5249:    Input Parameters:
    5250: +  mat - the matrix
    5251: .  option - the option, one of those listed below (and possibly others),
    5252: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

    5254:   Options Describing Matrix Structure:
    5255: +    MAT_SPD - symmetric positive definite
    5256: .    MAT_SYMMETRIC - symmetric in terms of both structure and value
    5257: .    MAT_HERMITIAN - transpose is the complex conjugation
    5258: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
    5259: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
    5260:                             you set to be kept with all future use of the matrix
    5261:                             including after MatAssemblyBegin/End() which could
    5262:                             potentially change the symmetry structure, i.e. you
    5263:                             KNOW the matrix will ALWAYS have the property you set.

    5266:    Options For Use with MatSetValues():
    5267:    Insert a logically dense subblock, which can be
    5268: .    MAT_ROW_ORIENTED - row-oriented (default)

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

    5274:    When (re)assembling a matrix, we can restrict the input for
    5275:    efficiency/debugging purposes.  These options include:
    5276: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
    5277: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
    5278: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
    5279: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
    5280: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
    5281: .    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
    5282:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
    5283:         performance for very large process counts.
    5284: -    MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
    5285:         of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
    5286:         functions, instead sending only neighbor messages.

    5288:    Notes:
    5289:    Except for MAT_UNUSED_NONZERO_LOCATION_ERR and  MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!

    5291:    Some options are relevant only for particular matrix types and
    5292:    are thus ignored by others.  Other options are not supported by
    5293:    certain matrix types and will generate an error message if set.

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

    5299:    MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
    5300:    that would generate a new entry in the nonzero structure is instead
    5301:    ignored.  Thus, if memory has not alredy been allocated for this particular
    5302:    data, then the insertion is ignored. For dense matrices, in which
    5303:    the entire array is allocated, no entries are ever ignored.
    5304:    Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction

    5306:    MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
    5307:    that would generate a new entry in the nonzero structure instead produces
    5308:    an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction

    5310:    MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
    5311:    that would generate a new entry that has not been preallocated will
    5312:    instead produce an error. (Currently supported for AIJ and BAIJ formats
    5313:    only.) This is a useful flag when debugging matrix memory preallocation.
    5314:    If this option is set then the MatAssemblyBegin/End() processes has one less global reduction

    5316:    MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
    5317:    other processors should be dropped, rather than stashed.
    5318:    This is useful if you know that the "owning" processor is also
    5319:    always generating the correct matrix entries, so that PETSc need
    5320:    not transfer duplicate entries generated on another processor.

    5322:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
    5323:    searches during matrix assembly. When this flag is set, the hash table
    5324:    is created during the first Matrix Assembly. This hash table is
    5325:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
    5326:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
    5327:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
    5328:    supported by MATMPIBAIJ format only.

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

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

    5336:    MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types

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

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

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

    5346:    Level: intermediate

    5348:    Concepts: matrices^setting options

    5350: .seealso:  MatOption, Mat

    5352: @*/
    5353: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
    5354: {

    5360:   if (op > 0) {
    5363:   }

    5365:   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);
    5366:   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()");

    5368:   switch (op) {
    5369:   case MAT_NO_OFF_PROC_ENTRIES:
    5370:     mat->nooffprocentries = flg;
    5371:     return(0);
    5372:     break;
    5373:   case MAT_SUBSET_OFF_PROC_ENTRIES:
    5374:     mat->subsetoffprocentries = flg;
    5375:     return(0);
    5376:   case MAT_NO_OFF_PROC_ZERO_ROWS:
    5377:     mat->nooffproczerorows = flg;
    5378:     return(0);
    5379:     break;
    5380:   case MAT_SPD:
    5381:     mat->spd_set = PETSC_TRUE;
    5382:     mat->spd     = flg;
    5383:     if (flg) {
    5384:       mat->symmetric                  = PETSC_TRUE;
    5385:       mat->structurally_symmetric     = PETSC_TRUE;
    5386:       mat->symmetric_set              = PETSC_TRUE;
    5387:       mat->structurally_symmetric_set = PETSC_TRUE;
    5388:     }
    5389:     break;
    5390:   case MAT_SYMMETRIC:
    5391:     mat->symmetric = flg;
    5392:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
    5393:     mat->symmetric_set              = PETSC_TRUE;
    5394:     mat->structurally_symmetric_set = flg;
    5395:     break;
    5396:   case MAT_HERMITIAN:
    5397:     mat->hermitian = flg;
    5398:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
    5399:     mat->hermitian_set              = PETSC_TRUE;
    5400:     mat->structurally_symmetric_set = flg;
    5401:     break;
    5402:   case MAT_STRUCTURALLY_SYMMETRIC:
    5403:     mat->structurally_symmetric     = flg;
    5404:     mat->structurally_symmetric_set = PETSC_TRUE;
    5405:     break;
    5406:   case MAT_SYMMETRY_ETERNAL:
    5407:     mat->symmetric_eternal = flg;
    5408:     break;
    5409:   default:
    5410:     break;
    5411:   }
    5412:   if (mat->ops->setoption) {
    5413:     (*mat->ops->setoption)(mat,op,flg);
    5414:   }
    5415:   return(0);
    5416: }

    5420: /*@
    5421:    MatGetOption - Gets a parameter option that has been set for a matrix.

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

    5425:    Input Parameters:
    5426: +  mat - the matrix
    5427: -  option - the option, this only responds to certain options, check the code for which ones

    5429:    Output Parameter:
    5430: .  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

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

    5434:    Level: intermediate

    5436:    Concepts: matrices^setting options

    5438: .seealso:  MatOption, MatSetOption()

    5440: @*/
    5441: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
    5442: {

    5447:   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);
    5448:   if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");

    5450:   switch (op) {
    5451:   case MAT_NO_OFF_PROC_ENTRIES:
    5452:     *flg = mat->nooffprocentries;
    5453:     break;
    5454:   case MAT_NO_OFF_PROC_ZERO_ROWS:
    5455:     *flg = mat->nooffproczerorows;
    5456:     break;
    5457:   case MAT_SYMMETRIC:
    5458:     *flg = mat->symmetric;
    5459:     break;
    5460:   case MAT_HERMITIAN:
    5461:     *flg = mat->hermitian;
    5462:     break;
    5463:   case MAT_STRUCTURALLY_SYMMETRIC:
    5464:     *flg = mat->structurally_symmetric;
    5465:     break;
    5466:   case MAT_SYMMETRY_ETERNAL:
    5467:     *flg = mat->symmetric_eternal;
    5468:     break;
    5469:   default:
    5470:     break;
    5471:   }
    5472:   return(0);
    5473: }

    5477: /*@
    5478:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
    5479:    this routine retains the old nonzero structure.

    5481:    Logically Collective on Mat

    5483:    Input Parameters:
    5484: .  mat - the matrix

    5486:    Level: intermediate

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

    5491:    Concepts: matrices^zeroing

    5493: .seealso: MatZeroRows()
    5494: @*/
    5495: PetscErrorCode MatZeroEntries(Mat mat)
    5496: {

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

    5507:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
    5508:   (*mat->ops->zeroentries)(mat);
    5509:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
    5510:   PetscObjectStateIncrease((PetscObject)mat);
    5511: #if defined(PETSC_HAVE_CUSP)
    5512:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5513:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5514:   }
    5515: #elif defined(PETSC_HAVE_VIENNACL)
    5516:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    5517:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    5518:   }
    5519: #elif defined(PETSC_HAVE_VECCUDA)
    5520:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    5521:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    5522:   }
    5523: #endif
    5524:   return(0);
    5525: }

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

    5533:    Collective on Mat

    5535:    Input Parameters:
    5536: +  mat - the matrix
    5537: .  numRows - the number of rows to remove
    5538: .  rows - the global row indices
    5539: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
    5540: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
    5541: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

    5560:    Level: intermediate

    5562:    Concepts: matrices^zeroing rows

    5564: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
    5565: @*/
    5566: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
    5567: {

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

    5579:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
    5580:   MatViewFromOptions(mat,NULL,"-mat_view");
    5581:   PetscObjectStateIncrease((PetscObject)mat);
    5582: #if defined(PETSC_HAVE_CUSP)
    5583:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5584:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5585:   }
    5586: #elif defined(PETSC_HAVE_VIENNACL)
    5587:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    5588:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    5589:   }
    5590: #elif defined(PETSC_HAVE_VECCUDA)
    5591:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    5592:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    5593:   }
    5594: #endif
    5595:   return(0);
    5596: }

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

    5604:    Collective on Mat

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

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

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

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

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

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

    5630:    Level: intermediate

    5632:    Concepts: matrices^zeroing rows

    5634: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
    5635: @*/
    5636: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    5637: {
    5639:   PetscInt       numRows;
    5640:   const PetscInt *rows;

    5647:   ISGetLocalSize(is,&numRows);
    5648:   ISGetIndices(is,&rows);
    5649:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
    5650:   ISRestoreIndices(is,&rows);
    5651:   return(0);
    5652: }

    5656: /*@C
    5657:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
    5658:    of a set of rows of a matrix.

    5660:    Collective on Mat

    5662:    Input Parameters:
    5663: +  mat - the matrix
    5664: .  numRows - the number of rows to remove
    5665: .  rows - the global row indices
    5666: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
    5667: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
    5668: -  b - optional vector of right hand side, that will be adjusted by provided solution

    5670:    Notes:
    5671:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5672:    but does not release memory.  For the dense and block diagonal
    5673:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5694:    Level: intermediate

    5696:    Concepts: matrices^zeroing rows

    5698: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5699: @*/
    5700: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
    5701: {

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

    5713:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
    5714:   MatViewFromOptions(mat,NULL,"-mat_view");
    5715:   PetscObjectStateIncrease((PetscObject)mat);
    5716: #if defined(PETSC_HAVE_CUSP)
    5717:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    5718:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    5719:   }
    5720: #elif defined(PETSC_HAVE_VIENNACL)
    5721:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    5722:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    5723:   }
    5724: #elif defined(PETSC_HAVE_VECCUDA)
    5725:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    5726:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    5727:   }
    5728: #endif
    5729:   return(0);
    5730: }

    5734: /*@C
    5735:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
    5736:    of a set of rows of a matrix.

    5738:    Collective on Mat

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

    5747:    Notes:
    5748:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5749:    but does not release memory.  For the dense and block diagonal
    5750:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5771:    Level: intermediate

    5773:    Concepts: matrices^zeroing rows

    5775: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5776: @*/
    5777: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    5778: {
    5779:   PetscInt       numRows;
    5780:   const PetscInt *rows;

    5787:   ISGetLocalSize(is,&numRows);
    5788:   ISGetIndices(is,&rows);
    5789:   MatZeroRows(mat,numRows,rows,diag,x,b);
    5790:   ISRestoreIndices(is,&rows);
    5791:   return(0);
    5792: }

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

    5800:    Collective on Mat

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

    5810:    Notes:
    5811:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5812:    but does not release memory.  For the dense and block diagonal
    5813:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5833:    In Fortran idxm and idxn should be declared as
    5834: $     MatStencil idxm(4,m)
    5835:    and the values inserted using
    5836: $    idxm(MatStencil_i,1) = i
    5837: $    idxm(MatStencil_j,1) = j
    5838: $    idxm(MatStencil_k,1) = k
    5839: $    idxm(MatStencil_c,1) = c
    5840:    etc

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

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

    5850:    Level: intermediate

    5852:    Concepts: matrices^zeroing rows

    5854: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5855: @*/
    5856: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
    5857: {
    5858:   PetscInt       dim     = mat->stencil.dim;
    5859:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
    5860:   PetscInt       *dims   = mat->stencil.dims+1;
    5861:   PetscInt       *starts = mat->stencil.starts;
    5862:   PetscInt       *dxm    = (PetscInt*) rows;
    5863:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;

    5871:   PetscMalloc1(numRows, &jdxm);
    5872:   for (i = 0; i < numRows; ++i) {
    5873:     /* Skip unused dimensions (they are ordered k, j, i, c) */
    5874:     for (j = 0; j < 3-sdim; ++j) dxm++;
    5875:     /* Local index in X dir */
    5876:     tmp = *dxm++ - starts[0];
    5877:     /* Loop over remaining dimensions */
    5878:     for (j = 0; j < dim-1; ++j) {
    5879:       /* If nonlocal, set index to be negative */
    5880:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
    5881:       /* Update local index */
    5882:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
    5883:     }
    5884:     /* Skip component slot if necessary */
    5885:     if (mat->stencil.noc) dxm++;
    5886:     /* Local row number */
    5887:     if (tmp >= 0) {
    5888:       jdxm[numNewRows++] = tmp;
    5889:     }
    5890:   }
    5891:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
    5892:   PetscFree(jdxm);
    5893:   return(0);
    5894: }

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

    5902:    Collective on Mat

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

    5912:    Notes:
    5913:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
    5914:    but does not release memory.  For the dense and block diagonal
    5915:    formats this does not alter the nonzero structure.

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

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

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

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

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

    5935:    In Fortran idxm and idxn should be declared as
    5936: $     MatStencil idxm(4,m)
    5937:    and the values inserted using
    5938: $    idxm(MatStencil_i,1) = i
    5939: $    idxm(MatStencil_j,1) = j
    5940: $    idxm(MatStencil_k,1) = k
    5941: $    idxm(MatStencil_c,1) = c
    5942:    etc

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

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

    5952:    Level: intermediate

    5954:    Concepts: matrices^zeroing rows

    5956: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
    5957: @*/
    5958: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
    5959: {
    5960:   PetscInt       dim     = mat->stencil.dim;
    5961:   PetscInt       sdim    = dim - (1 - (PetscInt) mat->stencil.noc);
    5962:   PetscInt       *dims   = mat->stencil.dims+1;
    5963:   PetscInt       *starts = mat->stencil.starts;
    5964:   PetscInt       *dxm    = (PetscInt*) rows;
    5965:   PetscInt       *jdxm, i, j, tmp, numNewRows = 0;

    5973:   PetscMalloc1(numRows, &jdxm);
    5974:   for (i = 0; i < numRows; ++i) {
    5975:     /* Skip unused dimensions (they are ordered k, j, i, c) */
    5976:     for (j = 0; j < 3-sdim; ++j) dxm++;
    5977:     /* Local index in X dir */
    5978:     tmp = *dxm++ - starts[0];
    5979:     /* Loop over remaining dimensions */
    5980:     for (j = 0; j < dim-1; ++j) {
    5981:       /* If nonlocal, set index to be negative */
    5982:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
    5983:       /* Update local index */
    5984:       else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
    5985:     }
    5986:     /* Skip component slot if necessary */
    5987:     if (mat->stencil.noc) dxm++;
    5988:     /* Local row number */
    5989:     if (tmp >= 0) {
    5990:       jdxm[numNewRows++] = tmp;
    5991:     }
    5992:   }
    5993:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
    5994:   PetscFree(jdxm);
    5995:   return(0);
    5996: }

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

    6004:    Collective on Mat

    6006:    Input Parameters:
    6007: +  mat - the matrix
    6008: .  numRows - the number of rows to remove
    6009: .  rows - the global row indices
    6010: .  diag - value put in all diagonals of eliminated rows
    6011: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
    6012: -  b - optional vector of right hand side, that will be adjusted by provided solution

    6014:    Notes:
    6015:    Before calling MatZeroRowsLocal(), the user must first set the
    6016:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

    6018:    For the AIJ matrix formats this removes the old nonzero structure,
    6019:    but does not release memory.  For the dense and block diagonal
    6020:    formats this does not alter the nonzero structure.

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

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

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

    6033:    Level: intermediate

    6035:    Concepts: matrices^zeroing

    6037: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    6038: @*/
    6039: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
    6040: {

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

    6051:   if (mat->ops->zerorowslocal) {
    6052:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
    6053:   } else {
    6054:     IS             is, newis;
    6055:     const PetscInt *newRows;

    6057:     if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
    6058:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
    6059:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
    6060:     ISGetIndices(newis,&newRows);
    6061:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
    6062:     ISRestoreIndices(newis,&newRows);
    6063:     ISDestroy(&newis);
    6064:     ISDestroy(&is);
    6065:   }
    6066:   PetscObjectStateIncrease((PetscObject)mat);
    6067: #if defined(PETSC_HAVE_CUSP)
    6068:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    6069:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    6070:   }
    6071: #elif defined(PETSC_HAVE_VIENNACL)
    6072:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    6073:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    6074:   }
    6075: #elif defined(PETSC_HAVE_VECCUDA)
    6076:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    6077:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    6078:   }
    6079: #endif
    6080:   return(0);
    6081: }

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

    6089:    Collective on Mat

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

    6098:    Notes:
    6099:    Before calling MatZeroRowsLocalIS(), the user must first set the
    6100:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

    6102:    For the AIJ matrix formats this removes the old nonzero structure,
    6103:    but does not release memory.  For the dense and block diagonal
    6104:    formats this does not alter the nonzero structure.

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

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

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

    6117:    Level: intermediate

    6119:    Concepts: matrices^zeroing

    6121: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    6122: @*/
    6123: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    6124: {
    6126:   PetscInt       numRows;
    6127:   const PetscInt *rows;

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

    6137:   ISGetLocalSize(is,&numRows);
    6138:   ISGetIndices(is,&rows);
    6139:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
    6140:   ISRestoreIndices(is,&rows);
    6141:   return(0);
    6142: }

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

    6150:    Collective on Mat

    6152:    Input Parameters:
    6153: +  mat - the matrix
    6154: .  numRows - the number of rows to remove
    6155: .  rows - the global row indices
    6156: .  diag - value put in all diagonals of eliminated rows
    6157: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
    6158: -  b - optional vector of right hand side, that will be adjusted by provided solution

    6160:    Notes:
    6161:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
    6162:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

    6168:    Level: intermediate

    6170:    Concepts: matrices^zeroing

    6172: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    6173: @*/
    6174: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
    6175: {
    6177:   IS             is, newis;
    6178:   const PetscInt *newRows;

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

    6188:   if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
    6189:   ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
    6190:   ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
    6191:   ISGetIndices(newis,&newRows);
    6192:   (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
    6193:   ISRestoreIndices(newis,&newRows);
    6194:   ISDestroy(&newis);
    6195:   ISDestroy(&is);
    6196:   PetscObjectStateIncrease((PetscObject)mat);
    6197: #if defined(PETSC_HAVE_CUSP)
    6198:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
    6199:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
    6200:   }
    6201: #elif defined(PETSC_HAVE_VIENNACL)
    6202:   if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
    6203:     mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
    6204:   }
    6205: #elif defined(PETSC_HAVE_VECCUDA)
    6206:   if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
    6207:     mat->valid_GPU_matrix = PETSC_CUDA_CPU;
    6208:   }
    6209: #endif
    6210:   return(0);
    6211: }

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

    6219:    Collective on Mat

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

    6228:    Notes:
    6229:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
    6230:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

    6236:    Level: intermediate

    6238:    Concepts: matrices^zeroing

    6240: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
    6241: @*/
    6242: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
    6243: {
    6245:   PetscInt       numRows;
    6246:   const PetscInt *rows;

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

    6256:   ISGetLocalSize(is,&numRows);
    6257:   ISGetIndices(is,&rows);
    6258:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
    6259:   ISRestoreIndices(is,&rows);
    6260:   return(0);
    6261: }

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

    6268:    Not Collective

    6270:    Input Parameter:
    6271: .  mat - the matrix

    6273:    Output Parameters:
    6274: +  m - the number of global rows
    6275: -  n - the number of global columns

    6277:    Note: both output parameters can be NULL on input.

    6279:    Level: beginner

    6281:    Concepts: matrices^size

    6283: .seealso: MatGetLocalSize()
    6284: @*/
    6285: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
    6286: {
    6289:   if (m) *m = mat->rmap->N;
    6290:   if (n) *n = mat->cmap->N;
    6291:   return(0);
    6292: }

    6296: /*@
    6297:    MatGetLocalSize - Returns the number of rows and columns in a matrix
    6298:    stored locally.  This information may be implementation dependent, so
    6299:    use with care.

    6301:    Not Collective

    6303:    Input Parameters:
    6304: .  mat - the matrix

    6306:    Output Parameters:
    6307: +  m - the number of local rows
    6308: -  n - the number of local columns

    6310:    Note: both output parameters can be NULL on input.

    6312:    Level: beginner

    6314:    Concepts: matrices^local size

    6316: .seealso: MatGetSize()
    6317: @*/
    6318: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
    6319: {
    6324:   if (m) *m = mat->rmap->n;
    6325:   if (n) *n = mat->cmap->n;
    6326:   return(0);
    6327: }

    6331: /*@
    6332:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
    6333:    this processor. (The columns of the "diagonal block")

    6335:    Not Collective, unless matrix has not been allocated, then collective on Mat

    6337:    Input Parameters:
    6338: .  mat - the matrix

    6340:    Output Parameters:
    6341: +  m - the global index of the first local column
    6342: -  n - one more than the global index of the last local column

    6344:    Notes: both output parameters can be NULL on input.

    6346:    Level: developer

    6348:    Concepts: matrices^column ownership

    6350: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

    6352: @*/
    6353: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
    6354: {
    6360:   MatCheckPreallocated(mat,1);
    6361:   if (m) *m = mat->cmap->rstart;
    6362:   if (n) *n = mat->cmap->rend;
    6363:   return(0);
    6364: }

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

    6374:    Not Collective

    6376:    Input Parameters:
    6377: .  mat - the matrix

    6379:    Output Parameters:
    6380: +  m - the global index of the first local row
    6381: -  n - one more than the global index of the last local row

    6383:    Note: Both output parameters can be NULL on input.
    6384: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
    6385: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
    6386: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

    6388:    Level: beginner

    6390:    Concepts: matrices^row ownership

    6392: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

    6394: @*/
    6395: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
    6396: {
    6402:   MatCheckPreallocated(mat,1);
    6403:   if (m) *m = mat->rmap->rstart;
    6404:   if (n) *n = mat->rmap->rend;
    6405:   return(0);
    6406: }

    6410: /*@C
    6411:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
    6412:    each process

    6414:    Not Collective, unless matrix has not been allocated, then collective on Mat

    6416:    Input Parameters:
    6417: .  mat - the matrix

    6419:    Output Parameters:
    6420: .  ranges - start of each processors portion plus one more than the total length at the end

    6422:    Level: beginner

    6424:    Concepts: matrices^row ownership

    6426: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

    6428: @*/
    6429: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
    6430: {

    6436:   MatCheckPreallocated(mat,1);
    6437:   PetscLayoutGetRanges(mat->rmap,ranges);
    6438:   return(0);
    6439: }

    6443: /*@C
    6444:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
    6445:    this processor. (The columns of the "diagonal blocks" for each process)

    6447:    Not Collective, unless matrix has not been allocated, then collective on Mat

    6449:    Input Parameters:
    6450: .  mat - the matrix

    6452:    Output Parameters:
    6453: .  ranges - start of each processors portion plus one more then the total length at the end

    6455:    Level: beginner

    6457:    Concepts: matrices^column ownership

    6459: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

    6461: @*/
    6462: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
    6463: {

    6469:   MatCheckPreallocated(mat,1);
    6470:   PetscLayoutGetRanges(mat->cmap,ranges);
    6471:   return(0);
    6472: }

    6476: /*@C
    6477:    MatGetOwnershipIS - Get row and column ownership as index sets

    6479:    Not Collective

    6481:    Input Arguments:
    6482: .  A - matrix of type Elemental

    6484:    Output Arguments:
    6485: +  rows - rows in which this process owns elements
    6486: .  cols - columns in which this process owns elements

    6488:    Level: intermediate

    6490: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
    6491: @*/
    6492: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
    6493: {
    6494:   PetscErrorCode ierr,(*f)(Mat,IS*,IS*);

    6497:   MatCheckPreallocated(A,1);
    6498:   PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
    6499:   if (f) {
    6500:     (*f)(A,rows,cols);
    6501:   } else {   /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
    6502:     if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
    6503:     if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
    6504:   }
    6505:   return(0);
    6506: }

    6510: /*@C
    6511:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
    6512:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
    6513:    to complete the factorization.

    6515:    Collective on Mat

    6517:    Input Parameters:
    6518: +  mat - the matrix
    6519: .  row - row permutation
    6520: .  column - column permutation
    6521: -  info - structure containing
    6522: $      levels - number of levels of fill.
    6523: $      expected fill - as ratio of original fill.
    6524: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
    6525:                 missing diagonal entries)

    6527:    Output Parameters:
    6528: .  fact - new matrix that has been symbolically factored

    6530:    Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.

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

    6536:    Level: developer

    6538:   Concepts: matrices^symbolic LU factorization
    6539:   Concepts: matrices^factorization
    6540:   Concepts: LU^symbolic factorization

    6542: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
    6543:           MatGetOrdering(), MatFactorInfo

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

    6548: @*/
    6549: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
    6550: {

    6560:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
    6561:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
    6562:   if (!(fact)->ops->ilufactorsymbolic) {
    6563:     const MatSolverPackage spackage;
    6564:     MatFactorGetSolverPackage(fact,&spackage);
    6565:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
    6566:   }
    6567:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6568:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6569:   MatCheckPreallocated(mat,2);

    6571:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
    6572:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
    6573:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
    6574:   return(0);
    6575: }

    6579: /*@C
    6580:    MatICCFactorSymbolic - Performs symbolic incomplete
    6581:    Cholesky factorization for a symmetric matrix.  Use
    6582:    MatCholeskyFactorNumeric() to complete the factorization.

    6584:    Collective on Mat

    6586:    Input Parameters:
    6587: +  mat - the matrix
    6588: .  perm - row and column permutation
    6589: -  info - structure containing
    6590: $      levels - number of levels of fill.
    6591: $      expected fill - as ratio of original fill.

    6593:    Output Parameter:
    6594: .  fact - the factored matrix

    6596:    Notes:
    6597:    Most users should employ the KSP interface for linear solvers
    6598:    instead of working directly with matrix algebra routines such as this.
    6599:    See, e.g., KSPCreate().

    6601:    Level: developer

    6603:   Concepts: matrices^symbolic incomplete Cholesky factorization
    6604:   Concepts: matrices^factorization
    6605:   Concepts: Cholsky^symbolic factorization

    6607: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

    6612: @*/
    6613: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
    6614: {

    6623:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6624:   if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
    6625:   if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
    6626:   if (!(fact)->ops->iccfactorsymbolic) {
    6627:     const MatSolverPackage spackage;
    6628:     MatFactorGetSolverPackage(fact,&spackage);
    6629:     SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
    6630:   }
    6631:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6632:   MatCheckPreallocated(mat,2);

    6634:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
    6635:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
    6636:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
    6637:   return(0);
    6638: }

    6642: /*@C
    6643:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
    6644:    points to an array of valid matrices, they may be reused to store the new
    6645:    submatrices.

    6647:    Collective on Mat

    6649:    Input Parameters:
    6650: +  mat - the matrix
    6651: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
    6652: .  irow, icol - index sets of rows and columns to extract
    6653: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    6655:    Output Parameter:
    6656: .  submat - the array of submatrices

    6658:    Notes:
    6659:    MatGetSubMatrices() can extract ONLY sequential submatrices
    6660:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
    6661:    to extract a parallel submatrix.

    6663:    Some matrix types place restrictions on the row and column
    6664:    indices, such as that they be sorted or that they be equal to each other.

    6666:    The index sets may not have duplicate entries.

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

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

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

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

    6681:    For BAIJ matrices the index sets must respect the block structure, that is if they
    6682:    request one row/column in a block, they must request all rows/columns that are in
    6683:    that block. For example, if the block size is 2 you cannot request just row 0 and
    6684:    column 0.

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

    6690:    Level: advanced

    6692:    Concepts: matrices^accessing submatrices
    6693:    Concepts: submatrices

    6695: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
    6696: @*/
    6697: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
    6698: {
    6700:   PetscInt       i;
    6701:   PetscBool      eq;

    6706:   if (n) {
    6711:   }
    6713:   if (n && scall == MAT_REUSE_MATRIX) {
    6716:   }
    6717:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    6718:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6719:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6720:   MatCheckPreallocated(mat,1);

    6722:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
    6723:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
    6724:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
    6725:   for (i=0; i<n; i++) {
    6726:     (*submat)[i]->factortype = MAT_FACTOR_NONE;  /* in case in place factorization was previously done on submatrix */
    6727:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
    6728:       ISEqual(irow[i],icol[i],&eq);
    6729:       if (eq) {
    6730:         if (mat->symmetric) {
    6731:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
    6732:         } else if (mat->hermitian) {
    6733:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
    6734:         } else if (mat->structurally_symmetric) {
    6735:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
    6736:         }
    6737:       }
    6738:     }
    6739:   }
    6740:   return(0);
    6741: }

    6745: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
    6746: {
    6748:   PetscInt       i;
    6749:   PetscBool      eq;

    6754:   if (n) {
    6759:   }
    6761:   if (n && scall == MAT_REUSE_MATRIX) {
    6764:   }
    6765:   if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    6766:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6767:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6768:   MatCheckPreallocated(mat,1);

    6770:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
    6771:   (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
    6772:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
    6773:   for (i=0; i<n; i++) {
    6774:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
    6775:       ISEqual(irow[i],icol[i],&eq);
    6776:       if (eq) {
    6777:         if (mat->symmetric) {
    6778:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
    6779:         } else if (mat->hermitian) {
    6780:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
    6781:         } else if (mat->structurally_symmetric) {
    6782:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
    6783:         }
    6784:       }
    6785:     }
    6786:   }
    6787:   return(0);
    6788: }

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

    6795:    Collective on Mat

    6797:    Input Parameters:
    6798: +  n - the number of local matrices
    6799: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
    6800:                        sequence of MatGetSubMatrices())

    6802:    Level: advanced

    6804:     Notes: Frees not only the matrices, but also the array that contains the matrices
    6805:            In Fortran will not free the array.

    6807: .seealso: MatGetSubMatrices()
    6808: @*/
    6809: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
    6810: {
    6812:   PetscInt       i;

    6815:   if (!*mat) return(0);
    6816:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
    6818:   for (i=0; i<n; i++) {
    6819:     MatDestroy(&(*mat)[i]);
    6820:   }
    6821:   /* memory is allocated even if n = 0 */
    6822:   PetscFree(*mat);
    6823:   *mat = NULL;
    6824:   return(0);
    6825: }

    6829: /*@C
    6830:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.

    6832:    Collective on Mat

    6834:    Input Parameters:
    6835: .  mat - the matrix

    6837:    Output Parameter:
    6838: .  matstruct - the sequential matrix with the nonzero structure of mat

    6840:   Level: intermediate

    6842: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
    6843: @*/
    6844: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
    6845: {

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

    6856:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
    6857:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
    6858:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
    6859:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
    6860:   return(0);
    6861: }

    6865: /*@C
    6866:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

    6868:    Collective on Mat

    6870:    Input Parameters:
    6871: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
    6872:                        sequence of MatGetSequentialNonzeroStructure())

    6874:    Level: advanced

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

    6878: .seealso: MatGetSeqNonzeroStructure()
    6879: @*/
    6880: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
    6881: {

    6886:   MatDestroy(mat);
    6887:   return(0);
    6888: }

    6892: /*@
    6893:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
    6894:    replaces the index sets by larger ones that represent submatrices with
    6895:    additional overlap.

    6897:    Collective on Mat

    6899:    Input Parameters:
    6900: +  mat - the matrix
    6901: .  n   - the number of index sets
    6902: .  is  - the array of index sets (these index sets will changed during the call)
    6903: -  ov  - the additional overlap requested

    6905:    Options Database:
    6906: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

    6908:    Level: developer

    6910:    Concepts: overlap
    6911:    Concepts: ASM^computing overlap

    6913: .seealso: MatGetSubMatrices()
    6914: @*/
    6915: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
    6916: {

    6922:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
    6923:   if (n) {
    6926:   }
    6927:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6928:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6929:   MatCheckPreallocated(mat,1);

    6931:   if (!ov) return(0);
    6932:   if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    6933:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
    6934:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
    6935:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
    6936:   return(0);
    6937: }

    6940: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);

    6944: /*@
    6945:    MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
    6946:    a sub communicator, replaces the index sets by larger ones that represent submatrices with
    6947:    additional overlap.

    6949:    Collective on Mat

    6951:    Input Parameters:
    6952: +  mat - the matrix
    6953: .  n   - the number of index sets
    6954: .  is  - the array of index sets (these index sets will changed during the call)
    6955: -  ov  - the additional overlap requested

    6957:    Options Database:
    6958: .  -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)

    6960:    Level: developer

    6962:    Concepts: overlap
    6963:    Concepts: ASM^computing overlap

    6965: .seealso: MatGetSubMatrices()
    6966: @*/
    6967: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
    6968: {
    6969:   PetscInt       i;

    6975:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
    6976:   if (n) {
    6979:   }
    6980:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    6981:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    6982:   MatCheckPreallocated(mat,1);
    6983:   if (!ov) return(0);
    6984:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
    6985:   for(i=0; i<n; i++){
    6986:          MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
    6987:   }
    6988:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
    6989:   return(0);
    6990: }

    6997: /*@
    6998:    MatGetBlockSize - Returns the matrix block size.

    7000:    Not Collective

    7002:    Input Parameter:
    7003: .  mat - the matrix

    7005:    Output Parameter:
    7006: .  bs - block size

    7008:    Notes:
    7009:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

    7011:    If the block size has not been set yet this routine returns 1.

    7013:    Level: intermediate

    7015:    Concepts: matrices^block size

    7017: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
    7018: @*/
    7019: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
    7020: {
    7024:   *bs = PetscAbs(mat->rmap->bs);
    7025:   return(0);
    7026: }

    7030: /*@
    7031:    MatGetBlockSizes - Returns the matrix block row and column sizes.

    7033:    Not Collective

    7035:    Input Parameter:
    7036: .  mat - the matrix

    7038:    Output Parameter:
    7039: .  rbs - row block size
    7040: .  cbs - coumn block size

    7042:    Notes:
    7043:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
    7044:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

    7046:    If a block size has not been set yet this routine returns 1.

    7048:    Level: intermediate

    7050:    Concepts: matrices^block size

    7052: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
    7053: @*/
    7054: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
    7055: {
    7060:   if (rbs) *rbs = PetscAbs(mat->rmap->bs);
    7061:   if (cbs) *cbs = PetscAbs(mat->cmap->bs);
    7062:   return(0);
    7063: }

    7067: /*@
    7068:    MatSetBlockSize - Sets the matrix block size.

    7070:    Logically Collective on Mat

    7072:    Input Parameters:
    7073: +  mat - the matrix
    7074: -  bs - block size

    7076:    Notes:
    7077:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.

    7079:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

    7081:    Level: intermediate

    7083:    Concepts: matrices^block size

    7085: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
    7086: @*/
    7087: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
    7088: {

    7094:   PetscLayoutSetBlockSize(mat->rmap,bs);
    7095:   PetscLayoutSetBlockSize(mat->cmap,bs);
    7096:   return(0);
    7097: }

    7101: /*@
    7102:    MatSetBlockSizes - Sets the matrix block row and column sizes.

    7104:    Logically Collective on Mat

    7106:    Input Parameters:
    7107: +  mat - the matrix
    7108: -  rbs - row block size
    7109: -  cbs - column block size

    7111:    Notes:
    7112:     Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
    7113:     If you pass a different block size for the columns than the rows, the row block size determines the square block storage.

    7115:     This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

    7117:     The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().

    7119:    Level: intermediate

    7121:    Concepts: matrices^block size

    7123: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
    7124: @*/
    7125: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
    7126: {

    7133:   PetscLayoutSetBlockSize(mat->rmap,rbs);
    7134:   PetscLayoutSetBlockSize(mat->cmap,cbs);
    7135:   return(0);
    7136: }

    7140: /*@
    7141:    MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices

    7143:    Logically Collective on Mat

    7145:    Input Parameters:
    7146: +  mat - the matrix
    7147: .  fromRow - matrix from which to copy row block size
    7148: -  fromCol - matrix from which to copy column block size (can be same as fromRow)

    7150:    Level: developer

    7152:    Concepts: matrices^block size

    7154: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
    7155: @*/
    7156: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
    7157: {

    7164:   if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
    7165:   if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
    7166:   return(0);
    7167: }

    7171: /*@
    7172:    MatResidual - Default routine to calculate the residual.

    7174:    Collective on Mat and Vec

    7176:    Input Parameters:
    7177: +  mat - the matrix
    7178: .  b   - the right-hand-side
    7179: -  x   - the approximate solution

    7181:    Output Parameter:
    7182: .  r - location to store the residual

    7184:    Level: developer

    7186: .keywords: MG, default, multigrid, residual

    7188: .seealso: PCMGSetResidual()
    7189: @*/
    7190: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
    7191: {

    7200:   MatCheckPreallocated(mat,1);
    7201:   PetscLogEventBegin(MAT_Residual,mat,0,0,0);
    7202:   if (!mat->ops->residual) {
    7203:     MatMult(mat,x,r);
    7204:     VecAYPX(r,-1.0,b);
    7205:   } else {
    7206:     (*mat->ops->residual)(mat,b,x,r);
    7207:   }
    7208:   PetscLogEventEnd(MAT_Residual,mat,0,0,0);
    7209:   return(0);
    7210: }

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

    7217:    Collective on Mat

    7219:     Input Parameters:
    7220: +   mat - the matrix
    7221: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
    7222: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
    7223: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
    7224:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    7225:                  always used.

    7227:     Output Parameters:
    7228: +   n - number of rows in the (possibly compressed) matrix
    7229: .   ia - the row pointers [of length n+1]
    7230: .   ja - the column indices
    7231: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
    7232:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

    7234:     Level: developer

    7236:     Notes: You CANNOT change any of the ia[] or ja[] values.

    7238:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

    7240:     Fortran Node

    7242:            In Fortran use
    7243: $           PetscInt ia(1), ja(1)
    7244: $           PetscOffset iia, jja
    7245: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
    7246: $      Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
    7247: $
    7248: $          or
    7249: $
    7250: $           PetscInt, pointer :: ia(:),ja(:)
    7251: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
    7252: $      Acess the ith and jth entries via ia(i) and ja(j)

    7256: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
    7257: @*/
    7258: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    7259: {

    7269:   MatCheckPreallocated(mat,1);
    7270:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
    7271:   else {
    7272:     *done = PETSC_TRUE;
    7273:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
    7274:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    7275:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
    7276:   }
    7277:   return(0);
    7278: }

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

    7285:     Collective on Mat

    7287:     Input Parameters:
    7288: +   mat - the matrix
    7289: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
    7290: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
    7291:                 symmetrized
    7292: .   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
    7293:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    7294:                  always used.
    7295: .   n - number of columns in the (possibly compressed) matrix
    7296: .   ia - the column pointers
    7297: -   ja - the row indices

    7299:     Output Parameters:
    7300: .   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

    7302:     Note:
    7303:     This routine zeros out n, ia, and ja. This is to prevent accidental
    7304:     us of the array after it has been restored. If you pass NULL, it will
    7305:     not zero the pointers.  Use of ia or ja after MatRestoreColumnIJ() is invalid.

    7307:     Level: developer

    7309: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
    7310: @*/
    7311: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    7312: {

    7322:   MatCheckPreallocated(mat,1);
    7323:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
    7324:   else {
    7325:     *done = PETSC_TRUE;
    7326:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    7327:   }
    7328:   return(0);
    7329: }

    7333: /*@C
    7334:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
    7335:     MatGetRowIJ().

    7337:     Collective on Mat

    7339:     Input Parameters:
    7340: +   mat - the matrix
    7341: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
    7342: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
    7343:                 symmetrized
    7344: .   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
    7345:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    7346:                  always used.
    7347: .   n - size of (possibly compressed) matrix
    7348: .   ia - the row pointers
    7349: -   ja - the column indices

    7351:     Output Parameters:
    7352: .   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

    7354:     Note:
    7355:     This routine zeros out n, ia, and ja. This is to prevent accidental
    7356:     us of the array after it has been restored. If you pass NULL, it will
    7357:     not zero the pointers.  Use of ia or ja after MatRestoreRowIJ() is invalid.

    7359:     Level: developer

    7361: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
    7362: @*/
    7363: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    7364: {

    7373:   MatCheckPreallocated(mat,1);

    7375:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
    7376:   else {
    7377:     *done = PETSC_TRUE;
    7378:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    7379:     if (n)  *n = 0;
    7380:     if (ia) *ia = NULL;
    7381:     if (ja) *ja = NULL;
    7382:   }
    7383:   return(0);
    7384: }

    7388: /*@C
    7389:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
    7390:     MatGetColumnIJ().

    7392:     Collective on Mat

    7394:     Input Parameters:
    7395: +   mat - the matrix
    7396: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
    7397: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
    7398:                 symmetrized
    7399: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
    7400:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
    7401:                  always used.

    7403:     Output Parameters:
    7404: +   n - size of (possibly compressed) matrix
    7405: .   ia - the column pointers
    7406: .   ja - the row indices
    7407: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

    7409:     Level: developer

    7411: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
    7412: @*/
    7413: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool  *done)
    7414: {

    7423:   MatCheckPreallocated(mat,1);

    7425:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
    7426:   else {
    7427:     *done = PETSC_TRUE;
    7428:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
    7429:     if (n)  *n = 0;
    7430:     if (ia) *ia = NULL;
    7431:     if (ja) *ja = NULL;
    7432:   }
    7433:   return(0);
    7434: }

    7438: /*@C
    7439:     MatColoringPatch -Used inside matrix coloring routines that
    7440:     use MatGetRowIJ() and/or MatGetColumnIJ().

    7442:     Collective on Mat

    7444:     Input Parameters:
    7445: +   mat - the matrix
    7446: .   ncolors - max color value
    7447: .   n   - number of entries in colorarray
    7448: -   colorarray - array indicating color for each column

    7450:     Output Parameters:
    7451: .   iscoloring - coloring generated using colorarray information

    7453:     Level: developer

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

    7457: @*/
    7458: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
    7459: {

    7467:   MatCheckPreallocated(mat,1);

    7469:   if (!mat->ops->coloringpatch) {
    7470:     ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
    7471:   } else {
    7472:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
    7473:   }
    7474:   return(0);
    7475: }

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

    7483:    Logically Collective on Mat

    7485:    Input Parameter:
    7486: .  mat - the factored matrix to be reset

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

    7495:    Note that one can specify in-place ILU(0) factorization by calling
    7496: .vb
    7497:      PCType(pc,PCILU);
    7498:      PCFactorSeUseInPlace(pc);
    7499: .ve
    7500:    or by using the options -pc_type ilu -pc_factor_in_place

    7502:    In-place factorization ILU(0) can also be used as a local
    7503:    solver for the blocks within the block Jacobi or additive Schwarz
    7504:    methods (runtime option: -sub_pc_factor_in_place).  See Users-Manual: ch_pc
    7505:    for details on setting local solver options.

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

    7511:    Level: developer

    7513: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()

    7515:    Concepts: matrices^unfactored

    7517: @*/
    7518: PetscErrorCode MatSetUnfactored(Mat mat)
    7519: {

    7525:   MatCheckPreallocated(mat,1);
    7526:   mat->factortype = MAT_FACTOR_NONE;
    7527:   if (!mat->ops->setunfactored) return(0);
    7528:   (*mat->ops->setunfactored)(mat);
    7529:   return(0);
    7530: }

    7532: /*MC
    7533:     MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.

    7535:     Synopsis:
    7536:     MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

    7538:     Not collective

    7540:     Input Parameter:
    7541: .   x - matrix

    7543:     Output Parameters:
    7544: +   xx_v - the Fortran90 pointer to the array
    7545: -   ierr - error code

    7547:     Example of Usage:
    7548: .vb
    7549:       PetscScalar, pointer xx_v(:,:)
    7550:       ....
    7551:       call MatDenseGetArrayF90(x,xx_v,ierr)
    7552:       a = xx_v(3)
    7553:       call MatDenseRestoreArrayF90(x,xx_v,ierr)
    7554: .ve

    7556:     Level: advanced

    7558: .seealso:  MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()

    7560:     Concepts: matrices^accessing array

    7562: M*/

    7564: /*MC
    7565:     MatDenseRestoreArrayF90 - Restores a matrix array that has been
    7566:     accessed with MatDenseGetArrayF90().

    7568:     Synopsis:
    7569:     MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

    7571:     Not collective

    7573:     Input Parameters:
    7574: +   x - matrix
    7575: -   xx_v - the Fortran90 pointer to the array

    7577:     Output Parameter:
    7578: .   ierr - error code

    7580:     Example of Usage:
    7581: .vb
    7582:        PetscScalar, pointer xx_v(:,:)
    7583:        ....
    7584:        call MatDenseGetArrayF90(x,xx_v,ierr)
    7585:        a = xx_v(3)
    7586:        call MatDenseRestoreArrayF90(x,xx_v,ierr)
    7587: .ve

    7589:     Level: advanced

    7591: .seealso:  MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()

    7593: M*/

    7596: /*MC
    7597:     MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.

    7599:     Synopsis:
    7600:     MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

    7602:     Not collective

    7604:     Input Parameter:
    7605: .   x - matrix

    7607:     Output Parameters:
    7608: +   xx_v - the Fortran90 pointer to the array
    7609: -   ierr - error code

    7611:     Example of Usage:
    7612: .vb
    7613:       PetscScalar, pointer xx_v(:)
    7614:       ....
    7615:       call MatSeqAIJGetArrayF90(x,xx_v,ierr)
    7616:       a = xx_v(3)
    7617:       call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
    7618: .ve

    7620:     Level: advanced

    7622: .seealso:  MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()

    7624:     Concepts: matrices^accessing array

    7626: M*/

    7628: /*MC
    7629:     MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
    7630:     accessed with MatSeqAIJGetArrayF90().

    7632:     Synopsis:
    7633:     MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

    7635:     Not collective

    7637:     Input Parameters:
    7638: +   x - matrix
    7639: -   xx_v - the Fortran90 pointer to the array

    7641:     Output Parameter:
    7642: .   ierr - error code

    7644:     Example of Usage:
    7645: .vb
    7646:        PetscScalar, pointer xx_v(:)
    7647:        ....
    7648:        call MatSeqAIJGetArrayF90(x,xx_v,ierr)
    7649:        a = xx_v(3)
    7650:        call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
    7651: .ve

    7653:     Level: advanced

    7655: .seealso:  MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()

    7657: M*/

    7662: /*@
    7663:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
    7664:                       as the original matrix.

    7666:     Collective on Mat

    7668:     Input Parameters:
    7669: +   mat - the original matrix
    7670: .   isrow - parallel IS containing the rows this processor should obtain
    7671: .   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.
    7672: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    7674:     Output Parameter:
    7675: .   newmat - the new submatrix, of the same type as the old

    7677:     Level: advanced

    7679:     Notes:
    7680:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

    7682:     Some matrix types place restrictions on the row and column indices, such
    7683:     as that they be sorted or that they be equal to each other.

    7685:     The index sets may not have duplicate entries.

    7687:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
    7688:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
    7689:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
    7690:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when
    7691:    you are finished using it.

    7693:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
    7694:     the input matrix.

    7696:     If iscol is NULL then all columns are obtained (not supported in Fortran).

    7698:    Example usage:
    7699:    Consider the following 8x8 matrix with 34 non-zero values, that is
    7700:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
    7701:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
    7702:    as follows:

    7704: .vb
    7705:             1  2  0  |  0  3  0  |  0  4
    7706:     Proc0   0  5  6  |  7  0  0  |  8  0
    7707:             9  0 10  | 11  0  0  | 12  0
    7708:     -------------------------------------
    7709:            13  0 14  | 15 16 17  |  0  0
    7710:     Proc1   0 18  0  | 19 20 21  |  0  0
    7711:             0  0  0  | 22 23  0  | 24  0
    7712:     -------------------------------------
    7713:     Proc2  25 26 27  |  0  0 28  | 29  0
    7714:            30  0  0  | 31 32 33  |  0 34
    7715: .ve

    7717:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

    7719: .vb
    7720:             2  0  |  0  3  0  |  0
    7721:     Proc0   5  6  |  7  0  0  |  8
    7722:     -------------------------------
    7723:     Proc1  18  0  | 19 20 21  |  0
    7724:     -------------------------------
    7725:     Proc2  26 27  |  0  0 28  | 29
    7726:             0  0  | 31 32 33  |  0
    7727: .ve

    7730:     Concepts: matrices^submatrices

    7732: .seealso: MatGetSubMatrices()
    7733: @*/
    7734: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
    7735: {
    7737:   PetscMPIInt    size;
    7738:   Mat            *local;
    7739:   IS             iscoltmp;

    7748:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    7749:   if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");

    7751:   MatCheckPreallocated(mat,1);
    7752:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);

    7754:   if (!iscol || isrow == iscol) {
    7755:     PetscBool   stride;
    7756:     PetscMPIInt grabentirematrix = 0,grab;
    7757:     PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
    7758:     if (stride) {
    7759:       PetscInt first,step,n,rstart,rend;
    7760:       ISStrideGetInfo(isrow,&first,&step);
    7761:       if (step == 1) {
    7762:         MatGetOwnershipRange(mat,&rstart,&rend);
    7763:         if (rstart == first) {
    7764:           ISGetLocalSize(isrow,&n);
    7765:           if (n == rend-rstart) {
    7766:             grabentirematrix = 1;
    7767:           }
    7768:         }
    7769:       }
    7770:     }
    7771:     MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
    7772:     if (grab) {
    7773:       PetscInfo(mat,"Getting entire matrix as submatrix\n");
    7774:       if (cll == MAT_INITIAL_MATRIX) {
    7775:         *newmat = mat;
    7776:         PetscObjectReference((PetscObject)mat);
    7777:       }
    7778:       return(0);
    7779:     }
    7780:   }

    7782:   if (!iscol) {
    7783:     ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
    7784:   } else {
    7785:     iscoltmp = iscol;
    7786:   }

    7788:   /* if original matrix is on just one processor then use submatrix generated */
    7789:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
    7790:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
    7791:     if (!iscol) {ISDestroy(&iscoltmp);}
    7792:     return(0);
    7793:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
    7794:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
    7795:     *newmat = *local;
    7796:     PetscFree(local);
    7797:     if (!iscol) {ISDestroy(&iscoltmp);}
    7798:     return(0);
    7799:   } else if (!mat->ops->getsubmatrix) {
    7800:     /* Create a new matrix type that implements the operation using the full matrix */
    7801:     PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
    7802:     switch (cll) {
    7803:     case MAT_INITIAL_MATRIX:
    7804:       MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
    7805:       break;
    7806:     case MAT_REUSE_MATRIX:
    7807:       MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
    7808:       break;
    7809:     default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
    7810:     }
    7811:     PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
    7812:     if (!iscol) {ISDestroy(&iscoltmp);}
    7813:     return(0);
    7814:   }

    7816:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    7817:   PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
    7818:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
    7819:   PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
    7820:   if (!iscol) {ISDestroy(&iscoltmp);}
    7821:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
    7822:   return(0);
    7823: }

    7827: /*@
    7828:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
    7829:    used during the assembly process to store values that belong to
    7830:    other processors.

    7832:    Not Collective

    7834:    Input Parameters:
    7835: +  mat   - the matrix
    7836: .  size  - the initial size of the stash.
    7837: -  bsize - the initial size of the block-stash(if used).

    7839:    Options Database Keys:
    7840: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
    7841: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

    7843:    Level: intermediate

    7845:    Notes:
    7846:      The block-stash is used for values set with MatSetValuesBlocked() while
    7847:      the stash is used for values set with MatSetValues()

    7849:      Run with the option -info and look for output of the form
    7850:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
    7851:      to determine the appropriate value, MM, to use for size and
    7852:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
    7853:      to determine the value, BMM to use for bsize

    7855:    Concepts: stash^setting matrix size
    7856:    Concepts: matrices^stash

    7858: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

    7860: @*/
    7861: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
    7862: {

    7868:   MatStashSetInitialSize_Private(&mat->stash,size);
    7869:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
    7870:   return(0);
    7871: }

    7875: /*@
    7876:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
    7877:      the matrix

    7879:    Neighbor-wise Collective on Mat

    7881:    Input Parameters:
    7882: +  mat   - the matrix
    7883: .  x,y - the vectors
    7884: -  w - where the result is stored

    7886:    Level: intermediate

    7888:    Notes:
    7889:     w may be the same vector as y.

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

    7894:     Concepts: interpolation

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

    7898: @*/
    7899: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
    7900: {
    7902:   PetscInt       M,N,Ny;

    7910:   MatCheckPreallocated(A,1);
    7911:   MatGetSize(A,&M,&N);
    7912:   VecGetSize(y,&Ny);
    7913:   if (M == Ny) {
    7914:     MatMultAdd(A,x,y,w);
    7915:   } else {
    7916:     MatMultTransposeAdd(A,x,y,w);
    7917:   }
    7918:   return(0);
    7919: }

    7923: /*@
    7924:    MatInterpolate - y = A*x or A'*x depending on the shape of
    7925:      the matrix

    7927:    Neighbor-wise Collective on Mat

    7929:    Input Parameters:
    7930: +  mat   - the matrix
    7931: -  x,y - the vectors

    7933:    Level: intermediate

    7935:    Notes:
    7936:     This allows one to use either the restriction or interpolation (its transpose)
    7937:     matrix to do the interpolation

    7939:    Concepts: matrices^interpolation

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

    7943: @*/
    7944: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
    7945: {
    7947:   PetscInt       M,N,Ny;

    7954:   MatCheckPreallocated(A,1);
    7955:   MatGetSize(A,&M,&N);
    7956:   VecGetSize(y,&Ny);
    7957:   if (M == Ny) {
    7958:     MatMult(A,x,y);
    7959:   } else {
    7960:     MatMultTranspose(A,x,y);
    7961:   }
    7962:   return(0);
    7963: }

    7967: /*@
    7968:    MatRestrict - y = A*x or A'*x

    7970:    Neighbor-wise Collective on Mat

    7972:    Input Parameters:
    7973: +  mat   - the matrix
    7974: -  x,y - the vectors

    7976:    Level: intermediate

    7978:    Notes:
    7979:     This allows one to use either the restriction or interpolation (its transpose)
    7980:     matrix to do the restriction

    7982:    Concepts: matrices^restriction

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

    7986: @*/
    7987: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
    7988: {
    7990:   PetscInt       M,N,Ny;

    7997:   MatCheckPreallocated(A,1);

    7999:   MatGetSize(A,&M,&N);
    8000:   VecGetSize(y,&Ny);
    8001:   if (M == Ny) {
    8002:     MatMult(A,x,y);
    8003:   } else {
    8004:     MatMultTranspose(A,x,y);
    8005:   }
    8006:   return(0);
    8007: }

    8011: /*@
    8012:    MatGetNullSpace - retrieves the null space to a matrix.

    8014:    Logically Collective on Mat and MatNullSpace

    8016:    Input Parameters:
    8017: +  mat - the matrix
    8018: -  nullsp - the null space object

    8020:    Level: developer

    8022:    Concepts: null space^attaching to matrix

    8024: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
    8025: @*/
    8026: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
    8027: {
    8032:   *nullsp = mat->nullsp;
    8033:   return(0);
    8034: }

    8038: /*@
    8039:    MatSetNullSpace - attaches a null space to a matrix.

    8041:    Logically Collective on Mat and MatNullSpace

    8043:    Input Parameters:
    8044: +  mat - the matrix
    8045: -  nullsp - the null space object

    8047:    Level: advanced

    8049:    Notes:
    8050:       This null space is used by the linear solvers. Overwrites any previous null space that may have been attached

    8052:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
    8053:       call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.

    8055:       You can remove the null space by calling this routine with an nullsp of NULL

    8058:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
    8059:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
    8060:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
    8061:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
    8062:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).

    8064:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

    8066:    Concepts: null space^attaching to matrix

    8068: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
    8069: @*/
    8070: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
    8071: {

    8078:   MatCheckPreallocated(mat,1);
    8079:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
    8080:   MatNullSpaceDestroy(&mat->nullsp);
    8081:   mat->nullsp = nullsp;
    8082:   return(0);
    8083: }

    8087: /*@
    8088:    MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.

    8090:    Logically Collective on Mat and MatNullSpace

    8092:    Input Parameters:
    8093: +  mat - the matrix
    8094: -  nullsp - the null space object

    8096:    Level: developer

    8098:    Concepts: null space^attaching to matrix

    8100: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
    8101: @*/
    8102: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
    8103: {
    8108:   *nullsp = mat->transnullsp;
    8109:   return(0);
    8110: }

    8114: /*@
    8115:    MatSetTransposeNullSpace - attaches a null space to a matrix.

    8117:    Logically Collective on Mat and MatNullSpace

    8119:    Input Parameters:
    8120: +  mat - the matrix
    8121: -  nullsp - the null space object

    8123:    Level: advanced

    8125:    Notes:
    8126:       For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
    8127:       You must also call MatSetNullSpace()

    8130:       The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
    8131:    the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
    8132:    Similarly R^m = direct sum n(A^T) + R(A).  Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
    8133:    n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
    8134:    the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).

    8136:       Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().

    8138:    Concepts: null space^attaching to matrix

    8140: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
    8141: @*/
    8142: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
    8143: {

    8150:   MatCheckPreallocated(mat,1);
    8151:   PetscObjectReference((PetscObject)nullsp);
    8152:   MatNullSpaceDestroy(&mat->transnullsp);
    8153:   mat->transnullsp = nullsp;
    8154:   return(0);
    8155: }

    8159: /*@
    8160:    MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
    8161:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

    8163:    Logically Collective on Mat and MatNullSpace

    8165:    Input Parameters:
    8166: +  mat - the matrix
    8167: -  nullsp - the null space object

    8169:    Level: advanced

    8171:    Notes:
    8172:       Overwrites any previous near null space that may have been attached

    8174:       You can remove the null space by calling this routine with an nullsp of NULL

    8176:    Concepts: null space^attaching to matrix

    8178: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
    8179: @*/
    8180: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
    8181: {

    8188:   MatCheckPreallocated(mat,1);
    8189:   if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
    8190:   MatNullSpaceDestroy(&mat->nearnullsp);
    8191:   mat->nearnullsp = nullsp;
    8192:   return(0);
    8193: }

    8197: /*@
    8198:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

    8200:    Not Collective

    8202:    Input Parameters:
    8203: .  mat - the matrix

    8205:    Output Parameters:
    8206: .  nullsp - the null space object, NULL if not set

    8208:    Level: developer

    8210:    Concepts: null space^attaching to matrix

    8212: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
    8213: @*/
    8214: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
    8215: {
    8220:   MatCheckPreallocated(mat,1);
    8221:   *nullsp = mat->nearnullsp;
    8222:   return(0);
    8223: }

    8227: /*@C
    8228:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

    8230:    Collective on Mat

    8232:    Input Parameters:
    8233: +  mat - the matrix
    8234: .  row - row/column permutation
    8235: .  fill - expected fill factor >= 1.0
    8236: -  level - level of fill, for ICC(k)

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

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

    8246:    Level: developer

    8248:    Concepts: matrices^incomplete Cholesky factorization
    8249:    Concepts: Cholesky factorization

    8251: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

    8256: @*/
    8257: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
    8258: {

    8266:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
    8267:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    8268:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    8269:   if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    8270:   MatCheckPreallocated(mat,1);
    8271:   (*mat->ops->iccfactor)(mat,row,info);
    8272:   PetscObjectStateIncrease((PetscObject)mat);
    8273:   return(0);
    8274: }

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

    8281:    Not Collective

    8283:    Input Parameters:
    8284: +  mat - the matrix
    8285: .  nl - leading dimension of v
    8286: -  v - the values compute with ADIFOR

    8288:    Level: developer

    8290:    Notes:
    8291:      Must call MatSetColoring() before using this routine. Also this matrix must already
    8292:      have its nonzero pattern determined.

    8294: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
    8295:           MatSetValues(), MatSetColoring()
    8296: @*/
    8297: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
    8298: {

    8306:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
    8307:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
    8308:   if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    8309:   (*mat->ops->setvaluesadifor)(mat,nl,v);
    8310:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
    8311:   PetscObjectStateIncrease((PetscObject)mat);
    8312:   return(0);
    8313: }

    8317: /*@
    8318:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
    8319:          ghosted ones.

    8321:    Not Collective

    8323:    Input Parameters:
    8324: +  mat - the matrix
    8325: -  diag = the diagonal values, including ghost ones

    8327:    Level: developer

    8329:    Notes: Works only for MPIAIJ and MPIBAIJ matrices

    8331: .seealso: MatDiagonalScale()
    8332: @*/
    8333: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
    8334: {
    8336:   PetscMPIInt    size;

    8343:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
    8344:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
    8345:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
    8346:   if (size == 1) {
    8347:     PetscInt n,m;
    8348:     VecGetSize(diag,&n);
    8349:     MatGetSize(mat,0,&m);
    8350:     if (m == n) {
    8351:       MatDiagonalScale(mat,0,diag);
    8352:     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
    8353:   } else {
    8354:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
    8355:   }
    8356:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
    8357:   PetscObjectStateIncrease((PetscObject)mat);
    8358:   return(0);
    8359: }

    8363: /*@
    8364:    MatGetInertia - Gets the inertia from a factored matrix

    8366:    Collective on Mat

    8368:    Input Parameter:
    8369: .  mat - the matrix

    8371:    Output Parameters:
    8372: +   nneg - number of negative eigenvalues
    8373: .   nzero - number of zero eigenvalues
    8374: -   npos - number of positive eigenvalues

    8376:    Level: advanced

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

    8381: @*/
    8382: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
    8383: {

    8389:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    8390:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
    8391:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    8392:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
    8393:   return(0);
    8394: }

    8396: /* ----------------------------------------------------------------*/
    8399: /*@C
    8400:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

    8402:    Neighbor-wise Collective on Mat and Vecs

    8404:    Input Parameters:
    8405: +  mat - the factored matrix
    8406: -  b - the right-hand-side vectors

    8408:    Output Parameter:
    8409: .  x - the result vectors

    8411:    Notes:
    8412:    The vectors b and x cannot be the same.  I.e., one cannot
    8413:    call MatSolves(A,x,x).

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

    8420:    Level: developer

    8422:    Concepts: matrices^triangular solves

    8424: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
    8425: @*/
    8426: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
    8427: {

    8433:   if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
    8434:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
    8435:   if (!mat->rmap->N && !mat->cmap->N) return(0);

    8437:   if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
    8438:   MatCheckPreallocated(mat,1);
    8439:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
    8440:   (*mat->ops->solves)(mat,b,x);
    8441:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
    8442:   return(0);
    8443: }

    8447: /*@
    8448:    MatIsSymmetric - Test whether a matrix is symmetric

    8450:    Collective on Mat

    8452:    Input Parameter:
    8453: +  A - the matrix to test
    8454: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

    8456:    Output Parameters:
    8457: .  flg - the result

    8459:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

    8461:    Level: intermediate

    8463:    Concepts: matrix^symmetry

    8465: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
    8466: @*/
    8467: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
    8468: {

    8475:   if (!A->symmetric_set) {
    8476:     if (!A->ops->issymmetric) {
    8477:       MatType mattype;
    8478:       MatGetType(A,&mattype);
    8479:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
    8480:     }
    8481:     (*A->ops->issymmetric)(A,tol,flg);
    8482:     if (!tol) {
    8483:       A->symmetric_set = PETSC_TRUE;
    8484:       A->symmetric     = *flg;
    8485:       if (A->symmetric) {
    8486:         A->structurally_symmetric_set = PETSC_TRUE;
    8487:         A->structurally_symmetric     = PETSC_TRUE;
    8488:       }
    8489:     }
    8490:   } else if (A->symmetric) {
    8491:     *flg = PETSC_TRUE;
    8492:   } else if (!tol) {
    8493:     *flg = PETSC_FALSE;
    8494:   } else {
    8495:     if (!A->ops->issymmetric) {
    8496:       MatType mattype;
    8497:       MatGetType(A,&mattype);
    8498:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
    8499:     }
    8500:     (*A->ops->issymmetric)(A,tol,flg);
    8501:   }
    8502:   return(0);
    8503: }

    8507: /*@
    8508:    MatIsHermitian - Test whether a matrix is Hermitian

    8510:    Collective on Mat

    8512:    Input Parameter:
    8513: +  A - the matrix to test
    8514: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

    8516:    Output Parameters:
    8517: .  flg - the result

    8519:    Level: intermediate

    8521:    Concepts: matrix^symmetry

    8523: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
    8524:           MatIsSymmetricKnown(), MatIsSymmetric()
    8525: @*/
    8526: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
    8527: {

    8534:   if (!A->hermitian_set) {
    8535:     if (!A->ops->ishermitian) {
    8536:       MatType mattype;
    8537:       MatGetType(A,&mattype);
    8538:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
    8539:     }
    8540:     (*A->ops->ishermitian)(A,tol,flg);
    8541:     if (!tol) {
    8542:       A->hermitian_set = PETSC_TRUE;
    8543:       A->hermitian     = *flg;
    8544:       if (A->hermitian) {
    8545:         A->structurally_symmetric_set = PETSC_TRUE;
    8546:         A->structurally_symmetric     = PETSC_TRUE;
    8547:       }
    8548:     }
    8549:   } else if (A->hermitian) {
    8550:     *flg = PETSC_TRUE;
    8551:   } else if (!tol) {
    8552:     *flg = PETSC_FALSE;
    8553:   } else {
    8554:     if (!A->ops->ishermitian) {
    8555:       MatType mattype;
    8556:       MatGetType(A,&mattype);
    8557:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
    8558:     }
    8559:     (*A->ops->ishermitian)(A,tol,flg);
    8560:   }
    8561:   return(0);
    8562: }

    8566: /*@
    8567:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

    8569:    Not Collective

    8571:    Input Parameter:
    8572: .  A - the matrix to check

    8574:    Output Parameters:
    8575: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
    8576: -  flg - the result

    8578:    Level: advanced

    8580:    Concepts: matrix^symmetry

    8582:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
    8583:          if you want it explicitly checked

    8585: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
    8586: @*/
    8587: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
    8588: {
    8593:   if (A->symmetric_set) {
    8594:     *set = PETSC_TRUE;
    8595:     *flg = A->symmetric;
    8596:   } else {
    8597:     *set = PETSC_FALSE;
    8598:   }
    8599:   return(0);
    8600: }

    8604: /*@
    8605:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

    8607:    Not Collective

    8609:    Input Parameter:
    8610: .  A - the matrix to check

    8612:    Output Parameters:
    8613: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
    8614: -  flg - the result

    8616:    Level: advanced

    8618:    Concepts: matrix^symmetry

    8620:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
    8621:          if you want it explicitly checked

    8623: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
    8624: @*/
    8625: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
    8626: {
    8631:   if (A->hermitian_set) {
    8632:     *set = PETSC_TRUE;
    8633:     *flg = A->hermitian;
    8634:   } else {
    8635:     *set = PETSC_FALSE;
    8636:   }
    8637:   return(0);
    8638: }

    8642: /*@
    8643:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

    8645:    Collective on Mat

    8647:    Input Parameter:
    8648: .  A - the matrix to test

    8650:    Output Parameters:
    8651: .  flg - the result

    8653:    Level: intermediate

    8655:    Concepts: matrix^symmetry

    8657: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
    8658: @*/
    8659: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
    8660: {

    8666:   if (!A->structurally_symmetric_set) {
    8667:     if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
    8668:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);

    8670:     A->structurally_symmetric_set = PETSC_TRUE;
    8671:   }
    8672:   *flg = A->structurally_symmetric;
    8673:   return(0);
    8674: }

    8678: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
    8679: /*@
    8680:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
    8681:        to be communicated to other processors during the MatAssemblyBegin/End() process

    8683:     Not collective

    8685:    Input Parameter:
    8686: .   vec - the vector

    8688:    Output Parameters:
    8689: +   nstash   - the size of the stash
    8690: .   reallocs - the number of additional mallocs incurred.
    8691: .   bnstash   - the size of the block stash
    8692: -   breallocs - the number of additional mallocs incurred.in the block stash

    8694:    Level: advanced

    8696: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()

    8698: @*/
    8699: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
    8700: {

    8704:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
    8705:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
    8706:   return(0);
    8707: }

    8711: /*@C
    8712:    MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
    8713:      parallel layout

    8715:    Collective on Mat

    8717:    Input Parameter:
    8718: .  mat - the matrix

    8720:    Output Parameter:
    8721: +   right - (optional) vector that the matrix can be multiplied against
    8722: -   left - (optional) vector that the matrix vector product can be stored in

    8724:    Notes:
    8725:     The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize().

    8727:   Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed

    8729:   Level: advanced

    8731: .seealso: MatCreate(), VecDestroy()
    8732: @*/
    8733: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
    8734: {

    8740:   if (mat->ops->getvecs) {
    8741:     (*mat->ops->getvecs)(mat,right,left);
    8742:   } else {
    8743:     PetscInt rbs,cbs;
    8744:     MatGetBlockSizes(mat,&rbs,&cbs);
    8745:     if (right) {
    8746:       if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
    8747:       VecCreate(PetscObjectComm((PetscObject)mat),right);
    8748:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
    8749:       VecSetBlockSize(*right,cbs);
    8750:       VecSetType(*right,VECSTANDARD);
    8751:       PetscLayoutReference(mat->cmap,&(*right)->map);
    8752:     }
    8753:     if (left) {
    8754:       if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
    8755:       VecCreate(PetscObjectComm((PetscObject)mat),left);
    8756:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
    8757:       VecSetBlockSize(*left,rbs);
    8758:       VecSetType(*left,VECSTANDARD);
    8759:       PetscLayoutReference(mat->rmap,&(*left)->map);
    8760:     }
    8761:   }
    8762:   return(0);
    8763: }

    8767: /*@C
    8768:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
    8769:      with default values.

    8771:    Not Collective

    8773:    Input Parameters:
    8774: .    info - the MatFactorInfo data structure

    8777:    Notes: The solvers are generally used through the KSP and PC objects, for example
    8778:           PCLU, PCILU, PCCHOLESKY, PCICC

    8780:    Level: developer

    8782: .seealso: MatFactorInfo

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

    8787: @*/

    8789: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
    8790: {

    8794:   PetscMemzero(info,sizeof(MatFactorInfo));
    8795:   return(0);
    8796: }

    8800: /*@
    8801:    MatFactorSetSchurIS - Set indices corresponding to the Schur complement

    8803:    Collective on Mat

    8805:    Input Parameters:
    8806: +  mat - the factored matrix
    8807: -  is - the index set defining the Schur indices (0-based)

    8809:    Notes:

    8811:    Level: developer

    8813:    Concepts:

    8815: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()

    8817: @*/
    8818: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
    8819: {
    8820:   PetscErrorCode ierr,(*f)(Mat,IS);

    8828:   if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
    8829:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
    8830:   if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverPackage does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
    8831:   (*f)(mat,is);
    8832:   return(0);
    8833: }

    8837: /*@
    8838:   MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step

    8840:    Logically Collective on Mat

    8842:    Input Parameters:
    8843: +  F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
    8844: .  *S - location where to return the Schur complement (MATDENSE)

    8846:    Notes:
    8847:    The routine provides a copy of the Schur data stored within solver's data strutures. The caller must destroy the object when it is no longer needed.
    8848:    If MatFactorInvertSchurComplement has been called, the routine gets back the inverse

    8850:    Level: advanced

    8852:    References:

    8854: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
    8855: @*/
    8856: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
    8857: {

    8862:   PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
    8863:   return(0);
    8864: }

    8868: /*@
    8869:   MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data

    8871:    Logically Collective on Mat

    8873:    Input Parameters:
    8874: +  F - the factored matrix obtained by calling MatGetFactor()
    8875: .  *S - location where to return the Schur complement (in MATDENSE format)

    8877:    Notes:
    8878:    Schur complement mode is currently implemented for sequential matrices.
    8879:    The routine returns a dense matrix pointing to the raw data of the Schur Complement stored within the data strutures of the solver; e.g. if MatFactorInvertSchurComplement has been called, the returned matrix is actually the inverse of the Schur complement.
    8880:    The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.

    8882:    Level: advanced

    8884:    References:

    8886: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
    8887: @*/
    8888: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
    8889: {

    8894:   PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
    8895:   return(0);
    8896: }

    8900: /*@
    8901:   MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement

    8903:    Logically Collective on Mat

    8905:    Input Parameters:
    8906: +  F - the factored matrix obtained by calling MatGetFactor()
    8907: .  *S - location where the Schur complement is stored

    8909:    Notes:

    8911:    Level: advanced

    8913:    References:

    8915: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
    8916: @*/
    8917: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
    8918: {

    8924:   MatDestroy(S);
    8925:   return(0);
    8926: }

    8930: /*@
    8931:   MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step

    8933:    Logically Collective on Mat

    8935:    Input Parameters:
    8936: +  F - the factored matrix obtained by calling MatGetFactor()
    8937: .  rhs - location where the right hand side of the Schur complement system is stored
    8938: -  sol - location where the solution of the Schur complement system has to be returned

    8940:    Notes:
    8941:    The sizes of the vectors should match the size of the Schur complement

    8943:    Level: advanced

    8945:    References:

    8947: .seealso: MatGetFactor(), MatFactorSetSchurIS()
    8948: @*/
    8949: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
    8950: {

    8959:   PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
    8960:   return(0);
    8961: }

    8965: /*@
    8966:   MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step

    8968:    Logically Collective on Mat

    8970:    Input Parameters:
    8971: +  F - the factored matrix obtained by calling MatGetFactor()
    8972: .  rhs - location where the right hand side of the Schur complement system is stored
    8973: -  sol - location where the solution of the Schur complement system has to be returned

    8975:    Notes:
    8976:    The sizes of the vectors should match the size of the Schur complement

    8978:    Level: advanced

    8980:    References:

    8982: .seealso: MatGetFactor(), MatFactorSetSchurIS()
    8983: @*/
    8984: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
    8985: {

    8994:   PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
    8995:   return(0);
    8996: }

    9000: /*@
    9001:   MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step

    9003:    Logically Collective on Mat

    9005:    Input Parameters:
    9006: +  F - the factored matrix obtained by calling MatGetFactor()

    9008:    Notes:

    9010:    Level: advanced

    9012:    References:

    9014: .seealso: MatGetFactor(), MatFactorSetSchurIS()
    9015: @*/
    9016: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
    9017: {

    9022:   PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
    9023:   return(0);
    9024: }

    9029: /*@
    9030:    MatPtAP - Creates the matrix product C = P^T * A * P

    9032:    Neighbor-wise Collective on Mat

    9034:    Input Parameters:
    9035: +  A - the matrix
    9036: .  P - the projection matrix
    9037: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    9038: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
    9039:           if the result is a dense matrix this is irrelevent

    9041:    Output Parameters:
    9042: .  C - the product matrix

    9044:    Notes:
    9045:    C will be created and must be destroyed by the user with MatDestroy().

    9047:    This routine is currently only implemented for pairs of AIJ matrices and classes
    9048:    which inherit from AIJ.

    9050:    Level: intermediate

    9052: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
    9053: @*/
    9054: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
    9055: {
    9057:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    9058:   PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
    9059:   PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
    9060:   PetscBool      viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;

    9063:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
    9064:   PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);

    9068:   MatCheckPreallocated(A,1);
    9069:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9070:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9073:   MatCheckPreallocated(P,2);
    9074:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9075:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    9077:   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);
    9078:   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);
    9079:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    9080:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

    9082:   if (scall == MAT_REUSE_MATRIX) {
    9085:     if (viatranspose || viamatmatmatmult) {
    9086:       Mat Pt;
    9087:       MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
    9088:       if (viamatmatmatmult) {
    9089:         MatMatMatMult(Pt,A,P,scall,fill,C);
    9090:       } else {
    9091:         Mat AP;
    9092:         MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
    9093:         MatMatMult(Pt,AP,scall,fill,C);
    9094:         MatDestroy(&AP);
    9095:       }
    9096:       MatDestroy(&Pt);
    9097:     } else {
    9098:       PetscLogEventBegin(MAT_PtAP,A,P,0,0);
    9099:       PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
    9100:       (*(*C)->ops->ptapnumeric)(A,P,*C);
    9101:       PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
    9102:       PetscLogEventEnd(MAT_PtAP,A,P,0,0);
    9103:     }
    9104:     return(0);
    9105:   }

    9107:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    9108:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

    9110:   fA = A->ops->ptap;
    9111:   fP = P->ops->ptap;
    9112:   if (fP == fA) {
    9113:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
    9114:     ptap = fA;
    9115:   } else {
    9116:     /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
    9117:     char ptapname[256];
    9118:     PetscStrcpy(ptapname,"MatPtAP_");
    9119:     PetscStrcat(ptapname,((PetscObject)A)->type_name);
    9120:     PetscStrcat(ptapname,"_");
    9121:     PetscStrcat(ptapname,((PetscObject)P)->type_name);
    9122:     PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
    9123:     PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
    9124:     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);
    9125:   }

    9127:   if (viatranspose || viamatmatmatmult) {
    9128:     Mat Pt;
    9129:     MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
    9130:     if (viamatmatmatmult) {
    9131:       MatMatMatMult(Pt,A,P,scall,fill,C);
    9132:       PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
    9133:     } else {
    9134:       Mat AP;
    9135:       MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
    9136:       MatMatMult(Pt,AP,scall,fill,C);
    9137:       MatDestroy(&AP);
    9138:       PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
    9139:     }
    9140:     MatDestroy(&Pt);
    9141:   } else {
    9142:     PetscLogEventBegin(MAT_PtAP,A,P,0,0);
    9143:     (*ptap)(A,P,scall,fill,C);
    9144:     PetscLogEventEnd(MAT_PtAP,A,P,0,0);
    9145:   }
    9146:   return(0);
    9147: }

    9151: /*@
    9152:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

    9154:    Neighbor-wise Collective on Mat

    9156:    Input Parameters:
    9157: +  A - the matrix
    9158: -  P - the projection matrix

    9160:    Output Parameters:
    9161: .  C - the product matrix

    9163:    Notes:
    9164:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
    9165:    the user using MatDeatroy().

    9167:    This routine is currently only implemented for pairs of AIJ matrices and classes
    9168:    which inherit from AIJ.  C will be of type MATAIJ.

    9170:    Level: intermediate

    9172: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
    9173: @*/
    9174: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
    9175: {

    9181:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9182:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9185:   MatCheckPreallocated(P,2);
    9186:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9187:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9190:   MatCheckPreallocated(C,3);
    9191:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9192:   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);
    9193:   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);
    9194:   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);
    9195:   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);
    9196:   MatCheckPreallocated(A,1);

    9198:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
    9199:   (*C->ops->ptapnumeric)(A,P,C);
    9200:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
    9201:   return(0);
    9202: }

    9206: /*@
    9207:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

    9209:    Neighbor-wise Collective on Mat

    9211:    Input Parameters:
    9212: +  A - the matrix
    9213: -  P - the projection matrix

    9215:    Output Parameters:
    9216: .  C - the (i,j) structure of the product matrix

    9218:    Notes:
    9219:    C will be created and must be destroyed by the user with MatDestroy().

    9221:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
    9222:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
    9223:    this (i,j) structure by calling MatPtAPNumeric().

    9225:    Level: intermediate

    9227: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
    9228: @*/
    9229: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
    9230: {

    9236:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9237:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9238:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
    9241:   MatCheckPreallocated(P,2);
    9242:   if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9243:   if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    9246:   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);
    9247:   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);
    9248:   MatCheckPreallocated(A,1);
    9249:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
    9250:   (*A->ops->ptapsymbolic)(A,P,fill,C);
    9251:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

    9253:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
    9254:   return(0);
    9255: }

    9259: /*@
    9260:    MatRARt - Creates the matrix product C = R * A * R^T

    9262:    Neighbor-wise Collective on Mat

    9264:    Input Parameters:
    9265: +  A - the matrix
    9266: .  R - the projection matrix
    9267: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    9268: -  fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
    9269:           if the result is a dense matrix this is irrelevent

    9271:    Output Parameters:
    9272: .  C - the product matrix

    9274:    Notes:
    9275:    C will be created and must be destroyed by the user with MatDestroy().

    9277:    This routine is currently only implemented for pairs of AIJ matrices and classes
    9278:    which inherit from AIJ.

    9280:    Level: intermediate

    9282: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
    9283: @*/
    9284: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
    9285: {

    9291:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9292:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9295:   MatCheckPreallocated(R,2);
    9296:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9297:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9299:   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);

    9301:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    9302:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
    9303:   MatCheckPreallocated(A,1);

    9305:   if (!A->ops->rart) {
    9306:     MatType mattype;
    9307:     MatGetType(A,&mattype);
    9308:     SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
    9309:   }
    9310:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
    9311:   (*A->ops->rart)(A,R,scall,fill,C);
    9312:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
    9313:   return(0);
    9314: }

    9318: /*@
    9319:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

    9321:    Neighbor-wise Collective on Mat

    9323:    Input Parameters:
    9324: +  A - the matrix
    9325: -  R - the projection matrix

    9327:    Output Parameters:
    9328: .  C - the product matrix

    9330:    Notes:
    9331:    C must have been created by calling MatRARtSymbolic and must be destroyed by
    9332:    the user using MatDestroy().

    9334:    This routine is currently only implemented for pairs of AIJ matrices and classes
    9335:    which inherit from AIJ.  C will be of type MATAIJ.

    9337:    Level: intermediate

    9339: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
    9340: @*/
    9341: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
    9342: {

    9348:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9349:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9352:   MatCheckPreallocated(R,2);
    9353:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9354:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9357:   MatCheckPreallocated(C,3);
    9358:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9359:   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);
    9360:   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);
    9361:   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);
    9362:   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);
    9363:   MatCheckPreallocated(A,1);

    9365:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
    9366:   (*A->ops->rartnumeric)(A,R,C);
    9367:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
    9368:   return(0);
    9369: }

    9373: /*@
    9374:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

    9376:    Neighbor-wise Collective on Mat

    9378:    Input Parameters:
    9379: +  A - the matrix
    9380: -  R - the projection matrix

    9382:    Output Parameters:
    9383: .  C - the (i,j) structure of the product matrix

    9385:    Notes:
    9386:    C will be created and must be destroyed by the user with MatDestroy().

    9388:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
    9389:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
    9390:    this (i,j) structure by calling MatRARtNumeric().

    9392:    Level: intermediate

    9394: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
    9395: @*/
    9396: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
    9397: {

    9403:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9404:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9405:   if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
    9408:   MatCheckPreallocated(R,2);
    9409:   if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9410:   if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    9413:   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);
    9414:   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);
    9415:   MatCheckPreallocated(A,1);
    9416:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
    9417:   (*A->ops->rartsymbolic)(A,R,fill,C);
    9418:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

    9420:   MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
    9421:   return(0);
    9422: }

    9426: /*@
    9427:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

    9429:    Neighbor-wise Collective on Mat

    9431:    Input Parameters:
    9432: +  A - the left matrix
    9433: .  B - the right matrix
    9434: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    9435: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
    9436:           if the result is a dense matrix this is irrelevent

    9438:    Output Parameters:
    9439: .  C - the product matrix

    9441:    Notes:
    9442:    Unless scall is MAT_REUSE_MATRIX C will be created.

    9444:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

    9446:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    9447:    actually needed.

    9449:    If you have many matrices with the same non-zero structure to multiply, you
    9450:    should either
    9451: $   1) use MAT_REUSE_MATRIX in all calls but the first or
    9452: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
    9453:    In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
    9454:    with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.

    9456:    Level: intermediate

    9458: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
    9459: @*/
    9460: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
    9461: {
    9463:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    9464:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
    9465:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

    9470:   MatCheckPreallocated(A,1);
    9471:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9472:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9475:   MatCheckPreallocated(B,2);
    9476:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9477:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9479:   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);
    9480:   if (scall == MAT_REUSE_MATRIX) {
    9483:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
    9484:     PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
    9485:     (*(*C)->ops->matmultnumeric)(A,B,*C);
    9486:     PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
    9487:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
    9488:     return(0);
    9489:   }
    9490:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    9491:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

    9493:   fA = A->ops->matmult;
    9494:   fB = B->ops->matmult;
    9495:   if (fB == fA) {
    9496:     if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
    9497:     mult = fB;
    9498:   } else {
    9499:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
    9500:     char multname[256];
    9501:     PetscStrcpy(multname,"MatMatMult_");
    9502:     PetscStrcat(multname,((PetscObject)A)->type_name);
    9503:     PetscStrcat(multname,"_");
    9504:     PetscStrcat(multname,((PetscObject)B)->type_name);
    9505:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
    9506:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
    9507:     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);
    9508:   }
    9509:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
    9510:   (*mult)(A,B,scall,fill,C);
    9511:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
    9512:   return(0);
    9513: }

    9517: /*@
    9518:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
    9519:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

    9521:    Neighbor-wise Collective on Mat

    9523:    Input Parameters:
    9524: +  A - the left matrix
    9525: .  B - the right matrix
    9526: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
    9527:       if C is a dense matrix this is irrelevent

    9529:    Output Parameters:
    9530: .  C - the product matrix

    9532:    Notes:
    9533:    Unless scall is MAT_REUSE_MATRIX C will be created.

    9535:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    9536:    actually needed.

    9538:    This routine is currently implemented for
    9539:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
    9540:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
    9541:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

    9543:    Level: intermediate

    9545:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
    9546:      We should incorporate them into PETSc.

    9548: .seealso: MatMatMult(), MatMatMultNumeric()
    9549: @*/
    9550: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
    9551: {
    9553:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
    9554:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
    9555:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;

    9560:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9561:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    9565:   MatCheckPreallocated(B,2);
    9566:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9567:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    9570:   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);
    9571:   if (fill == PETSC_DEFAULT) fill = 2.0;
    9572:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
    9573:   MatCheckPreallocated(A,1);

    9575:   Asymbolic = A->ops->matmultsymbolic;
    9576:   Bsymbolic = B->ops->matmultsymbolic;
    9577:   if (Asymbolic == Bsymbolic) {
    9578:     if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
    9579:     symbolic = Bsymbolic;
    9580:   } else { /* dispatch based on the type of A and B */
    9581:     char symbolicname[256];
    9582:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
    9583:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
    9584:     PetscStrcat(symbolicname,"_");
    9585:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
    9586:     PetscStrcat(symbolicname,"_C");
    9587:     PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
    9588:     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);
    9589:   }
    9590:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
    9591:   (*symbolic)(A,B,fill,C);
    9592:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
    9593:   return(0);
    9594: }

    9598: /*@
    9599:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
    9600:    Call this routine after first calling MatMatMultSymbolic().

    9602:    Neighbor-wise Collective on Mat

    9604:    Input Parameters:
    9605: +  A - the left matrix
    9606: -  B - the right matrix

    9608:    Output Parameters:
    9609: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

    9611:    Notes:
    9612:    C must have been created with MatMatMultSymbolic().

    9614:    This routine is currently implemented for
    9615:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
    9616:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
    9617:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

    9619:    Level: intermediate

    9621: .seealso: MatMatMult(), MatMatMultSymbolic()
    9622: @*/
    9623: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
    9624: {

    9628:   MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
    9629:   return(0);
    9630: }

    9634: /*@
    9635:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

    9637:    Neighbor-wise Collective on Mat

    9639:    Input Parameters:
    9640: +  A - the left matrix
    9641: .  B - the right matrix
    9642: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    9643: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

    9645:    Output Parameters:
    9646: .  C - the product matrix

    9648:    Notes:
    9649:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

    9651:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

    9653:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    9654:    actually needed.

    9656:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

    9658:    Level: intermediate

    9660: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
    9661: @*/
    9662: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
    9663: {
    9665:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    9666:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

    9671:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9672:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9675:   MatCheckPreallocated(B,2);
    9676:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9677:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9679:   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);
    9680:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    9681:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
    9682:   MatCheckPreallocated(A,1);

    9684:   fA = A->ops->mattransposemult;
    9685:   if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
    9686:   fB = B->ops->mattransposemult;
    9687:   if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
    9688:   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);

    9690:   PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
    9691:   if (scall == MAT_INITIAL_MATRIX) {
    9692:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
    9693:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
    9694:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
    9695:   }
    9696:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
    9697:   (*A->ops->mattransposemultnumeric)(A,B,*C);
    9698:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
    9699:   PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
    9700:   return(0);
    9701: }

    9705: /*@
    9706:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

    9708:    Neighbor-wise Collective on Mat

    9710:    Input Parameters:
    9711: +  A - the left matrix
    9712: .  B - the right matrix
    9713: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    9714: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

    9716:    Output Parameters:
    9717: .  C - the product matrix

    9719:    Notes:
    9720:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

    9722:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

    9724:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    9725:    actually needed.

    9727:    This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
    9728:    which inherit from SeqAIJ.  C will be of same type as the input matrices.

    9730:    Level: intermediate

    9732: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
    9733: @*/
    9734: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
    9735: {
    9737:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
    9738:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
    9739:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;

    9744:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9745:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9748:   MatCheckPreallocated(B,2);
    9749:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9750:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9752:   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);
    9753:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    9754:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
    9755:   MatCheckPreallocated(A,1);

    9757:   fA = A->ops->transposematmult;
    9758:   fB = B->ops->transposematmult;
    9759:   if (fB==fA) {
    9760:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
    9761:     transposematmult = fA;
    9762:   } else {
    9763:     /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
    9764:     char multname[256];
    9765:     PetscStrcpy(multname,"MatTransposeMatMult_");
    9766:     PetscStrcat(multname,((PetscObject)A)->type_name);
    9767:     PetscStrcat(multname,"_");
    9768:     PetscStrcat(multname,((PetscObject)B)->type_name);
    9769:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
    9770:     PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
    9771:     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);
    9772:   }
    9773:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
    9774:   (*transposematmult)(A,B,scall,fill,C);
    9775:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
    9776:   return(0);
    9777: }

    9781: /*@
    9782:    MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.

    9784:    Neighbor-wise Collective on Mat

    9786:    Input Parameters:
    9787: +  A - the left matrix
    9788: .  B - the middle matrix
    9789: .  C - the right matrix
    9790: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
    9791: -  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
    9792:           if the result is a dense matrix this is irrelevent

    9794:    Output Parameters:
    9795: .  D - the product matrix

    9797:    Notes:
    9798:    Unless scall is MAT_REUSE_MATRIX D will be created.

    9800:    MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call

    9802:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
    9803:    actually needed.

    9805:    If you have many matrices with the same non-zero structure to multiply, you
    9806:    should use MAT_REUSE_MATRIX in all calls but the first or

    9808:    Level: intermediate

    9810: .seealso: MatMatMult, MatPtAP()
    9811: @*/
    9812: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
    9813: {
    9815:   PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
    9816:   PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
    9817:   PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
    9818:   PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;

    9823:   MatCheckPreallocated(A,1);
    9824:   if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9825:   if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9828:   MatCheckPreallocated(B,2);
    9829:   if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9830:   if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9833:   MatCheckPreallocated(C,3);
    9834:   if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9835:   if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9836:   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);
    9837:   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);
    9838:   if (scall == MAT_REUSE_MATRIX) {
    9841:     PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
    9842:     (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
    9843:     PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
    9844:     return(0);
    9845:   }
    9846:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
    9847:   if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);

    9849:   fA = A->ops->matmatmult;
    9850:   fB = B->ops->matmatmult;
    9851:   fC = C->ops->matmatmult;
    9852:   if (fA == fB && fA == fC) {
    9853:     if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
    9854:     mult = fA;
    9855:   } else {
    9856:     /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
    9857:     char multname[256];
    9858:     PetscStrcpy(multname,"MatMatMatMult_");
    9859:     PetscStrcat(multname,((PetscObject)A)->type_name);
    9860:     PetscStrcat(multname,"_");
    9861:     PetscStrcat(multname,((PetscObject)B)->type_name);
    9862:     PetscStrcat(multname,"_");
    9863:     PetscStrcat(multname,((PetscObject)C)->type_name);
    9864:     PetscStrcat(multname,"_C");
    9865:     PetscObjectQueryFunction((PetscObject)B,multname,&mult);
    9866:     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);
    9867:   }
    9868:   PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
    9869:   (*mult)(A,B,C,scall,fill,D);
    9870:   PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
    9871:   return(0);
    9872: }

    9876: /*@C
    9877:    MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.

    9879:    Collective on Mat

    9881:    Input Parameters:
    9882: +  mat - the matrix
    9883: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
    9884: .  subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
    9885: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    9887:    Output Parameter:
    9888: .  matredundant - redundant matrix

    9890:    Notes:
    9891:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the
    9892:    original matrix has not changed from that last call to MatCreateRedundantMatrix().

    9894:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
    9895:    calling it.

    9897:    Level: advanced

    9899:    Concepts: subcommunicator
    9900:    Concepts: duplicate matrix

    9902: .seealso: MatDestroy()
    9903: @*/
    9904: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
    9905: {
    9907:   MPI_Comm       comm;
    9908:   PetscMPIInt    size;
    9909:   PetscInt       mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
    9910:   Mat_Redundant  *redund=NULL;
    9911:   PetscSubcomm   psubcomm=NULL;
    9912:   MPI_Comm       subcomm_in=subcomm;
    9913:   Mat            *matseq;
    9914:   IS             isrow,iscol;
    9915:   PetscBool      newsubcomm=PETSC_FALSE;

    9918:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
    9919:   if (size == 1 || nsubcomm == 1) {
    9920:     if (reuse == MAT_INITIAL_MATRIX) {
    9921:       MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
    9922:     } else {
    9923:       MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
    9924:     }
    9925:     return(0);
    9926:   }

    9929:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
    9932:   }
    9933:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    9934:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    9935:   MatCheckPreallocated(mat,1);

    9937:   PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
    9938:   if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
    9939:     /* create psubcomm, then get subcomm */
    9940:     PetscObjectGetComm((PetscObject)mat,&comm);
    9941:     MPI_Comm_size(comm,&size);
    9942:     if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);

    9944:     PetscSubcommCreate(comm,&psubcomm);
    9945:     PetscSubcommSetNumber(psubcomm,nsubcomm);
    9946:     PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
    9947:     PetscSubcommSetFromOptions(psubcomm);
    9948:     PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
    9949:     newsubcomm = PETSC_TRUE;
    9950:     PetscSubcommDestroy(&psubcomm);
    9951:   }

    9953:   /* get isrow, iscol and a local sequential matrix matseq[0] */
    9954:   if (reuse == MAT_INITIAL_MATRIX) {
    9955:     mloc_sub = PETSC_DECIDE;
    9956:     if (bs < 1) {
    9957:       PetscSplitOwnership(subcomm,&mloc_sub,&M);
    9958:     } else {
    9959:       PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
    9960:     }
    9961:     MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
    9962:     rstart = rend - mloc_sub;
    9963:     ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
    9964:     ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
    9965:   } else { /* reuse == MAT_REUSE_MATRIX */
    9966:     /* retrieve subcomm */
    9967:     PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
    9968:     redund = (*matredundant)->redundant;
    9969:     isrow  = redund->isrow;
    9970:     iscol  = redund->iscol;
    9971:     matseq = redund->matseq;
    9972:   }
    9973:   MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);

    9975:   /* get matredundant over subcomm */
    9976:   if (reuse == MAT_INITIAL_MATRIX) {
    9977:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);

    9979:     /* create a supporting struct and attach it to C for reuse */
    9980:     PetscNewLog(*matredundant,&redund);
    9981:     (*matredundant)->redundant = redund;
    9982:     redund->isrow              = isrow;
    9983:     redund->iscol              = iscol;
    9984:     redund->matseq             = matseq;
    9985:     if (newsubcomm) {
    9986:       redund->subcomm          = subcomm;
    9987:     } else {
    9988:       redund->subcomm          = MPI_COMM_NULL;
    9989:     }
    9990:   } else {
    9991:     MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
    9992:   }
    9993:   PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
    9994:   return(0);
    9995: }

    9999: /*@C
    10000:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
    10001:    a given 'mat' object. Each submatrix can span multiple procs.

    10003:    Collective on Mat

    10005:    Input Parameters:
    10006: +  mat - the matrix
    10007: .  subcomm - the subcommunicator obtained by com_split(comm)
    10008: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    10010:    Output Parameter:
    10011: .  subMat - 'parallel submatrices each spans a given subcomm

    10013:   Notes:
    10014:   The submatrix partition across processors is dictated by 'subComm' a
    10015:   communicator obtained by com_split(comm). The comm_split
    10016:   is not restriced to be grouped with consecutive original ranks.

    10018:   Due the comm_split() usage, the parallel layout of the submatrices
    10019:   map directly to the layout of the original matrix [wrt the local
    10020:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
    10021:   into the 'DiagonalMat' of the subMat, hence it is used directly from
    10022:   the subMat. However the offDiagMat looses some columns - and this is
    10023:   reconstructed with MatSetValues()

    10025:   Level: advanced

    10027:   Concepts: subcommunicator
    10028:   Concepts: submatrices

    10030: .seealso: MatGetSubMatrices()
    10031: @*/
    10032: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
    10033: {
    10035:   PetscMPIInt    commsize,subCommSize;

    10038:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
    10039:   MPI_Comm_size(subComm,&subCommSize);
    10040:   if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);

    10042:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
    10043:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
    10044:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
    10045:   return(0);
    10046: }

    10050: /*@
    10051:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

    10053:    Not Collective

    10055:    Input Arguments:
    10056:    mat - matrix to extract local submatrix from
    10057:    isrow - local row indices for submatrix
    10058:    iscol - local column indices for submatrix

    10060:    Output Arguments:
    10061:    submat - the submatrix

    10063:    Level: intermediate

    10065:    Notes:
    10066:    The submat should be returned with MatRestoreLocalSubMatrix().

    10068:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
    10069:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

    10071:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
    10072:    MatSetValuesBlockedLocal() will also be implemented.

    10074:    The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
    10075:    matrices obtained with DMCreateMat() generally already have the local to global mapping provided.

    10077: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
    10078: @*/
    10079: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
    10080: {

    10089:   if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
    10090:
    10091:   if (mat->ops->getlocalsubmatrix) {
    10092:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
    10093:   } else {
    10094:     MatCreateLocalRef(mat,isrow,iscol,submat);
    10095:   }
    10096:   return(0);
    10097: }

    10101: /*@
    10102:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

    10104:    Not Collective

    10106:    Input Arguments:
    10107:    mat - matrix to extract local submatrix from
    10108:    isrow - local row indices for submatrix
    10109:    iscol - local column indices for submatrix
    10110:    submat - the submatrix

    10112:    Level: intermediate

    10114: .seealso: MatGetLocalSubMatrix()
    10115: @*/
    10116: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
    10117: {

    10126:   if (*submat) {
    10128:   }

    10130:   if (mat->ops->restorelocalsubmatrix) {
    10131:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
    10132:   } else {
    10133:     MatDestroy(submat);
    10134:   }
    10135:   *submat = NULL;
    10136:   return(0);
    10137: }

    10139: /* --------------------------------------------------------*/
    10142: /*@
    10143:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

    10145:    Collective on Mat

    10147:    Input Parameter:
    10148: .  mat - the matrix

    10150:    Output Parameter:
    10151: .  is - if any rows have zero diagonals this contains the list of them

    10153:    Level: developer

    10155:    Concepts: matrix-vector product

    10157: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    10158: @*/
    10159: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
    10160: {

    10166:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    10167:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    10169:   if (!mat->ops->findzerodiagonals) {
    10170:     Vec                diag;
    10171:     const PetscScalar *a;
    10172:     PetscInt          *rows;
    10173:     PetscInt           rStart, rEnd, r, nrow = 0;

    10175:     MatCreateVecs(mat, &diag, NULL);
    10176:     MatGetDiagonal(mat, diag);
    10177:     MatGetOwnershipRange(mat, &rStart, &rEnd);
    10178:     VecGetArrayRead(diag, &a);
    10179:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
    10180:     PetscMalloc1(nrow, &rows);
    10181:     nrow = 0;
    10182:     for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
    10183:     VecRestoreArrayRead(diag, &a);
    10184:     VecDestroy(&diag);
    10185:     ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
    10186:   } else {
    10187:     (*mat->ops->findzerodiagonals)(mat, is);
    10188:   }
    10189:   return(0);
    10190: }

    10194: /*@
    10195:    MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)

    10197:    Collective on Mat

    10199:    Input Parameter:
    10200: .  mat - the matrix

    10202:    Output Parameter:
    10203: .  is - contains the list of rows with off block diagonal entries

    10205:    Level: developer

    10207:    Concepts: matrix-vector product

    10209: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
    10210: @*/
    10211: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
    10212: {

    10218:   if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    10219:   if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

    10221:   if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
    10222:   (*mat->ops->findoffblockdiagonalentries)(mat,is);
    10223:   return(0);
    10224: }

    10228: /*@C
    10229:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

    10231:   Collective on Mat

    10233:   Input Parameters:
    10234: . mat - the matrix

    10236:   Output Parameters:
    10237: . values - the block inverses in column major order (FORTRAN-like)

    10239:    Note:
    10240:    This routine is not available from Fortran.

    10242:   Level: advanced
    10243: @*/
    10244: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
    10245: {

    10250:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
    10251:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
    10252:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
    10253:   (*mat->ops->invertblockdiagonal)(mat,values);
    10254:   return(0);
    10255: }

    10259: /*@C
    10260:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
    10261:     via MatTransposeColoringCreate().

    10263:     Collective on MatTransposeColoring

    10265:     Input Parameter:
    10266: .   c - coloring context

    10268:     Level: intermediate

    10270: .seealso: MatTransposeColoringCreate()
    10271: @*/
    10272: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
    10273: {
    10274:   PetscErrorCode       ierr;
    10275:   MatTransposeColoring matcolor=*c;

    10278:   if (!matcolor) return(0);
    10279:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

    10281:   PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
    10282:   PetscFree(matcolor->rows);
    10283:   PetscFree(matcolor->den2sp);
    10284:   PetscFree(matcolor->colorforcol);
    10285:   PetscFree(matcolor->columns);
    10286:   if (matcolor->brows>0) {
    10287:     PetscFree(matcolor->lstart);
    10288:   }
    10289:   PetscHeaderDestroy(c);
    10290:   return(0);
    10291: }

    10295: /*@C
    10296:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
    10297:     a MatTransposeColoring context has been created, computes a dense B^T by Apply
    10298:     MatTransposeColoring to sparse B.

    10300:     Collective on MatTransposeColoring

    10302:     Input Parameters:
    10303: +   B - sparse matrix B
    10304: .   Btdense - symbolic dense matrix B^T
    10305: -   coloring - coloring context created with MatTransposeColoringCreate()

    10307:     Output Parameter:
    10308: .   Btdense - dense matrix B^T

    10310:     Options Database Keys:
    10311: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
    10312: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
    10313: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

    10315:     Level: intermediate

    10317: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

    10319: .keywords: coloring
    10320: @*/
    10321: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
    10322: {

    10330:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
    10331:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
    10332:   return(0);
    10333: }

    10337: /*@C
    10338:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
    10339:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
    10340:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
    10341:     Csp from Cden.

    10343:     Collective on MatTransposeColoring

    10345:     Input Parameters:
    10346: +   coloring - coloring context created with MatTransposeColoringCreate()
    10347: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

    10349:     Output Parameter:
    10350: .   Csp - sparse matrix

    10352:     Options Database Keys:
    10353: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
    10354: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
    10355: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

    10357:     Level: intermediate

    10359: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

    10361: .keywords: coloring
    10362: @*/
    10363: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
    10364: {

    10372:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
    10373:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
    10374:   return(0);
    10375: }

    10379: /*@C
    10380:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

    10382:    Collective on Mat

    10384:    Input Parameters:
    10385: +  mat - the matrix product C
    10386: -  iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()

    10388:     Output Parameter:
    10389: .   color - the new coloring context

    10391:     Level: intermediate

    10393: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
    10394:            MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
    10395: @*/
    10396: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
    10397: {
    10398:   MatTransposeColoring c;
    10399:   MPI_Comm             comm;
    10400:   PetscErrorCode       ierr;

    10403:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
    10404:   PetscObjectGetComm((PetscObject)mat,&comm);
    10405:   PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);

    10407:   c->ctype = iscoloring->ctype;
    10408:   if (mat->ops->transposecoloringcreate) {
    10409:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
    10410:   } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");

    10412:   *color = c;
    10413:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
    10414:   return(0);
    10415: }

    10419: /*@
    10420:       MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
    10421:         matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
    10422:         same, otherwise it will be larger

    10424:      Not Collective

    10426:   Input Parameter:
    10427: .    A  - the matrix

    10429:   Output Parameter:
    10430: .    state - the current state

    10432:   Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
    10433:          different matrices

    10435:   Level: intermediate

    10437: @*/
    10438: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
    10439: {
    10442:   *state = mat->nonzerostate;
    10443:   return(0);
    10444: }

    10448: /*@
    10449:       MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
    10450:                  matrices from each processor

    10452:     Collective on MPI_Comm

    10454:    Input Parameters:
    10455: +    comm - the communicators the parallel matrix will live on
    10456: .    seqmat - the input sequential matrices
    10457: .    n - number of local columns (or PETSC_DECIDE)
    10458: -    reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

    10460:    Output Parameter:
    10461: .    mpimat - the parallel matrix generated

    10463:     Level: advanced

    10465:    Notes: The number of columns of the matrix in EACH processor MUST be the same.

    10467: @*/
    10468: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
    10469: {
    10471:   PetscMPIInt    size;

    10474:   MPI_Comm_size(comm,&size);
    10475:   if (size == 1) {
    10476:     if (reuse == MAT_INITIAL_MATRIX) {
    10477:       MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
    10478:     } else {
    10479:       MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
    10480:     }
    10481:     return(0);
    10482:   }

    10484:   if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
    10485:   PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
    10486:   (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
    10487:   PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
    10488:   return(0);
    10489: }

    10493: /*@
    10494:      MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
    10495:                  ranks' ownership ranges.

    10497:     Collective on A

    10499:    Input Parameters:
    10500: +    A   - the matrix to create subdomains from
    10501: -    N   - requested number of subdomains

    10504:    Output Parameters:
    10505: +    n   - number of subdomains resulting on this rank
    10506: -    iss - IS list with indices of subdomains on this rank

    10508:     Level: advanced

    10510:     Notes: number of subdomains must be smaller than the communicator size
    10511: @*/
    10512: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
    10513: {
    10514:   MPI_Comm        comm,subcomm;
    10515:   PetscMPIInt     size,rank,color;
    10516:   PetscInt        rstart,rend,k;
    10517:   PetscErrorCode  ierr;

    10520:   PetscObjectGetComm((PetscObject)A,&comm);
    10521:   MPI_Comm_size(comm,&size);
    10522:   MPI_Comm_rank(comm,&rank);
    10523:   if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
    10524:   *n = 1;
    10525:   k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
    10526:   color = rank/k;
    10527:   MPI_Comm_split(comm,color,rank,&subcomm);
    10528:   PetscMalloc1(1,iss);
    10529:   MatGetOwnershipRange(A,&rstart,&rend);
    10530:   ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
    10531:   MPI_Comm_free(&subcomm);
    10532:   return(0);
    10533: }