Actual source code: matrix.c

petsc-3.3-p3 2012-08-29
  2: /*
  3:    This is where the abstract matrix operations are defined
  4: */

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

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

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

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

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

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

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

 48:   Level: intermediate

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

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

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

 69:    Not Collective

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

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

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

 79:    Level: advanced

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

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

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

113:    Collective on Mat

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

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

121:    Level: advanced

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

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

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

142:    Logically Collective on Mat

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

147:    Level: advanced


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

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

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

177:    Collective on Mat

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

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

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

188:    Level: advanced

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

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


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

215:    Logically Collective on Mat

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

220:    Level: advanced


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

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

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

250:    Collective on Mat

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

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

259:    Level: advanced


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

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

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

285:    Not Collective

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

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

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

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

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

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

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

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


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

335:    Level: advanced

337:    Concepts: matrices^row access

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

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

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

365:    Logically Collective on Mat

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

370:    Level: advanced

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

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

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

400:    Not Collective

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

408:    Notes: 
409:    This routine should be called after you have finished examining the entries.

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

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

426:    Level: advanced

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

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

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

449:    Not Collective

451:    Input Parameters:
452: +  mat - the matrix

454:    Notes:
455:    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.

457:    Level: advanced

459:    Concepts: matrices^row access

461: .seealso: MatRestoreRowRowUpperTriangular()
462: @*/
463: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
464: {

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

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

483:    Not Collective

485:    Input Parameters:
486: +  mat - the matrix

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


492:    Level: advanced

494: .seealso:  MatGetRowUpperTriangular()
495: @*/
496: PetscErrorCode  MatRestoreRowUpperTriangular(Mat mat)
497: {

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

510: /*@C
511:    MatSetOptionsPrefix - Sets the prefix used for searching for all 
512:    Mat options in the database.

514:    Logically Collective on Mat

516:    Input Parameter:
517: +  A - the Mat context
518: -  prefix - the prefix to prepend to all option names

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

524:    Level: advanced

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

528: .seealso: MatSetFromOptions()
529: @*/
530: PetscErrorCode  MatSetOptionsPrefix(Mat A,const char prefix[])
531: {

536:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
537:   return(0);
538: }

542: /*@C
543:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all 
544:    Mat options in the database.

546:    Logically Collective on Mat

548:    Input Parameters:
549: +  A - the Mat context
550: -  prefix - the prefix to prepend to all option names

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

556:    Level: advanced

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

560: .seealso: MatGetOptionsPrefix()
561: @*/
562: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
563: {
565: 
568:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
569:   return(0);
570: }

574: /*@C
575:    MatGetOptionsPrefix - Sets the prefix used for searching for all 
576:    Mat options in the database.

578:    Not Collective

580:    Input Parameter:
581: .  A - the Mat context

583:    Output Parameter:
584: .  prefix - pointer to the prefix string used

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

589:    Level: advanced

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

593: .seealso: MatAppendOptionsPrefix()
594: @*/
595: PetscErrorCode  MatGetOptionsPrefix(Mat A,const char *prefix[])
596: {

601:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
602:   return(0);
603: }

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

610:    Collective on Mat

612:    Input Parameters:
613: .  A - the Mat context

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

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

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

622:    Level: beginner

624: .keywords: Mat, setup

626: .seealso: MatCreate(), MatDestroy()
627: @*/
628: PetscErrorCode  MatSetUp(Mat A)
629: {
630:   PetscMPIInt    size;

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


654: /*@C
655:    MatView - Visualizes a matrix object.

657:    Collective on Mat

659:    Input Parameters:
660: +  mat - the matrix
661: -  viewer - visualization context

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

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

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

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

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

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

718:    Concepts: matrices^viewing
719:    Concepts: matrices^plotting
720:    Concepts: matrices^printing

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

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

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

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

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

808:    Collective on PetscViewer

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

815:    Options Database Keys:
816:    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
817:    block size
818: .    -matload_block_size <bs>

820:    Level: beginner

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

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

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

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

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

849: $    int    MAT_FILE_CLASSID
850: $    int    number of rows
851: $    int    number of columns
852: $    int    total number of nonzeros
853: $    int    *number nonzeros in each row
854: $    int    *column indices of all nonzeros (starting index is zero)
855: $    PetscScalar *values of all nonzeros

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

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

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

867:  @*/
868: PetscErrorCode  MatLoad(Mat newmat,PetscViewer viewer)
869: {
871:   PetscBool      isbinary,flg;

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

879:   if (!((PetscObject)newmat)->type_name) {
880:     MatSetType(newmat,MATAIJ);
881:   }

883:   if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
884:   PetscLogEventBegin(MAT_Load,viewer,0,0,0);
885:   (*newmat->ops->load)(newmat,viewer);
886:   PetscLogEventEnd(MAT_Load,viewer,0,0,0);

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

904: /*@
905:    MatDestroy - Frees space taken by a matrix.

907:    Collective on Mat

909:    Input Parameter:
910: .  A - the matrix

912:    Level: beginner

914: @*/
915: PetscErrorCode  MatDestroy(Mat *A)
916: {

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

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

943:    Not Collective

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

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

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

960:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 
961:    options cannot be mixed without intervening calls to the assembly
962:    routines.

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

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

972:    Efficiency Alert:
973:    The routine MatSetValuesBlocked() may offer much better efficiency
974:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

976:    Level: beginner

978:    Concepts: matrices^putting entries in

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

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

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

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


1038: /*@ 
1039:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1040:         values into a matrix

1042:    Not Collective

1044:    Input Parameters:
1045: +  mat - the matrix
1046: .  row - the (block) row to set
1047: -  v - a logically two-dimensional array of values

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

1052:    All the nonzeros in the row must be provided

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

1056:    The row must belong to this process

1058:    Level: intermediate

1060:    Concepts: matrices^putting entries in

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

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

1084: /*@ 
1085:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1086:         values into a matrix

1088:    Not Collective

1090:    Input Parameters:
1091: +  mat - the matrix
1092: .  row - the (block) row to set
1093: -  v - a logically two-dimensional array of values

1095:    Notes:
1096:    The values, v, are column-oriented for the block version.

1098:    All the nonzeros in the row must be provided

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

1102:    The row must belong to this process

1104:    Level: advanced

1106:    Concepts: matrices^putting entries in

1108: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1109:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1110: @*/
1111: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1112: {

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

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

1144: /*@
1145:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1146:      Using structured grid indexing

1148:    Not Collective

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

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

1164:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 
1165:    options cannot be mixed without intervening calls to the assembly
1166:    routines.

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

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

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

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

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

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

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

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

1204:    Efficiency Alert:
1205:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1206:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1208:    Level: beginner

1210:    Concepts: matrices^putting entries in

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

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

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

1263: /*@C 
1264:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1265:      Using structured grid indexing

1267:    Not Collective

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

1280:    Notes:
1281:    By default the values, v, are row-oriented and unsorted.
1282:    See MatSetOption() for other options.

1284:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 
1285:    options cannot be mixed without intervening calls to the assembly
1286:    routines.

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

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

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

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

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

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

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

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

1320:    Level: beginner

1322:    Concepts: matrices^putting entries in

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

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

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

1381: /*@ 
1382:    MatSetStencil - Sets the grid information for setting values into a matrix via
1383:         MatSetValuesStencil()

1385:    Not Collective

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


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

1398:    For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1399:    user.
1400:    
1401:    Level: beginner

1403:    Concepts: matrices^putting entries in

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


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

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

1433:    Not Collective

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

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

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

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

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

1460:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
1461:    options cannot be mixed without intervening calls to the assembly
1462:    routines.

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

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

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

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

1493:    Level: intermediate

1495:    Concepts: matrices^putting entries in blocked

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

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

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

1556: /*@ 
1557:    MatGetValues - Gets a block of values from a matrix.

1559:    Not Collective; currently only returns a local block

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

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

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

1575:    MatGetValues() requires that the matrix has been assembled
1576:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1577:    MatSetValues() and MatGetValues() CANNOT be made in succession
1578:    without intermediate matrix assembly.

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

1583:    Level: advanced

1585:    Concepts: matrices^accessing values

1587: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1588: @*/
1589: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1590: {

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

1605:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1606:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1607:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1608:   return(0);
1609: }

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

1617:   Not Collective

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

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

1629:   Level: advanced

1631:   Concepts: matrices^putting entries in

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

1645: #if defined(PETSC_USE_DEBUG)
1646:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1647: #endif

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

1664: /*@
1665:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1666:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1667:    using a local (per-processor) numbering.

1669:    Not Collective

1671:    Input Parameters:
1672: +  x - the matrix
1673: .  rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1674:              or ISLocalToGlobalMappingCreateIS()
1675: - cmapping - column mapping

1677:    Level: intermediate

1679:    Concepts: matrices^local to global mapping
1680:    Concepts: local to global mapping^for matrices

1682: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1683: @*/
1684: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1685: {

1693:   if (x->ops->setlocaltoglobalmapping) {
1694:     (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1695:   } else {
1696:     PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1697:     PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1698:   }
1699:   return(0);
1700: }

1704: /*@
1705:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1706:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1707:    entries using a local (per-processor) numbering.

1709:    Not Collective

1711:    Input Parameters:
1712: +  x - the matrix
1713: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1714:              ISLocalToGlobalMappingCreateIS()
1715: - cmapping - column mapping

1717:    Level: intermediate

1719:    Concepts: matrices^local to global mapping blocked
1720:    Concepts: local to global mapping^for matrices, blocked

1722: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1723:            MatSetValuesBlocked(), MatSetValuesLocal()
1724: @*/
1725: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1726: {

1734:   PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1735:   PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1736:   return(0);
1737: }

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

1744:    Not Collective

1746:    Input Parameters:
1747: .  A - the matrix

1749:    Output Parameters:
1750: + rmapping - row mapping
1751: - cmapping - column mapping

1753:    Level: advanced

1755:    Concepts: matrices^local to global mapping
1756:    Concepts: local to global mapping^for matrices

1758: .seealso:  MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1759: @*/
1760: PetscErrorCode  MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1761: {
1767:   if (rmapping) *rmapping = A->rmap->mapping;
1768:   if (cmapping) *cmapping = A->cmap->mapping;
1769:   return(0);
1770: }

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

1777:    Not Collective

1779:    Input Parameters:
1780: .  A - the matrix

1782:    Output Parameters:
1783: + rmapping - row mapping
1784: - cmapping - column mapping

1786:    Level: advanced

1788:    Concepts: matrices^local to global mapping blocked
1789:    Concepts: local to global mapping^for matrices, blocked

1791: .seealso:  MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1792: @*/
1793: PetscErrorCode  MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1794: {
1800:   if (rmapping) *rmapping = A->rmap->bmapping;
1801:   if (cmapping) *cmapping = A->cmap->bmapping;
1802:   return(0);
1803: }

1807: /*@
1808:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1809:    using a local ordering of the nodes. 

1811:    Not Collective

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

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

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

1828:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
1829:    options cannot be mixed without intervening calls to the assembly
1830:    routines.

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

1835:    Level: intermediate

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

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

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

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

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

1898:    Not Collective

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

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

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

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

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

1923:    Level: intermediate

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

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

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

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

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

2003:    Collective on Mat and Vec

2005:    Input Parameters:
2006: +  mat - the matrix
2007: -  x   - the vector to be multiplied

2009:    Output Parameters:
2010: .  y - the result

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

2016:    Level: developer

2018:    Concepts: matrix-vector product

2020: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2021: @*/
2022: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2023: {


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

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

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

2049:    Neighbor-wise Collective on Mat and Vec

2051:    Input Parameters:
2052: +  mat - the matrix
2053: -  x   - the vector to be multiplied

2055:    Output Parameters:
2056: .  y - the result

2058:    Notes:
2059:    The vectors x and y cannot be the same.  I.e., one cannot
2060:    call MatMult(A,y,y).

2062:    Level: beginner

2064:    Concepts: matrix-vector product

2066: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2067: @*/
2068: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
2069: {

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

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

2098: /*@
2099:    MatMultTranspose - Computes matrix transpose times a vector.

2101:    Neighbor-wise Collective on Mat and Vec

2103:    Input Parameters:
2104: +  mat - the matrix
2105: -  x   - the vector to be multilplied

2107:    Output Parameters:
2108: .  y - the result

2110:    Notes:
2111:    The vectors x and y cannot be the same.  I.e., one cannot
2112:    call MatMultTranspose(A,y,y).

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

2117:    Level: beginner

2119:    Concepts: matrix vector product^transpose

2121: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2122: @*/
2123: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
2124: {


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

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

2154: /*@
2155:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

2157:    Neighbor-wise Collective on Mat and Vec

2159:    Input Parameters:
2160: +  mat - the matrix
2161: -  x   - the vector to be multilplied

2163:    Output Parameters:
2164: .  y - the result

2166:    Notes:
2167:    The vectors x and y cannot be the same.  I.e., one cannot
2168:    call MatMultHermitianTranspose(A,y,y).

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

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

2174:    Level: beginner

2176:    Concepts: matrix vector product^transpose

2178: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2179: @*/
2180: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2181: {
2183:   Vec            w;


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

2200:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2201:   if (mat->ops->multhermitiantranspose) {
2202:     (*mat->ops->multhermitiantranspose)(mat,x,y);
2203:   } else {
2204:     VecDuplicate(x,&w);
2205:     VecCopy(x,w);
2206:     VecConjugate(w);
2207:     MatMultTranspose(mat,w,y);
2208:     VecDestroy(&w);
2209:     VecConjugate(y);
2210:   }
2211:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2212:   PetscObjectStateIncrease((PetscObject)y);
2213:   return(0);
2214: }

2218: /*@
2219:     MatMultAdd -  Computes v3 = v2 + A * v1.

2221:     Neighbor-wise Collective on Mat and Vec

2223:     Input Parameters:
2224: +   mat - the matrix
2225: -   v1, v2 - the vectors

2227:     Output Parameters:
2228: .   v3 - the result

2230:     Notes:
2231:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2232:     call MatMultAdd(A,v1,v2,v1).

2234:     Level: beginner

2236:     Concepts: matrix vector product^addition

2238: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2239: @*/
2240: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2241: {


2251:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2252:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2253:   if (mat->cmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2254:   /* 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);
2255:      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); */
2256:   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);
2257:   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);
2258:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2259:   MatCheckPreallocated(mat,1);

2261:   if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2262:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2263:   (*mat->ops->multadd)(mat,v1,v2,v3);
2264:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2265:   PetscObjectStateIncrease((PetscObject)v3);
2266:   return(0);
2267: }

2271: /*@
2272:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2274:    Neighbor-wise Collective on Mat and Vec

2276:    Input Parameters:
2277: +  mat - the matrix
2278: -  v1, v2 - the vectors

2280:    Output Parameters:
2281: .  v3 - the result

2283:    Notes:
2284:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2285:    call MatMultTransposeAdd(A,v1,v2,v1).

2287:    Level: beginner

2289:    Concepts: matrix vector product^transpose and addition

2291: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2292: @*/
2293: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2294: {


2304:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2305:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2306:   if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2307:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2308:   if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2309:   if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2310:   if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2311:   MatCheckPreallocated(mat,1);

2313:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2314:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2315:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2316:   PetscObjectStateIncrease((PetscObject)v3);
2317:   return(0);
2318: }

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

2325:    Neighbor-wise Collective on Mat and Vec

2327:    Input Parameters:
2328: +  mat - the matrix
2329: -  v1, v2 - the vectors

2331:    Output Parameters:
2332: .  v3 - the result

2334:    Notes:
2335:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2336:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2338:    Level: beginner

2340:    Concepts: matrix vector product^transpose and addition

2342: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2343: @*/
2344: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2345: {


2355:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2356:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2357:   if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2358:   if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2359:   if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2360:   if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2361:   if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2362:   MatCheckPreallocated(mat,1);

2364:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2365:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2366:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2367:   PetscObjectStateIncrease((PetscObject)v3);
2368:   return(0);
2369: }

2373: /*@
2374:    MatMultConstrained - The inner multiplication routine for a
2375:    constrained matrix P^T A P.

2377:    Neighbor-wise Collective on Mat and Vec

2379:    Input Parameters:
2380: +  mat - the matrix
2381: -  x   - the vector to be multilplied

2383:    Output Parameters:
2384: .  y - the result

2386:    Notes:
2387:    The vectors x and y cannot be the same.  I.e., one cannot
2388:    call MatMult(A,y,y).

2390:    Level: beginner

2392: .keywords: matrix, multiply, matrix-vector product, constraint
2393: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2394: @*/
2395: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2396: {

2403:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2404:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2405:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2406:   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);
2407:   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);
2408:   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);

2410:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2411:   (*mat->ops->multconstrained)(mat,x,y);
2412:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2413:   PetscObjectStateIncrease((PetscObject)y);

2415:   return(0);
2416: }

2420: /*@
2421:    MatMultTransposeConstrained - The inner multiplication routine for a
2422:    constrained matrix P^T A^T P.

2424:    Neighbor-wise Collective on Mat and Vec

2426:    Input Parameters:
2427: +  mat - the matrix
2428: -  x   - the vector to be multilplied

2430:    Output Parameters:
2431: .  y - the result

2433:    Notes:
2434:    The vectors x and y cannot be the same.  I.e., one cannot
2435:    call MatMult(A,y,y).

2437:    Level: beginner

2439: .keywords: matrix, multiply, matrix-vector product, constraint
2440: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2441: @*/
2442: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2443: {

2450:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2451:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2452:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2453:   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);
2454:   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);

2456:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2457:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2458:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2459:   PetscObjectStateIncrease((PetscObject)y);

2461:   return(0);
2462: }

2466: /*@C
2467:    MatGetFactorType - gets the type of factorization it is

2469:    Note Collective
2470:    as the flag

2472:    Input Parameters:
2473: .  mat - the matrix

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

2478:     Level: intermediate

2480: .seealso:    MatFactorType, MatGetFactor()
2481: @*/
2482: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2483: {
2487:   *t = mat->factortype;
2488:   return(0);
2489: }

2491: /* ------------------------------------------------------------*/
2494: /*@C
2495:    MatGetInfo - Returns information about matrix storage (number of
2496:    nonzeros, memory, etc.).

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

2500:    Input Parameters:
2501: .  mat - the matrix

2503:    Output Parameters:
2504: +  flag - flag indicating the type of parameters to be returned
2505:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2506:    MAT_GLOBAL_SUM - sum over all processors)
2507: -  info - matrix information context

2509:    Notes:
2510:    The MatInfo context contains a variety of matrix data, including
2511:    number of nonzeros allocated and used, number of mallocs during
2512:    matrix assembly, etc.  Additional information for factored matrices
2513:    is provided (such as the fill ratio, number of mallocs during
2514:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2515:    when using the runtime options 
2516: $       -info -mat_view_info

2518:    Example for C/C++ Users:
2519:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2520:    data within the MatInfo context.  For example, 
2521: .vb
2522:       MatInfo info;
2523:       Mat     A;
2524:       double  mal, nz_a, nz_u;

2526:       MatGetInfo(A,MAT_LOCAL,&info);
2527:       mal  = info.mallocs;
2528:       nz_a = info.nz_allocated;
2529: .ve

2531:    Example for Fortran Users:
2532:    Fortran users should declare info as a double precision
2533:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2534:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2535:    a complete list of parameter names.
2536: .vb
2537:       double  precision info(MAT_INFO_SIZE)
2538:       double  precision mal, nz_a
2539:       Mat     A
2540:       integer ierr

2542:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2543:       mal = info(MAT_INFO_MALLOCS)
2544:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2545: .ve

2547:     Level: intermediate

2549:     Concepts: matrices^getting information on
2550:     
2551:     Developer Note: fortran interface is not autogenerated as the f90
2552:     interface defintion cannot be generated correctly [due to MatInfo]

2554: .seealso: MatStashGetInfo()
2555:  
2556: @*/
2557: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2558: {

2565:   if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2566:   MatCheckPreallocated(mat,1);
2567:   (*mat->ops->getinfo)(mat,flag,info);
2568:   return(0);
2569: }

2571: /* ----------------------------------------------------------*/

2575: /*@C
2576:    MatLUFactor - Performs in-place LU factorization of matrix.

2578:    Collective on Mat

2580:    Input Parameters:
2581: +  mat - the matrix
2582: .  row - row permutation
2583: .  col - column permutation
2584: -  info - options for factorization, includes 
2585: $          fill - expected fill as ratio of original fill.
2586: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2587: $                   Run with the option -info to determine an optimal value to use

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

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

2597:    Level: developer

2599:    Concepts: matrices^LU factorization

2601: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2602:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()

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

2607: @*/
2608: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2609: {
2611:   MatFactorInfo  tinfo;

2619:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2620:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2621:   if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2622:   MatCheckPreallocated(mat,1);
2623:   if (!info) {
2624:     MatFactorInfoInitialize(&tinfo);
2625:     info = &tinfo;
2626:   }

2628:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2629:   (*mat->ops->lufactor)(mat,row,col,info);
2630:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2631:   PetscObjectStateIncrease((PetscObject)mat);
2632:   return(0);
2633: }

2637: /*@C
2638:    MatILUFactor - Performs in-place ILU factorization of matrix.

2640:    Collective on Mat

2642:    Input Parameters:
2643: +  mat - the matrix
2644: .  row - row permutation
2645: .  col - column permutation
2646: -  info - structure containing 
2647: $      levels - number of levels of fill.
2648: $      expected fill - as ratio of original fill.
2649: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2650:                 missing diagonal entries)

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

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

2660:    Level: developer

2662:    Concepts: matrices^ILU factorization

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

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

2669: @*/
2670: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2671: {

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

2686:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2687:   (*mat->ops->ilufactor)(mat,row,col,info);
2688:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2689:   PetscObjectStateIncrease((PetscObject)mat);
2690:   return(0);
2691: }

2695: /*@C
2696:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2697:    Call this routine before calling MatLUFactorNumeric().

2699:    Collective on Mat

2701:    Input Parameters:
2702: +  fact - the factor matrix obtained with MatGetFactor()
2703: .  mat - the matrix
2704: .  row, col - row and column permutations
2705: -  info - options for factorization, includes 
2706: $          fill - expected fill as ratio of original fill.
2707: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2708: $                   Run with the option -info to determine an optimal value to use


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

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

2719:    Level: developer

2721:    Concepts: matrices^LU symbolic factorization

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

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

2728: @*/
2729: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2730: {

2740:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2741:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2742:   if (!(fact)->ops->lufactorsymbolic) {
2743:     const MatSolverPackage spackage;
2744:     MatFactorGetSolverPackage(fact,&spackage);
2745:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2746:   }
2747:   MatCheckPreallocated(mat,2);

2749:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2750:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2751:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2752:   PetscObjectStateIncrease((PetscObject)fact);
2753:   return(0);
2754: }

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

2762:    Collective on Mat

2764:    Input Parameters:
2765: +  fact - the factor matrix obtained with MatGetFactor()
2766: .  mat - the matrix
2767: -  info - options for factorization

2769:    Notes:
2770:    See MatLUFactor() for in-place factorization.  See 
2771:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

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

2777:    Level: developer

2779:    Concepts: matrices^LU numeric factorization

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

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

2786: @*/
2787: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2788: {

2796:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2797:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2798:     SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2799:   }
2800:   if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2801:   MatCheckPreallocated(mat,2);
2802:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2803:   (fact->ops->lufactornumeric)(fact,mat,info);
2804:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

2806:   MatView_Private(fact);
2807:   PetscObjectStateIncrease((PetscObject)fact);
2808:   return(0);
2809: }

2813: /*@C
2814:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2815:    symmetric matrix. 

2817:    Collective on Mat

2819:    Input Parameters:
2820: +  mat - the matrix
2821: .  perm - row and column permutations
2822: -  f - expected fill as ratio of original fill

2824:    Notes:
2825:    See MatLUFactor() for the nonsymmetric case.  See also
2826:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2832:    Level: developer

2834:    Concepts: matrices^Cholesky factorization

2836: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2837:           MatGetOrdering()

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

2842: @*/
2843: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2844: {

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

2858:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2859:   (*mat->ops->choleskyfactor)(mat,perm,info);
2860:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2861:   PetscObjectStateIncrease((PetscObject)mat);
2862:   return(0);
2863: }

2867: /*@C
2868:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2869:    of a symmetric matrix. 

2871:    Collective on Mat

2873:    Input Parameters:
2874: +  fact - the factor matrix obtained with MatGetFactor()
2875: .  mat - the matrix
2876: .  perm - row and column permutations
2877: -  info - options for factorization, includes 
2878: $          fill - expected fill as ratio of original fill.
2879: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2880: $                   Run with the option -info to determine an optimal value to use

2882:    Notes:
2883:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2884:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2890:    Level: developer

2892:    Concepts: matrices^Cholesky symbolic factorization

2894: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2895:           MatGetOrdering()

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

2900: @*/
2901: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2902: {

2911:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square");
2912:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2913:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2914:   if (!(fact)->ops->choleskyfactorsymbolic) {
2915:     const MatSolverPackage spackage;
2916:     MatFactorGetSolverPackage(fact,&spackage);
2917:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
2918:   }
2919:   MatCheckPreallocated(mat,2);

2921:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2922:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2923:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2924:   PetscObjectStateIncrease((PetscObject)fact);
2925:   return(0);
2926: }

2930: /*@C
2931:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2932:    of a symmetric matrix. Call this routine after first calling
2933:    MatCholeskyFactorSymbolic().

2935:    Collective on Mat

2937:    Input Parameters:
2938: +  fact - the factor matrix obtained with MatGetFactor()
2939: .  mat - the initial matrix
2940: .  info - options for factorization
2941: -  fact - the symbolic factor of mat


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

2949:    Level: developer

2951:    Concepts: matrices^Cholesky numeric factorization

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

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

2958: @*/
2959: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2960: {

2968:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2969:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
2970:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2971:     SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N);
2972:   }
2973:   MatCheckPreallocated(mat,2);

2975:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2976:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
2977:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

2979:   MatView_Private(fact);
2980:   PetscObjectStateIncrease((PetscObject)fact);
2981:   return(0);
2982: }

2984: /* ----------------------------------------------------------------*/
2987: /*@
2988:    MatSolve - Solves A x = b, given a factored matrix.

2990:    Neighbor-wise Collective on Mat and Vec

2992:    Input Parameters:
2993: +  mat - the factored matrix
2994: -  b - the right-hand-side vector

2996:    Output Parameter:
2997: .  x - the result vector

2999:    Notes:
3000:    The vectors b and x cannot be the same.  I.e., one cannot
3001:    call MatSolve(A,x,x).

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

3008:    Level: developer

3010:    Concepts: matrices^triangular solves

3012: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3013: @*/
3014: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
3015: {

3025:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3026:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3027:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3028:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3029:   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);
3030:   if (!mat->rmap->N && !mat->cmap->N) return(0);
3031:   if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3032:   MatCheckPreallocated(mat,1);

3034:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3035:   (*mat->ops->solve)(mat,b,x);
3036:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3037:   PetscObjectStateIncrease((PetscObject)x);
3038:   return(0);
3039: }

3043: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
3044: {
3046:   Vec            b,x;
3047:   PetscInt       m,N,i;
3048:   PetscScalar    *bb,*xx;
3049:   PetscBool      flg;

3052:   PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3053:   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3054:   PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);
3055:   if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");

3057:   MatGetArray(B,&bb);
3058:   MatGetArray(X,&xx);
3059:   MatGetLocalSize(B,&m,PETSC_NULL);  /* number local rows */
3060:   MatGetSize(B,PETSC_NULL,&N);       /* total columns in dense matrix */
3061:   MatGetVecs(A,&x,&b);
3062:   for (i=0; i<N; i++) {
3063:     VecPlaceArray(b,bb + i*m);
3064:     VecPlaceArray(x,xx + i*m);
3065:     MatSolve(A,b,x);
3066:     VecResetArray(x);
3067:     VecResetArray(b);
3068:   }
3069:   VecDestroy(&b);
3070:   VecDestroy(&x);
3071:   MatRestoreArray(B,&bb);
3072:   MatRestoreArray(X,&xx);
3073:   return(0);
3074: }

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

3081:    Neighbor-wise Collective on Mat 

3083:    Input Parameters:
3084: +  mat - the factored matrix
3085: -  B - the right-hand-side matrix  (dense matrix)

3087:    Output Parameter:
3088: .  X - the result matrix (dense matrix)

3090:    Notes:
3091:    The matrices b and x cannot be the same.  I.e., one cannot
3092:    call MatMatSolve(A,x,x).

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

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

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

3105:    Level: developer

3107:    Concepts: matrices^triangular solves

3109: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3110: @*/
3111: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
3112: {

3122:   if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3123:   if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3124:   if (A->cmap->N != X->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
3125:   if (A->rmap->N != B->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
3126:   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);
3127:   if (!A->rmap->N && !A->cmap->N) return(0);
3128:   MatCheckPreallocated(A,1);

3130:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3131:   if (!A->ops->matsolve) {
3132:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3133:     MatMatSolve_Basic(A,B,X);
3134:   } else {
3135:     (*A->ops->matsolve)(A,B,X);
3136:   }
3137:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3138:   PetscObjectStateIncrease((PetscObject)X);
3139:   return(0);
3140: }


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

3149:    Neighbor-wise Collective on Mat and Vec

3151:    Input Parameters:
3152: +  mat - the factored matrix
3153: -  b - the right-hand-side vector

3155:    Output Parameter:
3156: .  x - the result vector

3158:    Notes:
3159:    MatSolve() should be used for most applications, as it performs
3160:    a forward solve followed by a backward solve.

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

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

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

3175:    Level: developer

3177:    Concepts: matrices^forward solves

3179: .seealso: MatSolve(), MatBackwardSolve()
3180: @*/
3181: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
3182: {

3192:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3193:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3194:   if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3195:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3196:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3197:   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);
3198:   MatCheckPreallocated(mat,1);
3199:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3200:   (*mat->ops->forwardsolve)(mat,b,x);
3201:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3202:   PetscObjectStateIncrease((PetscObject)x);
3203:   return(0);
3204: }

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

3212:    Neighbor-wise Collective on Mat and Vec

3214:    Input Parameters:
3215: +  mat - the factored matrix
3216: -  b - the right-hand-side vector

3218:    Output Parameter:
3219: .  x - the result vector

3221:    Notes:
3222:    MatSolve() should be used for most applications, as it performs
3223:    a forward solve followed by a backward solve.

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

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

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

3238:    Level: developer

3240:    Concepts: matrices^backward solves

3242: .seealso: MatSolve(), MatForwardSolve()
3243: @*/
3244: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3245: {

3255:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3256:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3257:   if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3258:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3259:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3260:   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);
3261:   MatCheckPreallocated(mat,1);

3263:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3264:   (*mat->ops->backwardsolve)(mat,b,x);
3265:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3266:   PetscObjectStateIncrease((PetscObject)x);
3267:   return(0);
3268: }

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

3275:    Neighbor-wise Collective on Mat and Vec

3277:    Input Parameters:
3278: +  mat - the factored matrix
3279: .  b - the right-hand-side vector
3280: -  y - the vector to be added to 

3282:    Output Parameter:
3283: .  x - the result vector

3285:    Notes:
3286:    The vectors b and x cannot be the same.  I.e., one cannot
3287:    call MatSolveAdd(A,x,y,x).

3289:    Most users should 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().

3293:    Level: developer

3295:    Concepts: matrices^triangular solves

3297: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3298: @*/
3299: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3300: {
3301:   PetscScalar    one = 1.0;
3302:   Vec            tmp;

3314:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3315:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3316:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3317:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3318:   if (mat->rmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3319:   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);
3320:   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);
3321:   MatCheckPreallocated(mat,1);

3323:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3324:   if (mat->ops->solveadd)  {
3325:     (*mat->ops->solveadd)(mat,b,y,x);
3326:   } else {
3327:     /* do the solve then the add manually */
3328:     if (x != y) {
3329:       MatSolve(mat,b,x);
3330:       VecAXPY(x,one,y);
3331:     } else {
3332:       VecDuplicate(x,&tmp);
3333:       PetscLogObjectParent(mat,tmp);
3334:       VecCopy(x,tmp);
3335:       MatSolve(mat,b,x);
3336:       VecAXPY(x,one,tmp);
3337:       VecDestroy(&tmp);
3338:     }
3339:   }
3340:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3341:   PetscObjectStateIncrease((PetscObject)x);
3342:   return(0);
3343: }

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

3350:    Neighbor-wise Collective on Mat and Vec

3352:    Input Parameters:
3353: +  mat - the factored matrix
3354: -  b - the right-hand-side vector

3356:    Output Parameter:
3357: .  x - the result vector

3359:    Notes:
3360:    The vectors b and x cannot be the same.  I.e., one cannot
3361:    call MatSolveTranspose(A,x,x).

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

3367:    Level: developer

3369:    Concepts: matrices^triangular solves

3371: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3372: @*/
3373: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3374: {

3384:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3385:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3386:   if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3387:   if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3388:   if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3389:   MatCheckPreallocated(mat,1);
3390:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3391:   (*mat->ops->solvetranspose)(mat,b,x);
3392:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3393:   PetscObjectStateIncrease((PetscObject)x);
3394:   return(0);
3395: }

3399: /*@
3400:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
3401:                       factored matrix. 

3403:    Neighbor-wise Collective on Mat and Vec

3405:    Input Parameters:
3406: +  mat - the factored matrix
3407: .  b - the right-hand-side vector
3408: -  y - the vector to be added to 

3410:    Output Parameter:
3411: .  x - the result vector

3413:    Notes:
3414:    The vectors b and x cannot be the same.  I.e., one cannot
3415:    call MatSolveTransposeAdd(A,x,y,x).

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

3421:    Level: developer

3423:    Concepts: matrices^triangular solves

3425: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3426: @*/
3427: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3428: {
3429:   PetscScalar    one = 1.0;
3431:   Vec            tmp;

3442:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3443:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3444:   if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3445:   if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3446:   if (mat->cmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3447:   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);
3448:   MatCheckPreallocated(mat,1);

3450:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3451:   if (mat->ops->solvetransposeadd) {
3452:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3453:   } else {
3454:     /* do the solve then the add manually */
3455:     if (x != y) {
3456:       MatSolveTranspose(mat,b,x);
3457:       VecAXPY(x,one,y);
3458:     } else {
3459:       VecDuplicate(x,&tmp);
3460:       PetscLogObjectParent(mat,tmp);
3461:       VecCopy(x,tmp);
3462:       MatSolveTranspose(mat,b,x);
3463:       VecAXPY(x,one,tmp);
3464:       VecDestroy(&tmp);
3465:     }
3466:   }
3467:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3468:   PetscObjectStateIncrease((PetscObject)x);
3469:   return(0);
3470: }
3471: /* ----------------------------------------------------------------*/

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

3478:    Neighbor-wise Collective on Mat and Vec

3480:    Input Parameters:
3481: +  mat - the matrix
3482: .  b - the right hand side
3483: .  omega - the relaxation factor
3484: .  flag - flag indicating the type of SOR (see below)
3485: .  shift -  diagonal shift
3486: .  its - the number of iterations
3487: -  lits - the number of local iterations 

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

3492:    SOR Flags:
3493: .     SOR_FORWARD_SWEEP - forward SOR
3494: .     SOR_BACKWARD_SWEEP - backward SOR
3495: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3496: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
3497: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
3498: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3499: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
3500:          upper/lower triangular part of matrix to
3501:          vector (with omega)
3502: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3504:    Notes:
3505:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3506:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3507:    on each processor. 

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

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

3514:    Notes for Advanced Users:
3515:    The flags are implemented as bitwise inclusive or operations.
3516:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3517:    to specify a zero initial guess for SSOR.

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

3523:    Vectors x and b CANNOT be the same

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

3527:    Level: developer

3529:    Concepts: matrices^relaxation
3530:    Concepts: matrices^SOR
3531:    Concepts: matrices^Gauss-Seidel

3533: @*/
3534: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3535: {

3545:   if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3546:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3547:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3548:   if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3549:   if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3550:   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);
3551:   if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3552:   if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3553:   if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");

3555:   MatCheckPreallocated(mat,1);
3556:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3557:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3558:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3559:   PetscObjectStateIncrease((PetscObject)x);
3560:   return(0);
3561: }

3565: /*
3566:       Default matrix copy routine.
3567: */
3568: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3569: {
3570:   PetscErrorCode    ierr;
3571:   PetscInt          i,rstart = 0,rend = 0,nz;
3572:   const PetscInt    *cwork;
3573:   const PetscScalar *vwork;

3576:   if (B->assembled) {
3577:     MatZeroEntries(B);
3578:   }
3579:   MatGetOwnershipRange(A,&rstart,&rend);
3580:   for (i=rstart; i<rend; i++) {
3581:     MatGetRow(A,i,&nz,&cwork,&vwork);
3582:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3583:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3584:   }
3585:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3586:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3587:   PetscObjectStateIncrease((PetscObject)B);
3588:   return(0);
3589: }

3593: /*@
3594:    MatCopy - Copys a matrix to another matrix.

3596:    Collective on Mat

3598:    Input Parameters:
3599: +  A - the matrix
3600: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3602:    Output Parameter:
3603: .  B - where the copy is put

3605:    Notes:
3606:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
3607:    same nonzero pattern or the routine will crash.

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

3613:    Level: intermediate
3614:    
3615:    Concepts: matrices^copying

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

3619: @*/
3620: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3621: {
3623:   PetscInt       i;

3631:   MatCheckPreallocated(B,2);
3632:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3633:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3634:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
3635:   MatCheckPreallocated(A,1);

3637:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3638:   if (A->ops->copy) {
3639:     (*A->ops->copy)(A,B,str);
3640:   } else { /* generic conversion */
3641:     MatCopy_Basic(A,B,str);
3642:   }

3644:   B->stencil.dim = A->stencil.dim;
3645:   B->stencil.noc = A->stencil.noc;
3646:   for (i=0; i<=A->stencil.dim; i++) {
3647:     B->stencil.dims[i]   = A->stencil.dims[i];
3648:     B->stencil.starts[i] = A->stencil.starts[i];
3649:   }

3651:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3652:   PetscObjectStateIncrease((PetscObject)B);
3653:   return(0);
3654: }

3658: /*@C  
3659:    MatConvert - Converts a matrix to another matrix, either of the same
3660:    or different type.

3662:    Collective on Mat

3664:    Input Parameters:
3665: +  mat - the matrix
3666: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3667:    same type as the original matrix.
3668: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3669:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3670:    MAT_INITIAL_MATRIX.

3672:    Output Parameter:
3673: .  M - pointer to place new matrix

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

3680:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3681:    the MPI communicator of the generated matrix is always the same as the communicator
3682:    of the input matrix.

3684:    Level: intermediate

3686:    Concepts: matrices^converting between storage formats

3688: .seealso: MatCopy(), MatDuplicate()
3689: @*/
3690: PetscErrorCode  MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3691: {
3692:   PetscErrorCode         ierr;
3693:   PetscBool              sametype,issame,flg;
3694:   char                   convname[256],mtype[256];
3695:   Mat                    B;

3701:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3702:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3703:   MatCheckPreallocated(mat,1);
3704:   MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);

3706:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3707:   if (flg) {
3708:     newtype = mtype;
3709:   }
3710:   PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3711:   PetscStrcmp(newtype,"same",&issame);
3712:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");

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

3744:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3745:     MatCreate(((PetscObject)mat)->comm,&B);
3746:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3747:     MatSetType(B,newtype);
3748:     for (i=0; i<3; i++) {
3749:       PetscStrcpy(convname,"MatConvert_");
3750:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3751:       PetscStrcat(convname,"_");
3752:       PetscStrcat(convname,prefix[i]);
3753:       PetscStrcat(convname,newtype);
3754:       PetscStrcat(convname,"_C");
3755:       PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3756:       if (conv) {
3757:         MatDestroy(&B);
3758:         goto foundconv;
3759:       }
3760:     }

3762:     /* 3) See if a good general converter is registered for the desired class */
3763:     conv = B->ops->convertfrom;
3764:     MatDestroy(&B);
3765:     if (conv) goto foundconv;

3767:     /* 4) See if a good general converter is known for the current matrix */
3768:     if (mat->ops->convert) {
3769:       conv = mat->ops->convert;
3770:     }
3771:     if (conv) goto foundconv;

3773:     /* 5) Use a really basic converter. */
3774:     conv = MatConvert_Basic;

3776:     foundconv:
3777:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3778:     (*conv)(mat,newtype,reuse,M);
3779:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3780:   }
3781:   PetscObjectStateIncrease((PetscObject)*M);

3783:   /* Copy Mat options */
3784:   if (mat->symmetric){MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3785:   if (mat->hermitian){MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3786:   return(0);
3787: }

3791: /*@C  
3792:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3794:    Not Collective

3796:    Input Parameter:
3797: .  mat - the matrix, must be a factored matrix

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

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

3806:    Level: intermediate

3808: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3809: @*/
3810: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3811: {
3812:   PetscErrorCode         ierr;
3813:   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);

3818:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3819:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3820:   if (!conv) {
3821:     *type = MATSOLVERPETSC;
3822:   } else {
3823:     (*conv)(mat,type);
3824:   }
3825:   return(0);
3826: }

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

3833:    Collective on Mat

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

3840:    Output Parameters:
3841: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

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

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

3849:    Level: intermediate

3851: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3852: @*/
3853: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3854: {
3855:   PetscErrorCode  ierr,(*conv)(Mat,MatFactorType,Mat*);
3856:   char            convname[256];


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

3865:   PetscStrcpy(convname,"MatGetFactor_");
3866:   PetscStrcat(convname,type);
3867:   PetscStrcat(convname,"_C");
3868:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3869:   if (!conv) {
3870:     PetscBool  flag;
3871:     MPI_Comm   comm;

3873:     PetscObjectGetComm((PetscObject)mat,&comm);
3874:     PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3875:     if (flag) {
3876:       SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3877:     } else {
3878:       SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type);
3879:     }
3880:   }
3881:   (*conv)(mat,ftype,f);
3882:   return(0);
3883: }

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

3890:    Not Collective

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

3897:    Output Parameter:
3898: .    flg - PETSC_TRUE if the factorization is available

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

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

3906:    Level: intermediate

3908: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3909: @*/
3910: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool  *flg)
3911: {
3912:   PetscErrorCode         ierr;
3913:   char                   convname[256];
3914:   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscBool *);


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

3923:   PetscStrcpy(convname,"MatGetFactorAvailable_");
3924:   PetscStrcat(convname,type);
3925:   PetscStrcat(convname,"_C");
3926:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3927:   if (!conv) {
3928:     *flg = PETSC_FALSE;
3929:   } else {
3930:     (*conv)(mat,ftype,flg);
3931:   }
3932:   return(0);
3933: }


3938: /*@
3939:    MatDuplicate - Duplicates a matrix including the non-zero structure.

3941:    Collective on Mat

3943:    Input Parameters:
3944: +  mat - the matrix
3945: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3946:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

3948:    Output Parameter:
3949: .  M - pointer to place new matrix

3951:    Level: intermediate

3953:    Concepts: matrices^duplicating

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

3957: .seealso: MatCopy(), MatConvert()
3958: @*/
3959: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3960: {
3962:   Mat            B;
3963:   PetscInt       i;

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

3973:   *M  = 0;
3974:   if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type");
3975:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3976:   (*mat->ops->duplicate)(mat,op,M);
3977:   B = *M;
3978: 
3979:   B->stencil.dim = mat->stencil.dim;
3980:   B->stencil.noc = mat->stencil.noc;
3981:   for (i=0; i<=mat->stencil.dim; i++) {
3982:     B->stencil.dims[i]   = mat->stencil.dims[i];
3983:     B->stencil.starts[i] = mat->stencil.starts[i];
3984:   }

3986:   B->nooffproczerorows = mat->nooffproczerorows;
3987:   B->nooffprocentries  = mat->nooffprocentries;
3988:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3989:   PetscObjectStateIncrease((PetscObject)B);
3990:   return(0);
3991: }

3995: /*@
3996:    MatGetDiagonal - Gets the diagonal of a matrix.

3998:    Logically Collective on Mat and Vec

4000:    Input Parameters:
4001: +  mat - the matrix
4002: -  v - the vector for storing the diagonal

4004:    Output Parameter:
4005: .  v - the diagonal of the matrix

4007:    Level: intermediate

4009:    Note:
4010:    Currently only correct in parallel for square matrices.

4012:    Concepts: matrices^accessing diagonals

4014: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4015: @*/
4016: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
4017: {

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

4028:   (*mat->ops->getdiagonal)(mat,v);
4029:   PetscObjectStateIncrease((PetscObject)v);
4030:   return(0);
4031: }

4035: /*@ 
4036:    MatGetRowMin - Gets the minimum value (of the real part) of each
4037:         row of the matrix

4039:    Logically Collective on Mat and Vec

4041:    Input Parameters:
4042: .  mat - the matrix

4044:    Output Parameter:
4045: +  v - the vector for storing the maximums
4046: -  idx - the indices of the column found for each row (optional)

4048:    Level: intermediate

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

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

4055:    Concepts: matrices^getting row maximums

4057: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4058:           MatGetRowMax()
4059: @*/
4060: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4061: {

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

4072:   (*mat->ops->getrowmin)(mat,v,idx);
4073:   PetscObjectStateIncrease((PetscObject)v);
4074:   return(0);
4075: }

4079: /*@ 
4080:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4081:         row of the matrix

4083:    Logically Collective on Mat and Vec

4085:    Input Parameters:
4086: .  mat - the matrix

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

4092:    Level: intermediate

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

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

4099:    Concepts: matrices^getting row maximums

4101: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4102: @*/
4103: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4104: {

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

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

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

4127:    Logically Collective on Mat and Vec

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

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

4136:    Level: intermediate

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

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

4143:    Concepts: matrices^getting row maximums

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

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

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

4166: /*@ 
4167:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4168:         row of the matrix

4170:    Logically Collective on Mat and Vec

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

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

4179:    Level: intermediate

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

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

4186:    Concepts: matrices^getting row maximums

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

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

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

4210: /*@ 
4211:    MatGetRowSum - Gets the sum of each row of the matrix

4213:    Logically Collective on Mat and Vec

4215:    Input Parameters:
4216: .  mat - the matrix

4218:    Output Parameter:
4219: .  v - the vector for storing the sum of rows

4221:    Level: intermediate

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

4225:    Concepts: matrices^getting row sums

4227: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4228: @*/
4229: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4230: {
4231:   PetscInt       start = 0, end = 0, row;
4232:   PetscScalar   *array;

4239:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4240:   MatCheckPreallocated(mat,1);
4241:   MatGetOwnershipRange(mat, &start, &end);
4242:   VecGetArray(v, &array);
4243:   for(row = start; row < end; ++row) {
4244:     PetscInt           ncols, col;
4245:     const PetscInt    *cols;
4246:     const PetscScalar *vals;

4248:     array[row - start] = 0.0;
4249:     MatGetRow(mat, row, &ncols, &cols, &vals);
4250:     for(col = 0; col < ncols; col++) {
4251:       array[row - start] += vals[col];
4252:     }
4253:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4254:   }
4255:   VecRestoreArray(v, &array);
4256:   PetscObjectStateIncrease((PetscObject) v);
4257:   return(0);
4258: }

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

4265:    Collective on Mat

4267:    Input Parameter:
4268: +  mat - the matrix to transpose
4269: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

4271:    Output Parameters:
4272: .  B - the transpose 

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

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

4279:    Level: intermediate

4281:    Concepts: matrices^transposing

4283: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4284: @*/
4285: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4286: {

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

4297:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4298:   (*mat->ops->transpose)(mat,reuse,B);
4299:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4300:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4301:   return(0);
4302: }

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

4310:    Collective on Mat

4312:    Input Parameter:
4313: +  A - the matrix to test
4314: -  B - the matrix to test against, this can equal the first parameter

4316:    Output Parameters:
4317: .  flg - the result

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

4324:    Level: intermediate

4326:    Concepts: matrices^transposing, matrix^symmetry

4328: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4329: @*/
4330: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool  *flg)
4331: {
4332:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *);

4338:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4339:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4340:   *flg = PETSC_FALSE;
4341:   if (f && g) {
4342:     if (f == g) {
4343:       (*f)(A,B,tol,flg);
4344:     } else {
4345:       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4346:     }
4347:   } else {
4348:     const MatType mattype;
4349:     if (!f) {MatGetType(A,&mattype);}
4350:     else    {MatGetType(B,&mattype);}
4351:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4352:   }
4353:   return(0);
4354: }

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

4361:    Collective on Mat

4363:    Input Parameter:
4364: +  mat - the matrix to transpose and complex conjugate
4365: -  reuse - store the transpose matrix in the provided B

4367:    Output Parameters:
4368: .  B - the Hermitian

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

4373:    Level: intermediate

4375:    Concepts: matrices^transposing, complex conjugatex

4377: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4378: @*/
4379: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4380: {

4384:   MatTranspose(mat,reuse,B);
4385: #if defined(PETSC_USE_COMPLEX)
4386:   MatConjugate(*B);
4387: #endif
4388:   return(0);
4389: }

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

4396:    Collective on Mat

4398:    Input Parameter:
4399: +  A - the matrix to test
4400: -  B - the matrix to test against, this can equal the first parameter

4402:    Output Parameters:
4403: .  flg - the result

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

4410:    Level: intermediate

4412:    Concepts: matrices^transposing, matrix^symmetry

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

4424:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4425:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4426:   if (f && g) {
4427:     if (f==g) {
4428:       (*f)(A,B,tol,flg);
4429:     } else {
4430:       SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4431:     }
4432:   }
4433:   return(0);
4434: }

4438: /*@
4439:    MatPermute - Creates a new matrix with rows and columns permuted from the 
4440:    original.

4442:    Collective on Mat

4444:    Input Parameters:
4445: +  mat - the matrix to permute
4446: .  row - row permutation, each processor supplies only the permutation for its rows
4447: -  col - column permutation, each processor needs the entire column permutation, that is
4448:          this is the same size as the total number of columns in the matrix. It can often
4449:          be obtained with ISAllGather() on the row permutation

4451:    Output Parameters:
4452: .  B - the permuted matrix

4454:    Level: advanced

4456:    Concepts: matrices^permuting

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

4460: @*/
4461: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4462: {

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

4476:   (*mat->ops->permute)(mat,row,col,B);
4477:   PetscObjectStateIncrease((PetscObject)*B);
4478:   return(0);
4479: }

4483: /*@
4484:    MatEqual - Compares two matrices.

4486:    Collective on Mat

4488:    Input Parameters:
4489: +  A - the first matrix
4490: -  B - the second matrix

4492:    Output Parameter:
4493: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4495:    Level: intermediate

4497:    Concepts: matrices^equality between
4498: @*/
4499: PetscErrorCode  MatEqual(Mat A,Mat B,PetscBool  *flg)
4500: {

4510:   MatCheckPreallocated(B,2);
4511:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4512:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4513:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N);
4514:   if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4515:   if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4516:   if (A->ops->equal != B->ops->equal) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4517:   MatCheckPreallocated(A,1);

4519:   (*A->ops->equal)(A,B,flg);
4520:   return(0);
4521: }

4525: /*@
4526:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4527:    matrices that are stored as vectors.  Either of the two scaling
4528:    matrices can be PETSC_NULL.

4530:    Collective on Mat

4532:    Input Parameters:
4533: +  mat - the matrix to be scaled
4534: .  l - the left scaling vector (or PETSC_NULL)
4535: -  r - the right scaling vector (or PETSC_NULL)

4537:    Notes:
4538:    MatDiagonalScale() computes A = LAR, where
4539:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4540:    The L scales the rows of the matrix, the R scales the columns of the matrix.

4542:    Level: intermediate

4544:    Concepts: matrices^diagonal scaling
4545:    Concepts: diagonal scaling of matrices

4547: .seealso: MatScale()
4548: @*/
4549: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4550: {

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

4563:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4564:   (*mat->ops->diagonalscale)(mat,l,r);
4565:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4566:   PetscObjectStateIncrease((PetscObject)mat);
4567: #if defined(PETSC_HAVE_CUSP)
4568:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4569:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4570:   }
4571: #endif
4572:   return(0);
4573: }

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

4580:     Logically Collective on Mat

4582:     Input Parameters:
4583: +   mat - the matrix to be scaled
4584: -   a  - the scaling value

4586:     Output Parameter:
4587: .   mat - the scaled matrix

4589:     Level: intermediate

4591:     Concepts: matrices^scaling all entries

4593: .seealso: MatDiagonalScale()
4594: @*/
4595: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4596: {

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

4608:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4609:   if (a != (PetscScalar)1.0) {
4610:     (*mat->ops->scale)(mat,a);
4611:     PetscObjectStateIncrease((PetscObject)mat);
4612:   }
4613:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4614: #if defined(PETSC_HAVE_CUSP)
4615:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4616:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4617:   }
4618: #endif
4619:   return(0);
4620: }

4624: /*@ 
4625:    MatNorm - Calculates various norms of a matrix.

4627:    Collective on Mat

4629:    Input Parameters:
4630: +  mat - the matrix
4631: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4633:    Output Parameters:
4634: .  nrm - the resulting norm 

4636:    Level: intermediate

4638:    Concepts: matrices^norm
4639:    Concepts: norm^of matrix
4640: @*/
4641: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4642: {


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

4655:   (*mat->ops->norm)(mat,type,nrm);
4656:   return(0);
4657: }

4659: /* 
4660:      This variable is used to prevent counting of MatAssemblyBegin() that
4661:    are called from within a MatAssemblyEnd().
4662: */
4663: static PetscInt MatAssemblyEnd_InUse = 0;
4666: /*@
4667:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4668:    be called after completing all calls to MatSetValues().

4670:    Collective on Mat

4672:    Input Parameters:
4673: +  mat - the matrix 
4674: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4675:  
4676:    Notes: 
4677:    MatSetValues() generally caches the values.  The matrix is ready to
4678:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4679:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4680:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4681:    using the matrix.

4683:    Level: beginner

4685:    Concepts: matrices^assembling

4687: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4688: @*/
4689: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4690: {

4696:   MatCheckPreallocated(mat,1);
4697:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4698:   if (mat->assembled) {
4699:     mat->was_assembled = PETSC_TRUE;
4700:     mat->assembled     = PETSC_FALSE;
4701:   }
4702:   if (!MatAssemblyEnd_InUse) {
4703:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4704:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4705:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4706:   } else {
4707:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4708:   }
4709:   return(0);
4710: }

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

4718:    Not Collective

4720:    Input Parameter:
4721: .  mat - the matrix 

4723:    Output Parameter:
4724: .  assembled - PETSC_TRUE or PETSC_FALSE

4726:    Level: advanced

4728:    Concepts: matrices^assembled?

4730: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4731: @*/
4732: PetscErrorCode  MatAssembled(Mat mat,PetscBool  *assembled)
4733: {
4738:   *assembled = mat->assembled;
4739:   return(0);
4740: }

4744: /*
4745:     Processes command line options to determine if/how a matrix
4746:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4747: */
4748: PetscErrorCode MatView_Private(Mat mat)
4749: {
4750:   PetscErrorCode    ierr;
4751:   PetscBool         flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4752:   static PetscBool  incall = PETSC_FALSE;
4753: #if defined(PETSC_USE_SOCKET_VIEWER)
4754:   PetscBool         flg5 = PETSC_FALSE;
4755: #endif

4758:   if (incall) return(0);
4759:   incall = PETSC_TRUE;
4760:   PetscObjectOptionsBegin((PetscObject)mat);
4761:     PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4762:     PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4763:     PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4764:     PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4765: #if defined(PETSC_USE_SOCKET_VIEWER)
4766:     PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4767: #endif
4768:     PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4769:     PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4770:   PetscOptionsEnd();

4772:   if (flg1) {
4773:     PetscViewer viewer;

4775:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4776:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4777:     MatView(mat,viewer);
4778:     PetscViewerPopFormat(viewer);
4779:   }
4780:   if (flg2) {
4781:     PetscViewer viewer;

4783:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4784:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4785:     MatView(mat,viewer);
4786:     PetscViewerPopFormat(viewer);
4787:   }
4788:   if (flg3) {
4789:     PetscViewer viewer;

4791:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4792:     MatView(mat,viewer);
4793:   }
4794:   if (flg4) {
4795:     PetscViewer viewer;

4797:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4798:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4799:     MatView(mat,viewer);
4800:     PetscViewerPopFormat(viewer);
4801:   }
4802: #if defined(PETSC_USE_SOCKET_VIEWER)
4803:   if (flg5) {
4804:     MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4805:     PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4806:   }
4807: #endif
4808:   if (flg6) {
4809:     MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4810:     PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4811:   }
4812:   if (flg7) {
4813:     PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4814:     if (flg8) {
4815:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4816:     }
4817:     MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4818:     PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4819:     if (flg8) {
4820:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4821:     }
4822:   }
4823:   incall = PETSC_FALSE;
4824:   return(0);
4825: }

4829: /*@
4830:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4831:    be called after MatAssemblyBegin().

4833:    Collective on Mat

4835:    Input Parameters:
4836: +  mat - the matrix 
4837: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4839:    Options Database Keys:
4840: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4841: .  -mat_view_info_detailed - Prints more detailed info
4842: .  -mat_view - Prints matrix in ASCII format
4843: .  -mat_view_matlab - Prints matrix in Matlab format
4844: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4845: .  -display <name> - Sets display name (default is host)
4846: .  -draw_pause <sec> - Sets number of seconds to pause after display
4847: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4848: .  -viewer_socket_machine <machine>
4849: .  -viewer_socket_port <port>
4850: .  -mat_view_binary - save matrix to file in binary format
4851: -  -viewer_binary_filename <name>

4853:    Notes: 
4854:    MatSetValues() generally caches the values.  The matrix is ready to
4855:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4856:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4857:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4858:    using the matrix.

4860:    Level: beginner

4862: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4863: @*/
4864: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4865: {
4866:   PetscErrorCode  ierr;
4867:   static PetscInt inassm = 0;
4868:   PetscBool       flg = PETSC_FALSE;


4874:   inassm++;
4875:   MatAssemblyEnd_InUse++;
4876:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4877:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4878:     if (mat->ops->assemblyend) {
4879:       (*mat->ops->assemblyend)(mat,type);
4880:     }
4881:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4882:   } else {
4883:     if (mat->ops->assemblyend) {
4884:       (*mat->ops->assemblyend)(mat,type);
4885:     }
4886:   }

4888:   /* Flush assembly is not a true assembly */
4889:   if (type != MAT_FLUSH_ASSEMBLY) {
4890:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4891:   }
4892:   mat->insertmode = NOT_SET_VALUES;
4893:   MatAssemblyEnd_InUse--;
4894:   PetscObjectStateIncrease((PetscObject)mat);
4895:   if (!mat->symmetric_eternal) {
4896:     mat->symmetric_set              = PETSC_FALSE;
4897:     mat->hermitian_set              = PETSC_FALSE;
4898:     mat->structurally_symmetric_set = PETSC_FALSE;
4899:   }
4900: #if defined(PETSC_HAVE_CUSP)
4901:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4902:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4903:   }
4904: #endif
4905:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4906:     MatView_Private(mat);
4907:     PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4908:     if (flg) {
4909:       PetscReal tol = 0.0;
4910:       PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4911:       MatIsSymmetric(mat,tol,&flg);
4912:       if (flg) {
4913:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4914:       } else {
4915:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4916:       }
4917:     }
4918:   }
4919:   inassm--;
4920:   return(0);
4921: }

4925: /*@
4926:    MatSetOption - Sets a parameter option for a matrix. Some options
4927:    may be specific to certain storage formats.  Some options
4928:    determine how values will be inserted (or added). Sorted, 
4929:    row-oriented input will generally assemble the fastest. The default
4930:    is row-oriented. 

4932:    Logically Collective on Mat

4934:    Input Parameters:
4935: +  mat - the matrix 
4936: .  option - the option, one of those listed below (and possibly others),
4937: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

4939:   Options Describing Matrix Structure:
4940: +    MAT_SPD - symmetric positive definite
4941: -    MAT_SYMMETRIC - symmetric in terms of both structure and value
4942: .    MAT_HERMITIAN - transpose is the complex conjugation
4943: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4944: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4945:                             you set to be kept with all future use of the matrix
4946:                             including after MatAssemblyBegin/End() which could
4947:                             potentially change the symmetry structure, i.e. you 
4948:                             KNOW the matrix will ALWAYS have the property you set.


4951:    Options For Use with MatSetValues():
4952:    Insert a logically dense subblock, which can be
4953: .    MAT_ROW_ORIENTED - row-oriented (default)

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

4959:    When (re)assembling a matrix, we can restrict the input for
4960:    efficiency/debugging purposes.  These options include
4961: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4962:         allowed if they generate a new nonzero
4963: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4964: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4965: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4966: .    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
4967: +    MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
4968:         any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
4969:         performance for very large process counts.

4971:    Notes:
4972:    Some options are relevant only for particular matrix types and
4973:    are thus ignored by others.  Other options are not supported by
4974:    certain matrix types and will generate an error message if set.

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

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

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

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

4999:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
5000:    other processors should be dropped, rather than stashed.
5001:    This is useful if you know that the "owning" processor is also 
5002:    always generating the correct matrix entries, so that PETSc need
5003:    not transfer duplicate entries generated on another processor.
5004:    
5005:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5006:    searches during matrix assembly. When this flag is set, the hash table
5007:    is created during the first Matrix Assembly. This hash table is
5008:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5009:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 
5010:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
5011:    supported by MATMPIBAIJ format only.

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

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

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

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

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

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

5030:    Level: intermediate

5032:    Concepts: matrices^setting options

5034: @*/
5035: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscBool  flg)
5036: {


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

5048:   switch (op) {
5049:   case MAT_NO_OFF_PROC_ENTRIES:
5050:     mat->nooffprocentries                = flg;
5051:     return(0);
5052:     break;
5053:   case MAT_NO_OFF_PROC_ZERO_ROWS:
5054:     mat->nooffproczerorows               = flg;
5055:     return(0);
5056:     break;
5057:   case MAT_SPD:
5058:     mat->spd_set                         = PETSC_TRUE;
5059:     mat->spd                             = flg;
5060:     if (flg) {
5061:       mat->symmetric                     = PETSC_TRUE;
5062:       mat->structurally_symmetric        = PETSC_TRUE;
5063:       mat->symmetric_set                 = PETSC_TRUE;
5064:       mat->structurally_symmetric_set    = PETSC_TRUE;
5065:     }
5066:     break;
5067:   case MAT_SYMMETRIC:
5068:     mat->symmetric                       = flg;
5069:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5070:     mat->symmetric_set                   = PETSC_TRUE;
5071:     mat->structurally_symmetric_set      = flg;
5072:     break;
5073:   case MAT_HERMITIAN:
5074:     mat->hermitian                       = flg;
5075:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
5076:     mat->hermitian_set                   = PETSC_TRUE;
5077:     mat->structurally_symmetric_set      = flg;
5078:     break;
5079:   case MAT_STRUCTURALLY_SYMMETRIC:
5080:     mat->structurally_symmetric          = flg;
5081:     mat->structurally_symmetric_set      = PETSC_TRUE;
5082:     break;
5083:   case MAT_SYMMETRY_ETERNAL:
5084:     mat->symmetric_eternal               = flg;
5085:     break;
5086:   default:
5087:     break;
5088:   }
5089:   if (mat->ops->setoption) {
5090:     (*mat->ops->setoption)(mat,op,flg);
5091:   }
5092:   return(0);
5093: }

5097: /*@
5098:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
5099:    this routine retains the old nonzero structure.

5101:    Logically Collective on Mat

5103:    Input Parameters:
5104: .  mat - the matrix 

5106:    Level: intermediate

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

5111:    Concepts: matrices^zeroing

5113: .seealso: MatZeroRows()
5114: @*/
5115: PetscErrorCode  MatZeroEntries(Mat mat)
5116: {

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

5127:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5128:   (*mat->ops->zeroentries)(mat);
5129:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5130:   PetscObjectStateIncrease((PetscObject)mat);
5131: #if defined(PETSC_HAVE_CUSP)
5132:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5133:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5134:   }
5135: #endif
5136:   return(0);
5137: }

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

5145:    Collective on Mat

5147:    Input Parameters:
5148: +  mat - the matrix
5149: .  numRows - the number of rows to remove
5150: .  rows - the global row indices
5151: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5152: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5153: -  b - optional vector of right hand side, that will be adjusted by provided solution

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

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

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

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

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

5172:    Level: intermediate

5174:    Concepts: matrices^zeroing rows

5176: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5177: @*/
5178: PetscErrorCode  MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5179: {

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

5191:   (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5192:   MatView_Private(mat);
5193:   PetscObjectStateIncrease((PetscObject)mat);
5194: #if defined(PETSC_HAVE_CUSP)
5195:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5196:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5197:   }
5198: #endif
5199:   return(0);
5200: }

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

5208:    Collective on Mat

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

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

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

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

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

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

5234:    Level: intermediate

5236:    Concepts: matrices^zeroing rows

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

5251:   ISGetLocalSize(is,&numRows);
5252:   ISGetIndices(is,&rows);
5253:   MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5254:   ISRestoreIndices(is,&rows);
5255:   return(0);
5256: }

5260: /*@C
5261:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
5262:    of a set of rows of a matrix.

5264:    Collective on Mat

5266:    Input Parameters:
5267: +  mat - the matrix
5268: .  numRows - the number of rows to remove
5269: .  rows - the global row indices
5270: .  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5271: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5272: -  b - optional vector of right hand side, that will be adjusted by provided solution

5274:    Notes:
5275:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5276:    but does not release memory.  For the dense and block diagonal
5277:    formats this does not alter the nonzero structure.

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

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

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

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

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

5298:    Level: intermediate

5300:    Concepts: matrices^zeroing rows

5302: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5303: @*/
5304: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5305: {

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

5317:   (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5318:   MatView_Private(mat);
5319:   PetscObjectStateIncrease((PetscObject)mat);
5320: #if defined(PETSC_HAVE_CUSP)
5321:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5322:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5323:   }
5324: #endif
5325:   return(0);
5326: }

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

5334:    Collective on Mat

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

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

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

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

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

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

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

5367:    Level: intermediate

5369:    Concepts: matrices^zeroing rows

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

5383:   ISGetLocalSize(is,&numRows);
5384:   ISGetIndices(is,&rows);
5385:   MatZeroRows(mat,numRows,rows,diag,x,b);
5386:   ISRestoreIndices(is,&rows);
5387:   return(0);
5388: }

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

5396:    Collective on Mat

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

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

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

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

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

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

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

5429:    In Fortran idxm and idxn should be declared as
5430: $     MatStencil idxm(4,m)
5431:    and the values inserted using
5432: $    idxm(MatStencil_i,1) = i
5433: $    idxm(MatStencil_j,1) = j
5434: $    idxm(MatStencil_k,1) = k
5435: $    idxm(MatStencil_c,1) = c
5436:    etc

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

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

5446:    Level: intermediate

5448:    Concepts: matrices^zeroing rows

5450: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5451: @*/
5452: PetscErrorCode  MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5453: {
5454:   PetscInt       dim    = mat->stencil.dim;
5455:   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5456:   PetscInt      *dims   = mat->stencil.dims+1;
5457:   PetscInt      *starts = mat->stencil.starts;
5458:   PetscInt      *dxm    = (PetscInt *) rows;
5459:   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;


5467:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5468:   for(i = 0; i < numRows; ++i) {
5469:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5470:     for(j = 0; j < 3-sdim; ++j) dxm++;
5471:     /* Local index in X dir */
5472:     tmp = *dxm++ - starts[0];
5473:     /* Loop over remaining dimensions */
5474:     for(j = 0; j < dim-1; ++j) {
5475:       /* If nonlocal, set index to be negative */
5476:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5477:       /* Update local index */
5478:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5479:     }
5480:     /* Skip component slot if necessary */
5481:     if (mat->stencil.noc) dxm++;
5482:     /* Local row number */
5483:     if (tmp >= 0) {
5484:       jdxm[numNewRows++] = tmp;
5485:     }
5486:   }
5487:   MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5488:   PetscFree(jdxm);
5489:   return(0);
5490: }

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

5498:    Collective on Mat

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

5508:    Notes:
5509:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5510:    but does not release memory.  For the dense and block diagonal
5511:    formats this does not alter the nonzero structure.

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

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

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

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

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

5531:    In Fortran idxm and idxn should be declared as
5532: $     MatStencil idxm(4,m)
5533:    and the values inserted using
5534: $    idxm(MatStencil_i,1) = i
5535: $    idxm(MatStencil_j,1) = j
5536: $    idxm(MatStencil_k,1) = k
5537: $    idxm(MatStencil_c,1) = c
5538:    etc

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

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

5548:    Level: intermediate

5550:    Concepts: matrices^zeroing rows

5552: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5553: @*/
5554: PetscErrorCode  MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5555: {
5556:   PetscInt       dim    = mat->stencil.dim;
5557:   PetscInt       sdim   = dim - (1 - (PetscInt) mat->stencil.noc);
5558:   PetscInt      *dims   = mat->stencil.dims+1;
5559:   PetscInt      *starts = mat->stencil.starts;
5560:   PetscInt      *dxm    = (PetscInt *) rows;
5561:   PetscInt      *jdxm, i, j, tmp, numNewRows = 0;


5569:   PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5570:   for(i = 0; i < numRows; ++i) {
5571:     /* Skip unused dimensions (they are ordered k, j, i, c) */
5572:     for(j = 0; j < 3-sdim; ++j) dxm++;
5573:     /* Local index in X dir */
5574:     tmp = *dxm++ - starts[0];
5575:     /* Loop over remaining dimensions */
5576:     for(j = 0; j < dim-1; ++j) {
5577:       /* If nonlocal, set index to be negative */
5578:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5579:       /* Update local index */
5580:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5581:     }
5582:     /* Skip component slot if necessary */
5583:     if (mat->stencil.noc) dxm++;
5584:     /* Local row number */
5585:     if (tmp >= 0) {
5586:       jdxm[numNewRows++] = tmp;
5587:     }
5588:   }
5589:   MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5590:   PetscFree(jdxm);
5591:   return(0);
5592: }

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

5600:    Collective on Mat

5602:    Input Parameters:
5603: +  mat - the matrix
5604: .  numRows - the number of rows to remove
5605: .  rows - the global row indices
5606: .  diag - value put in all diagonals of eliminated rows
5607: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5608: -  b - optional vector of right hand side, that will be adjusted by provided solution

5610:    Notes:
5611:    Before calling MatZeroRowsLocal(), the user must first set the
5612:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5614:    For the AIJ matrix formats this removes the old nonzero structure,
5615:    but does not release memory.  For the dense and block diagonal
5616:    formats this does not alter the nonzero structure.

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

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

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

5629:    Level: intermediate

5631:    Concepts: matrices^zeroing

5633: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5634: @*/
5635: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5636: {
5638:   PetscMPIInt    size;

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

5648:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
5649:   if (mat->ops->zerorowslocal) {
5650:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5651:   } else if (size == 1) {
5652:     (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5653:   } else {
5654:     IS             is, newis;
5655:     const PetscInt *newRows;

5657:     if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5658:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5659:     ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5660:     ISGetIndices(newis,&newRows);
5661:     (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5662:     ISRestoreIndices(newis,&newRows);
5663:     ISDestroy(&newis);
5664:     ISDestroy(&is);
5665:   }
5666:   PetscObjectStateIncrease((PetscObject)mat);
5667: #if defined(PETSC_HAVE_CUSP)
5668:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5669:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5670:   }
5671: #endif
5672:   return(0);
5673: }

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

5681:    Collective on Mat

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

5690:    Notes:
5691:    Before calling MatZeroRowsLocalIS(), the user must first set the
5692:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5694:    For the AIJ matrix formats this removes the old nonzero structure,
5695:    but does not release memory.  For the dense and block diagonal
5696:    formats this does not alter the nonzero structure.

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

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

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

5709:    Level: intermediate

5711:    Concepts: matrices^zeroing

5713: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5714: @*/
5715: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5716: {
5718:   PetscInt       numRows;
5719:   const PetscInt *rows;

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

5729:   ISGetLocalSize(is,&numRows);
5730:   ISGetIndices(is,&rows);
5731:   MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5732:   ISRestoreIndices(is,&rows);
5733:   return(0);
5734: }

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

5742:    Collective on Mat

5744:    Input Parameters:
5745: +  mat - the matrix
5746: .  numRows - the number of rows to remove
5747: .  rows - the global row indices
5748: .  diag - value put in all diagonals of eliminated rows
5749: .  x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5750: -  b - optional vector of right hand side, that will be adjusted by provided solution

5752:    Notes:
5753:    Before calling MatZeroRowsColumnsLocal(), the user must first set the
5754:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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:    Level: intermediate

5762:    Concepts: matrices^zeroing

5764: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5765: @*/
5766: PetscErrorCode  MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5767: {
5769:   PetscMPIInt    size;

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

5779:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
5780:   if (size == 1) {
5781:     (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5782:   } else {
5783:     IS             is, newis;
5784:     const PetscInt *newRows;

5786:     if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5787:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5788:     ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5789:     ISGetIndices(newis,&newRows);
5790:     (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5791:     ISRestoreIndices(newis,&newRows);
5792:     ISDestroy(&newis);
5793:     ISDestroy(&is);
5794:   }
5795:   PetscObjectStateIncrease((PetscObject)mat);
5796: #if defined(PETSC_HAVE_CUSP)
5797:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5798:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5799:   }
5800: #endif
5801:   return(0);
5802: }

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

5810:    Collective on Mat

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

5819:    Notes:
5820:    Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5821:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

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

5827:    Level: intermediate

5829:    Concepts: matrices^zeroing

5831: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5832: @*/
5833: PetscErrorCode  MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5834: {
5836:   PetscInt       numRows;
5837:   const PetscInt *rows;

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

5847:   ISGetLocalSize(is,&numRows);
5848:   ISGetIndices(is,&rows);
5849:   MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5850:   ISRestoreIndices(is,&rows);
5851:   return(0);
5852: }

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

5859:    Not Collective

5861:    Input Parameter:
5862: .  mat - the matrix

5864:    Output Parameters:
5865: +  m - the number of global rows
5866: -  n - the number of global columns

5868:    Note: both output parameters can be PETSC_NULL on input.

5870:    Level: beginner

5872:    Concepts: matrices^size

5874: .seealso: MatGetLocalSize()
5875: @*/
5876: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5877: {
5880:   if (m) *m = mat->rmap->N;
5881:   if (n) *n = mat->cmap->N;
5882:   return(0);
5883: }

5887: /*@
5888:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5889:    stored locally.  This information may be implementation dependent, so
5890:    use with care.

5892:    Not Collective

5894:    Input Parameters:
5895: .  mat - the matrix

5897:    Output Parameters:
5898: +  m - the number of local rows
5899: -  n - the number of local columns

5901:    Note: both output parameters can be PETSC_NULL on input.

5903:    Level: beginner

5905:    Concepts: matrices^local size

5907: .seealso: MatGetSize()
5908: @*/
5909: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5910: {
5915:   if (m) *m = mat->rmap->n;
5916:   if (n) *n = mat->cmap->n;
5917:   return(0);
5918: }

5922: /*@
5923:    MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5924:    this processor. (The columns of the "diagonal block")

5926:    Not Collective, unless matrix has not been allocated, then collective on Mat

5928:    Input Parameters:
5929: .  mat - the matrix

5931:    Output Parameters:
5932: +  m - the global index of the first local column
5933: -  n - one more than the global index of the last local column

5935:    Notes: both output parameters can be PETSC_NULL on input.

5937:    Level: developer

5939:    Concepts: matrices^column ownership

5941: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

5943: @*/
5944: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5945: {

5952:   MatCheckPreallocated(mat,1);
5953:   if (m) *m = mat->cmap->rstart;
5954:   if (n) *n = mat->cmap->rend;
5955:   return(0);
5956: }

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

5966:    Not Collective, unless matrix has not been allocated, then collective on Mat

5968:    Input Parameters:
5969: .  mat - the matrix

5971:    Output Parameters:
5972: +  m - the global index of the first local row
5973: -  n - one more than the global index of the last local row

5975:    Note: both output parameters can be PETSC_NULL on input.

5977:    Level: beginner

5979:    Concepts: matrices^row ownership

5981: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

5983: @*/
5984: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5985: {

5992:   MatCheckPreallocated(mat,1);
5993:   if (m) *m = mat->rmap->rstart;
5994:   if (n) *n = mat->rmap->rend;
5995:   return(0);
5996: }

6000: /*@C
6001:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6002:    each process

6004:    Not Collective, unless matrix has not been allocated, then collective on Mat

6006:    Input Parameters:
6007: .  mat - the matrix

6009:    Output Parameters:
6010: .  ranges - start of each processors portion plus one more then the total length at the end

6012:    Level: beginner

6014:    Concepts: matrices^row ownership

6016: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6018: @*/
6019: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6020: {

6026:   MatCheckPreallocated(mat,1);
6027:   PetscLayoutGetRanges(mat->rmap,ranges);
6028:   return(0);
6029: }

6033: /*@C
6034:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6035:    this processor. (The columns of the "diagonal blocks" for each process)

6037:    Not Collective, unless matrix has not been allocated, then collective on Mat

6039:    Input Parameters:
6040: .  mat - the matrix

6042:    Output Parameters:
6043: .  ranges - start of each processors portion plus one more then the total length at the end

6045:    Level: beginner

6047:    Concepts: matrices^column ownership

6049: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6051: @*/
6052: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6053: {

6059:   MatCheckPreallocated(mat,1);
6060:   PetscLayoutGetRanges(mat->cmap,ranges);
6061:   return(0);
6062: }

6066: /*@C
6067:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6068:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
6069:    to complete the factorization.

6071:    Collective on Mat

6073:    Input Parameters:
6074: +  mat - the matrix
6075: .  row - row permutation
6076: .  column - column permutation
6077: -  info - structure containing 
6078: $      levels - number of levels of fill.
6079: $      expected fill - as ratio of original fill.
6080: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6081:                 missing diagonal entries)

6083:    Output Parameters:
6084: .  fact - new matrix that has been symbolically factored

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

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

6094:    Level: developer

6096:   Concepts: matrices^symbolic LU factorization
6097:   Concepts: matrices^factorization
6098:   Concepts: LU^symbolic factorization

6100: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6101:           MatGetOrdering(), MatFactorInfo

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

6106: @*/
6107: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6108: {

6118:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6119:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6120:   if (!(fact)->ops->ilufactorsymbolic) {
6121:     const MatSolverPackage spackage;
6122:     MatFactorGetSolverPackage(fact,&spackage);
6123:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6124:   }
6125:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6126:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6127:   MatCheckPreallocated(mat,2);

6129:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6130:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6131:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6132:   return(0);
6133: }

6137: /*@C
6138:    MatICCFactorSymbolic - Performs symbolic incomplete
6139:    Cholesky factorization for a symmetric matrix.  Use 
6140:    MatCholeskyFactorNumeric() to complete the factorization.

6142:    Collective on Mat

6144:    Input Parameters:
6145: +  mat - the matrix
6146: .  perm - row and column permutation
6147: -  info - structure containing 
6148: $      levels - number of levels of fill.
6149: $      expected fill - as ratio of original fill.

6151:    Output Parameter:
6152: .  fact - the factored matrix

6154:    Notes:
6155:    Most users should employ the KSP interface for linear solvers
6156:    instead of working directly with matrix algebra routines such as this.
6157:    See, e.g., KSPCreate().

6159:    Level: developer

6161:   Concepts: matrices^symbolic incomplete Cholesky factorization
6162:   Concepts: matrices^factorization
6163:   Concepts: Cholsky^symbolic factorization

6165: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6170: @*/
6171: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6172: {

6181:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6182:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6183:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6184:   if (!(fact)->ops->iccfactorsymbolic) {
6185:     const MatSolverPackage spackage;
6186:     MatFactorGetSolverPackage(fact,&spackage);
6187:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6188:   }
6189:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6190:   MatCheckPreallocated(mat,2);

6192:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6193:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6194:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6195:   return(0);
6196: }

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

6206:    Not Collective

6208:    Input Parameter:
6209: .  mat - the matrix

6211:    Output Parameter:
6212: .  v - the location of the values


6215:    Fortran Note:
6216:    This routine is used differently from Fortran, e.g.,
6217: .vb
6218:         Mat         mat
6219:         PetscScalar mat_array(1)
6220:         PetscOffset i_mat
6221:         PetscErrorCode ierr
6222:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

6228:         [... other code ...]
6229:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6230: .ve

6232:    See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a> and 
6233:    src/mat/examples/tests for details.

6235:    Level: advanced

6237:    Concepts: matrices^access array

6239: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6240: @*/
6241: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6242: {

6249:   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6250:   MatCheckPreallocated(mat,1);
6251:   (*mat->ops->getarray)(mat,v);
6252:   CHKMEMQ;
6253:   return(0);
6254: }

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

6261:    Not Collective

6263:    Input Parameter:
6264: +  mat - the matrix
6265: -  v - the location of the values

6267:    Fortran Note:
6268:    This routine is used differently from Fortran, e.g.,
6269: .vb
6270:         Mat         mat
6271:         PetscScalar mat_array(1)
6272:         PetscOffset i_mat
6273:         PetscErrorCode ierr
6274:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

6280:         [... other code ...]
6281:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6282: .ve

6284:    See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6285:    src/mat/examples/tests for details

6287:    Level: advanced

6289: .seealso: MatGetArray(), MatRestoreArrayF90()
6290: @*/
6291: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6292: {

6299:   CHKMEMQ;
6300:   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6301:   (*mat->ops->restorearray)(mat,v);
6302:   PetscObjectStateIncrease((PetscObject)mat);
6303: #if defined(PETSC_HAVE_CUSP)
6304:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6305:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6306:   }
6307: #endif
6308:   return(0);
6309: }

6313: /*@C
6314:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6315:    points to an array of valid matrices, they may be reused to store the new
6316:    submatrices.

6318:    Collective on Mat

6320:    Input Parameters:
6321: +  mat - the matrix
6322: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6323: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6324: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6326:    Output Parameter:
6327: .  submat - the array of submatrices

6329:    Notes:
6330:    MatGetSubMatrices() can extract ONLY sequential submatrices
6331:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6332:    to extract a parallel submatrix.

6334:    Currently both row and column indices must be sorted to guarantee 
6335:    correctness with all matrix types.

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

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

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

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

6350:    For BAIJ matrices the index sets must respect the block structure, that is if they
6351:    request one row/column in a block, they must request all rows/columns that are in
6352:    that block. For example, if the block size is 2 you cannot request just row 0 and 
6353:    column 0.

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

6359:    Level: advanced

6361:    Concepts: matrices^accessing submatrices
6362:    Concepts: submatrices

6364: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6365: @*/
6366: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6367: {
6369:   PetscInt        i;
6370:   PetscBool       eq;

6375:   if (n) {
6380:   }
6382:   if (n && scall == MAT_REUSE_MATRIX) {
6385:   }
6386:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6387:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6388:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6389:   MatCheckPreallocated(mat,1);

6391:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6392:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6393:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6394:   for (i=0; i<n; i++) {
6395:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6396:       ISEqual(irow[i],icol[i],&eq);
6397:       if (eq) {
6398:         if (mat->symmetric){
6399:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6400:         } else if (mat->hermitian) {
6401:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6402:         } else if (mat->structurally_symmetric) {
6403:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6404:         }
6405:       }
6406:     }
6407:   }
6408:   return(0);
6409: }

6413: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6414: {
6416:   PetscInt        i;
6417:   PetscBool       eq;

6422:   if (n) {
6427:   }
6429:   if (n && scall == MAT_REUSE_MATRIX) {
6432:   }
6433:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6434:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6435:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6436:   MatCheckPreallocated(mat,1);

6438:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6439:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6440:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6441:   for (i=0; i<n; i++) {
6442:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6443:       ISEqual(irow[i],icol[i],&eq);
6444:       if (eq) {
6445:         if (mat->symmetric){
6446:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6447:         } else if (mat->hermitian) {
6448:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6449:         } else if (mat->structurally_symmetric) {
6450:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6451:         }
6452:       }
6453:     }
6454:   }
6455:   return(0);
6456: }

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

6463:    Collective on Mat

6465:    Input Parameters:
6466: +  n - the number of local matrices
6467: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6468:                        sequence of MatGetSubMatrices())

6470:    Level: advanced

6472:     Notes: Frees not only the matrices, but also the array that contains the matrices
6473:            In Fortran will not free the array.

6475: .seealso: MatGetSubMatrices()
6476: @*/
6477: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6478: {
6480:   PetscInt       i;

6483:   if (!*mat) return(0);
6484:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6486:   for (i=0; i<n; i++) {
6487:     MatDestroy(&(*mat)[i]);
6488:   }
6489:   /* memory is allocated even if n = 0 */
6490:   PetscFree(*mat);
6491:   *mat = PETSC_NULL;
6492:   return(0);
6493: }

6497: /*@C
6498:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 

6500:    Collective on Mat

6502:    Input Parameters:
6503: .  mat - the matrix

6505:    Output Parameter:
6506: .  matstruct - the sequential matrix with the nonzero structure of mat

6508:   Level: intermediate

6510: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6511: @*/
6512: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6513: {

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

6524:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6525:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6526:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6527:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6528:   return(0);
6529: }

6533: /*@C
6534:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6536:    Collective on Mat

6538:    Input Parameters:
6539: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6540:                        sequence of MatGetSequentialNonzeroStructure())

6542:    Level: advanced

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

6546: .seealso: MatGetSeqNonzeroStructure()
6547: @*/
6548: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6549: {

6554:   MatDestroy(mat);
6555:   return(0);
6556: }

6560: /*@
6561:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6562:    replaces the index sets by larger ones that represent submatrices with
6563:    additional overlap.

6565:    Collective on Mat

6567:    Input Parameters:
6568: +  mat - the matrix
6569: .  n   - the number of index sets
6570: .  is  - the array of index sets (these index sets will changed during the call)
6571: -  ov  - the additional overlap requested

6573:    Level: developer

6575:    Concepts: overlap
6576:    Concepts: ASM^computing overlap

6578: .seealso: MatGetSubMatrices()
6579: @*/
6580: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6581: {

6587:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6588:   if (n) {
6591:   }
6592:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6593:   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6594:   MatCheckPreallocated(mat,1);

6596:   if (!ov) return(0);
6597:   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6598:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6599:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6600:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6601:   return(0);
6602: }

6606: /*@
6607:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6608:    block row and block diagonal formats.
6609:    
6610:    Not Collective

6612:    Input Parameter:
6613: .  mat - the matrix

6615:    Output Parameter:
6616: .  bs - block size

6618:    Notes:
6619:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6621:    Level: intermediate

6623:    Concepts: matrices^block size

6625: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6626: @*/
6627: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6628: {

6634:   MatCheckPreallocated(mat,1);
6635:   *bs = mat->rmap->bs;
6636:   return(0);
6637: }

6641: /*@
6642:    MatGetBlockSizes - Returns the matrix block row and column sizes; 
6643:    useful especially for the block row and block diagonal formats.
6644:    
6645:    Not Collective

6647:    Input Parameter:
6648: .  mat - the matrix

6650:    Output Parameter:
6651: .  rbs - row block size
6652: .  cbs - coumn block size

6654:    Notes:
6655:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6657:    Level: intermediate

6659:    Concepts: matrices^block size

6661: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6662: @*/
6663: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6664: {

6671:   MatCheckPreallocated(mat,1);
6672:   if(rbs) *rbs = mat->rmap->bs;
6673:   if(cbs) *cbs = mat->cmap->bs;
6674:   return(0);
6675: }

6679: /*@
6680:    MatSetBlockSize - Sets the matrix block size.
6681:    
6682:    Logically Collective on Mat

6684:    Input Parameters:
6685: +  mat - the matrix
6686: -  bs - block size

6688:    Notes:
6689:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6691:    Level: intermediate

6693:    Concepts: matrices^block size

6695: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6696: @*/
6697: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6698: {

6704:   PetscLayoutSetBlockSize(mat->rmap,bs);
6705:   PetscLayoutSetBlockSize(mat->cmap,bs);
6706:   return(0);
6707: }

6711: /*@
6712:    MatSetBlockSizes - Sets the matrix block row and column sizes.
6713:    
6714:    Logically Collective on Mat

6716:    Input Parameters:
6717: +  mat - the matrix
6718: -  rbs - row block size
6719: -  cbs - column block size

6721:    Notes:
6722:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6724:    Level: intermediate

6726:    Concepts: matrices^block size

6728: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6729: @*/
6730: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6731: {

6737:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6738:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6739:   return(0);
6740: }

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

6747:    Collective on Mat

6749:     Input Parameters:
6750: +   mat - the matrix
6751: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6752: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6753: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6754:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6755:                  always used.

6757:     Output Parameters:
6758: +   n - number of rows in the (possibly compressed) matrix
6759: .   ia - the row pointers [of length n+1]
6760: .   ja - the column indices
6761: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6762:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6764:     Level: developer

6766:     Notes: You CANNOT change any of the ia[] or ja[] values.

6768:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6770:     Fortran Node

6772:            In Fortran use
6773: $           PetscInt ia(1), ja(1)
6774: $           PetscOffset iia, jja
6775: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6776: $
6777: $          or 
6778: $
6779: $           PetscScalar, pointer :: xx_v(:)
6780: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6781:   
6782:  
6783:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6785: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6786: @*/
6787: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6788: {

6798:   MatCheckPreallocated(mat,1);
6799:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6800:   else {
6801:     *done = PETSC_TRUE;
6802:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6803:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6804:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6805:   }
6806:   return(0);
6807: }

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

6814:     Collective on Mat

6816:     Input Parameters:
6817: +   mat - the matrix
6818: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6819: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6820:                 symmetrized
6821: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6822:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6823:                  always used.

6825:     Output Parameters:
6826: +   n - number of columns in the (possibly compressed) matrix
6827: .   ia - the column pointers
6828: .   ja - the row indices
6829: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6831:     Level: developer

6833: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6834: @*/
6835: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6836: {

6846:   MatCheckPreallocated(mat,1);
6847:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6848:   else {
6849:     *done = PETSC_TRUE;
6850:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6851:   }
6852:   return(0);
6853: }

6857: /*@C
6858:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6859:     MatGetRowIJ().

6861:     Collective on Mat

6863:     Input Parameters:
6864: +   mat - the matrix
6865: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6866: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6867:                 symmetrized
6868: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6869:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6870:                  always used.

6872:     Output Parameters:
6873: +   n - size of (possibly compressed) matrix
6874: .   ia - the row pointers
6875: .   ja - the column indices
6876: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6878:     Level: developer

6880: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6881: @*/
6882: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6883: {

6892:   MatCheckPreallocated(mat,1);

6894:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6895:   else {
6896:     *done = PETSC_TRUE;
6897:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6898:   }
6899:   return(0);
6900: }

6904: /*@C
6905:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6906:     MatGetColumnIJ().

6908:     Collective on Mat

6910:     Input Parameters:
6911: +   mat - the matrix
6912: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6913: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6914:                 symmetrized
6915: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6916:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6917:                  always used.

6919:     Output Parameters:
6920: +   n - size of (possibly compressed) matrix
6921: .   ia - the column pointers
6922: .   ja - the row indices
6923: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6925:     Level: developer

6927: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6928: @*/
6929: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6930: {

6939:   MatCheckPreallocated(mat,1);

6941:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6942:   else {
6943:     *done = PETSC_TRUE;
6944:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6945:   }
6946:   return(0);
6947: }

6951: /*@C
6952:     MatColoringPatch -Used inside matrix coloring routines that 
6953:     use MatGetRowIJ() and/or MatGetColumnIJ().

6955:     Collective on Mat

6957:     Input Parameters:
6958: +   mat - the matrix
6959: .   ncolors - max color value
6960: .   n   - number of entries in colorarray
6961: -   colorarray - array indicating color for each column

6963:     Output Parameters:
6964: .   iscoloring - coloring generated using colorarray information

6966:     Level: developer

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

6970: @*/
6971: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6972: {

6980:   MatCheckPreallocated(mat,1);

6982:   if (!mat->ops->coloringpatch){
6983:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6984:   } else {
6985:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6986:   }
6987:   return(0);
6988: }


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

6996:    Logically Collective on Mat

6998:    Input Parameter:
6999: .  mat - the factored matrix to be reset

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

7008:    Note that one can specify in-place ILU(0) factorization by calling 
7009: .vb
7010:      PCType(pc,PCILU);
7011:      PCFactorSeUseInPlace(pc);
7012: .ve
7013:    or by using the options -pc_type ilu -pc_factor_in_place

7015:    In-place factorization ILU(0) can also be used as a local
7016:    solver for the blocks within the block Jacobi or additive Schwarz
7017:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion 
7018:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7019:    local solver options.

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

7025:    Level: developer

7027: .seealso: PCFactorSetUseInPlace()

7029:    Concepts: matrices^unfactored

7031: @*/
7032: PetscErrorCode  MatSetUnfactored(Mat mat)
7033: {

7039:   MatCheckPreallocated(mat,1);
7040:   mat->factortype = MAT_FACTOR_NONE;
7041:   if (!mat->ops->setunfactored) return(0);
7042:   (*mat->ops->setunfactored)(mat);
7043:   return(0);
7044: }

7046: /*MC
7047:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

7049:     Synopsis:
7050:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7052:     Not collective

7054:     Input Parameter:
7055: .   x - matrix

7057:     Output Parameters:
7058: +   xx_v - the Fortran90 pointer to the array
7059: -   ierr - error code

7061:     Example of Usage: 
7062: .vb
7063:       PetscScalar, pointer xx_v(:,:)
7064:       ....
7065:       call MatGetArrayF90(x,xx_v,ierr)
7066:       a = xx_v(3)
7067:       call MatRestoreArrayF90(x,xx_v,ierr)
7068: .ve

7070:     Notes:
7071:     Not yet supported for all F90 compilers

7073:     Level: advanced

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

7077:     Concepts: matrices^accessing array

7079: M*/

7081: /*MC
7082:     MatRestoreArrayF90 - Restores a matrix array that has been
7083:     accessed with MatGetArrayF90().

7085:     Synopsis:
7086:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7088:     Not collective

7090:     Input Parameters:
7091: +   x - matrix
7092: -   xx_v - the Fortran90 pointer to the array

7094:     Output Parameter:
7095: .   ierr - error code

7097:     Example of Usage: 
7098: .vb
7099:        PetscScalar, pointer xx_v(:)
7100:        ....
7101:        call MatGetArrayF90(x,xx_v,ierr)
7102:        a = xx_v(3)
7103:        call MatRestoreArrayF90(x,xx_v,ierr)
7104: .ve
7105:    
7106:     Notes:
7107:     Not yet supported for all F90 compilers

7109:     Level: advanced

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

7113: M*/


7118: /*@
7119:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7120:                       as the original matrix.

7122:     Collective on Mat

7124:     Input Parameters:
7125: +   mat - the original matrix
7126: .   isrow - parallel IS containing the rows this processor should obtain
7127: .   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.
7128: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7130:     Output Parameter:
7131: .   newmat - the new submatrix, of the same type as the old

7133:     Level: advanced

7135:     Notes:
7136:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7138:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7140:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7141:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7142:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX  
7143:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when 
7144:    you are finished using it.

7146:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7147:     the input matrix.

7149:     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).

7151:    Example usage:
7152:    Consider the following 8x8 matrix with 34 non-zero values, that is
7153:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7154:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7155:    as follows:

7157: .vb
7158:             1  2  0  |  0  3  0  |  0  4
7159:     Proc0   0  5  6  |  7  0  0  |  8  0
7160:             9  0 10  | 11  0  0  | 12  0
7161:     -------------------------------------
7162:            13  0 14  | 15 16 17  |  0  0
7163:     Proc1   0 18  0  | 19 20 21  |  0  0
7164:             0  0  0  | 22 23  0  | 24  0
7165:     -------------------------------------
7166:     Proc2  25 26 27  |  0  0 28  | 29  0
7167:            30  0  0  | 31 32 33  |  0 34
7168: .ve

7170:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7172: .vb
7173:             2  0  |  0  3  0  |  0
7174:     Proc0   5  6  |  7  0  0  |  8
7175:     -------------------------------
7176:     Proc1  18  0  | 19 20 21  |  0
7177:     -------------------------------
7178:     Proc2  26 27  |  0  0 28  | 29
7179:             0  0  | 31 32 33  |  0
7180: .ve


7183:     Concepts: matrices^submatrices

7185: .seealso: MatGetSubMatrices()
7186: @*/
7187: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7188: {
7190:   PetscMPIInt    size;
7191:   Mat            *local;
7192:   IS             iscoltmp;

7201:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7202:   MatCheckPreallocated(mat,1);
7203:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

7205:   if (!iscol) {
7206:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7207:   } else {
7208:     iscoltmp = iscol;
7209:   }

7211:   /* if original matrix is on just one processor then use submatrix generated */
7212:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7213:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7214:     if (!iscol) {ISDestroy(&iscoltmp);}
7215:     return(0);
7216:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7217:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7218:     *newmat = *local;
7219:     PetscFree(local);
7220:     if (!iscol) {ISDestroy(&iscoltmp);}
7221:     return(0);
7222:   } else if (!mat->ops->getsubmatrix) {
7223:     /* Create a new matrix type that implements the operation using the full matrix */
7224:     switch (cll) {
7225:       case MAT_INITIAL_MATRIX:
7226:         MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7227:         break;
7228:       case MAT_REUSE_MATRIX:
7229:         MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7230:         break;
7231:       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7232:     }
7233:     if (!iscol) {ISDestroy(&iscoltmp);}
7234:     return(0);
7235:   }

7237:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7238:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7239:   if (!iscol) {ISDestroy(&iscoltmp);}
7240:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7241:   return(0);
7242: }

7246: /*@
7247:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7248:    used during the assembly process to store values that belong to 
7249:    other processors.

7251:    Not Collective

7253:    Input Parameters:
7254: +  mat   - the matrix
7255: .  size  - the initial size of the stash.
7256: -  bsize - the initial size of the block-stash(if used).

7258:    Options Database Keys:
7259: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7260: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7262:    Level: intermediate

7264:    Notes: 
7265:      The block-stash is used for values set with MatSetValuesBlocked() while
7266:      the stash is used for values set with MatSetValues()

7268:      Run with the option -info and look for output of the form
7269:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7270:      to determine the appropriate value, MM, to use for size and 
7271:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7272:      to determine the value, BMM to use for bsize

7274:    Concepts: stash^setting matrix size
7275:    Concepts: matrices^stash

7277: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7279: @*/
7280: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7281: {

7287:   MatStashSetInitialSize_Private(&mat->stash,size);
7288:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7289:   return(0);
7290: }

7294: /*@
7295:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
7296:      the matrix

7298:    Neighbor-wise Collective on Mat

7300:    Input Parameters:
7301: +  mat   - the matrix
7302: .  x,y - the vectors
7303: -  w - where the result is stored

7305:    Level: intermediate

7307:    Notes: 
7308:     w may be the same vector as y. 

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

7313:     Concepts: interpolation

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

7317: @*/
7318: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7319: {
7321:   PetscInt       M,N,Ny;

7329:   MatCheckPreallocated(A,1);
7330:   MatGetSize(A,&M,&N);
7331:   VecGetSize(y,&Ny);
7332:   if (M == Ny) {
7333:     MatMultAdd(A,x,y,w);
7334:   } else {
7335:     MatMultTransposeAdd(A,x,y,w);
7336:   }
7337:   return(0);
7338: }

7342: /*@
7343:    MatInterpolate - y = A*x or A'*x depending on the shape of 
7344:      the matrix

7346:    Neighbor-wise Collective on Mat

7348:    Input Parameters:
7349: +  mat   - the matrix
7350: -  x,y - the vectors

7352:    Level: intermediate

7354:    Notes: 
7355:     This allows one to use either the restriction or interpolation (its transpose)
7356:     matrix to do the interpolation

7358:    Concepts: matrices^interpolation

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

7362: @*/
7363: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7364: {
7366:   PetscInt       M,N,Ny;

7373:   MatCheckPreallocated(A,1);
7374:   MatGetSize(A,&M,&N);
7375:   VecGetSize(y,&Ny);
7376:   if (M == Ny) {
7377:     MatMult(A,x,y);
7378:   } else {
7379:     MatMultTranspose(A,x,y);
7380:   }
7381:   return(0);
7382: }

7386: /*@
7387:    MatRestrict - y = A*x or A'*x

7389:    Neighbor-wise Collective on Mat

7391:    Input Parameters:
7392: +  mat   - the matrix
7393: -  x,y - the vectors

7395:    Level: intermediate

7397:    Notes: 
7398:     This allows one to use either the restriction or interpolation (its transpose)
7399:     matrix to do the restriction

7401:    Concepts: matrices^restriction

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

7405: @*/
7406: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7407: {
7409:   PetscInt       M,N,Ny;

7416:   MatCheckPreallocated(A,1);

7418:   MatGetSize(A,&M,&N);
7419:   VecGetSize(y,&Ny);
7420:   if (M == Ny) {
7421:     MatMult(A,x,y);
7422:   } else {
7423:     MatMultTranspose(A,x,y);
7424:   }
7425:   return(0);
7426: }

7430: /*@
7431:    MatGetNullSpace - retrieves the null space to a matrix.

7433:    Logically Collective on Mat and MatNullSpace

7435:    Input Parameters:
7436: +  mat - the matrix
7437: -  nullsp - the null space object

7439:    Level: developer

7441:    Notes:
7442:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7444:    Concepts: null space^attaching to matrix

7446: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7447: @*/
7448: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7449: {
7454:   *nullsp = mat->nullsp;
7455:   return(0);
7456: }

7460: /*@
7461:    MatSetNullSpace - attaches a null space to a matrix.
7462:         This null space will be removed from the resulting vector whenever
7463:         MatMult() is called

7465:    Logically Collective on Mat and MatNullSpace

7467:    Input Parameters:
7468: +  mat - the matrix
7469: -  nullsp - the null space object

7471:    Level: advanced

7473:    Notes:
7474:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7476:    Concepts: null space^attaching to matrix

7478: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7479: @*/
7480: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7481: {

7488:   MatCheckPreallocated(mat,1);
7489:   PetscObjectReference((PetscObject)nullsp);
7490:   MatNullSpaceDestroy(&mat->nullsp);
7491:   mat->nullsp = nullsp;
7492:   return(0);
7493: }

7497: /*@
7498:    MatSetNearNullSpace - attaches a null space to a matrix.
7499:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7501:    Logically Collective on Mat and MatNullSpace

7503:    Input Parameters:
7504: +  mat - the matrix
7505: -  nullsp - the null space object

7507:    Level: advanced

7509:    Notes:
7510:       Overwrites any previous near null space that may have been attached

7512:    Concepts: null space^attaching to matrix

7514: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7515: @*/
7516: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7517: {

7524:   MatCheckPreallocated(mat,1);
7525:   PetscObjectReference((PetscObject)nullsp);
7526:   MatNullSpaceDestroy(&mat->nearnullsp);
7527:   mat->nearnullsp = nullsp;
7528:   return(0);
7529: }

7533: /*@
7534:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7536:    Not Collective

7538:    Input Parameters:
7539: .  mat - the matrix

7541:    Output Parameters:
7542: .  nullsp - the null space object, PETSC_NULL if not set

7544:    Level: developer

7546:    Concepts: null space^attaching to matrix

7548: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7549: @*/
7550: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7551: {

7557:   MatCheckPreallocated(mat,1);
7558:   *nullsp = mat->nearnullsp;
7559:   return(0);
7560: }

7564: /*@C
7565:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7567:    Collective on Mat

7569:    Input Parameters:
7570: +  mat - the matrix
7571: .  row - row/column permutation
7572: .  fill - expected fill factor >= 1.0
7573: -  level - level of fill, for ICC(k)

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

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

7583:    Level: developer

7585:    Concepts: matrices^incomplete Cholesky factorization
7586:    Concepts: Cholesky factorization

7588: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

7593: @*/
7594: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7595: {

7603:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7604:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7605:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7606:   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7607:   MatCheckPreallocated(mat,1);
7608:   (*mat->ops->iccfactor)(mat,row,info);
7609:   PetscObjectStateIncrease((PetscObject)mat);
7610:   return(0);
7611: }

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

7618:    Not Collective

7620:    Input Parameters:
7621: +  mat - the matrix
7622: -  v - the values compute with ADIC

7624:    Level: developer

7626:    Notes:
7627:      Must call MatSetColoring() before using this routine. Also this matrix must already
7628:      have its nonzero pattern determined.

7630: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7631:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7632: @*/
7633: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7634: {


7642:   if (!mat->assembled) {
7643:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7644:   }
7645:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7646:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7647:   (*mat->ops->setvaluesadic)(mat,v);
7648:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7649:   MatView_Private(mat);
7650:   PetscObjectStateIncrease((PetscObject)mat);
7651:   return(0);
7652: }


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

7660:    Not Collective

7662:    Input Parameters:
7663: +  mat - the matrix
7664: -  coloring - the coloring

7666:    Level: developer

7668: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7669:           MatSetValues(), MatSetValuesAdic()
7670: @*/
7671: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7672: {


7680:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7681:   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7682:   (*mat->ops->setcoloring)(mat,coloring);
7683:   return(0);
7684: }

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

7691:    Not Collective

7693:    Input Parameters:
7694: +  mat - the matrix
7695: .  nl - leading dimension of v
7696: -  v - the values compute with ADIFOR

7698:    Level: developer

7700:    Notes:
7701:      Must call MatSetColoring() before using this routine. Also this matrix must already
7702:      have its nonzero pattern determined.

7704: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7705:           MatSetValues(), MatSetColoring()
7706: @*/
7707: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7708: {


7716:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7717:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7718:   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7719:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7720:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7721:   PetscObjectStateIncrease((PetscObject)mat);
7722:   return(0);
7723: }

7727: /*@ 
7728:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
7729:          ghosted ones.

7731:    Not Collective

7733:    Input Parameters:
7734: +  mat - the matrix
7735: -  diag = the diagonal values, including ghost ones

7737:    Level: developer

7739:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7740:       
7741: .seealso: MatDiagonalScale()
7742: @*/
7743: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7744: {
7746:   PetscMPIInt    size;


7753:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7754:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7755:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
7756:   if (size == 1) {
7757:     PetscInt n,m;
7758:     VecGetSize(diag,&n);
7759:     MatGetSize(mat,0,&m);
7760:     if (m == n) {
7761:       MatDiagonalScale(mat,0,diag);
7762:     } else {
7763:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7764:     }
7765:   } else {
7766:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7767:   }
7768:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7769:   PetscObjectStateIncrease((PetscObject)mat);
7770:   return(0);
7771: }

7775: /*@ 
7776:    MatGetInertia - Gets the inertia from a factored matrix

7778:    Collective on Mat

7780:    Input Parameter:
7781: .  mat - the matrix

7783:    Output Parameters:
7784: +   nneg - number of negative eigenvalues
7785: .   nzero - number of zero eigenvalues
7786: -   npos - number of positive eigenvalues

7788:    Level: advanced

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


7793: @*/
7794: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7795: {

7801:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7802:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7803:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7804:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7805:   return(0);
7806: }

7808: /* ----------------------------------------------------------------*/
7811: /*@C
7812:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7814:    Neighbor-wise Collective on Mat and Vecs

7816:    Input Parameters:
7817: +  mat - the factored matrix
7818: -  b - the right-hand-side vectors

7820:    Output Parameter:
7821: .  x - the result vectors

7823:    Notes:
7824:    The vectors b and x cannot be the same.  I.e., one cannot
7825:    call MatSolves(A,x,x).

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

7832:    Level: developer

7834:    Concepts: matrices^triangular solves

7836: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7837: @*/
7838: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7839: {

7845:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7846:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7847:   if (!mat->rmap->N && !mat->cmap->N) return(0);

7849:   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7850:   MatCheckPreallocated(mat,1);
7851:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7852:   (*mat->ops->solves)(mat,b,x);
7853:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7854:   return(0);
7855: }

7859: /*@
7860:    MatIsSymmetric - Test whether a matrix is symmetric

7862:    Collective on Mat

7864:    Input Parameter:
7865: +  A - the matrix to test
7866: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

7868:    Output Parameters:
7869: .  flg - the result

7871:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

7873:    Level: intermediate

7875:    Concepts: matrix^symmetry

7877: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7878: @*/
7879: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7880: {


7887:   if (!A->symmetric_set) {
7888:     if (!A->ops->issymmetric) {
7889:       const MatType mattype;
7890:       MatGetType(A,&mattype);
7891:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7892:     }
7893:     (*A->ops->issymmetric)(A,tol,flg);
7894:     if (!tol) {
7895:       A->symmetric_set = PETSC_TRUE;
7896:       A->symmetric = *flg;
7897:       if (A->symmetric) {
7898:         A->structurally_symmetric_set = PETSC_TRUE;
7899:         A->structurally_symmetric     = PETSC_TRUE;
7900:       }
7901:     }
7902:   } else if (A->symmetric) {
7903:     *flg = PETSC_TRUE;
7904:   } else if (!tol) {
7905:     *flg = PETSC_FALSE;
7906:   } else {
7907:     if (!A->ops->issymmetric) {
7908:       const MatType mattype;
7909:       MatGetType(A,&mattype);
7910:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7911:     }
7912:     (*A->ops->issymmetric)(A,tol,flg);
7913:   }
7914:   return(0);
7915: }

7919: /*@
7920:    MatIsHermitian - Test whether a matrix is Hermitian

7922:    Collective on Mat

7924:    Input Parameter:
7925: +  A - the matrix to test
7926: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

7928:    Output Parameters:
7929: .  flg - the result

7931:    Level: intermediate

7933:    Concepts: matrix^symmetry

7935: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7936:           MatIsSymmetricKnown(), MatIsSymmetric()
7937: @*/
7938: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7939: {


7946:   if (!A->hermitian_set) {
7947:     if (!A->ops->ishermitian) {
7948:       const MatType mattype;
7949:       MatGetType(A,&mattype);
7950:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7951:     }
7952:     (*A->ops->ishermitian)(A,tol,flg);
7953:     if (!tol) {
7954:       A->hermitian_set = PETSC_TRUE;
7955:       A->hermitian = *flg;
7956:       if (A->hermitian) {
7957:         A->structurally_symmetric_set = PETSC_TRUE;
7958:         A->structurally_symmetric     = PETSC_TRUE;
7959:       }
7960:     }
7961:   } else if (A->hermitian) {
7962:     *flg = PETSC_TRUE;
7963:   } else if (!tol) {
7964:     *flg = PETSC_FALSE;
7965:   } else {
7966:     if (!A->ops->ishermitian) {
7967:       const MatType mattype;
7968:       MatGetType(A,&mattype);
7969:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7970:     }
7971:     (*A->ops->ishermitian)(A,tol,flg);
7972:   }
7973:   return(0);
7974: }

7978: /*@
7979:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

7981:    Not Collective

7983:    Input Parameter:
7984: .  A - the matrix to check

7986:    Output Parameters:
7987: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7988: -  flg - the result

7990:    Level: advanced

7992:    Concepts: matrix^symmetry

7994:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7995:          if you want it explicitly checked

7997: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7998: @*/
7999: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8000: {
8005:   if (A->symmetric_set) {
8006:     *set = PETSC_TRUE;
8007:     *flg = A->symmetric;
8008:   } else {
8009:     *set = PETSC_FALSE;
8010:   }
8011:   return(0);
8012: }

8016: /*@
8017:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8019:    Not Collective

8021:    Input Parameter:
8022: .  A - the matrix to check

8024:    Output Parameters:
8025: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8026: -  flg - the result

8028:    Level: advanced

8030:    Concepts: matrix^symmetry

8032:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8033:          if you want it explicitly checked

8035: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8036: @*/
8037: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8038: {
8043:   if (A->hermitian_set) {
8044:     *set = PETSC_TRUE;
8045:     *flg = A->hermitian;
8046:   } else {
8047:     *set = PETSC_FALSE;
8048:   }
8049:   return(0);
8050: }

8054: /*@
8055:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8057:    Collective on Mat

8059:    Input Parameter:
8060: .  A - the matrix to test

8062:    Output Parameters:
8063: .  flg - the result

8065:    Level: intermediate

8067:    Concepts: matrix^symmetry

8069: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8070: @*/
8071: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8072: {

8078:   if (!A->structurally_symmetric_set) {
8079:     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8080:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8081:     A->structurally_symmetric_set = PETSC_TRUE;
8082:   }
8083:   *flg = A->structurally_symmetric;
8084:   return(0);
8085: }

8089: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8090: /*@ 
8091:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8092:        to be communicated to other processors during the MatAssemblyBegin/End() process

8094:     Not collective

8096:    Input Parameter:
8097: .   vec - the vector

8099:    Output Parameters:
8100: +   nstash   - the size of the stash
8101: .   reallocs - the number of additional mallocs incurred.
8102: .   bnstash   - the size of the block stash
8103: -   breallocs - the number of additional mallocs incurred.in the block stash
8104:  
8105:    Level: advanced

8107: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8108:   
8109: @*/
8110: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8111: {
8114:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8115:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8116:   return(0);
8117: }

8121: /*@C
8122:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
8123:      parallel layout
8124:    
8125:    Collective on Mat

8127:    Input Parameter:
8128: .  mat - the matrix

8130:    Output Parameter:
8131: +   right - (optional) vector that the matrix can be multiplied against
8132: -   left - (optional) vector that the matrix vector product can be stored in

8134:   Level: advanced

8136: .seealso: MatCreate()
8137: @*/
8138: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8139: {

8145:   MatCheckPreallocated(mat,1);
8146:   if (mat->ops->getvecs) {
8147:     (*mat->ops->getvecs)(mat,right,left);
8148:   } else {
8149:     PetscMPIInt size;
8150:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
8151:     if (right) {
8152:       VecCreate(((PetscObject)mat)->comm,right);
8153:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8154:       VecSetBlockSize(*right,mat->rmap->bs);
8155:       VecSetType(*right,VECSTANDARD);
8156:       PetscLayoutReference(mat->cmap,&(*right)->map);
8157:     }
8158:     if (left) {
8159:       VecCreate(((PetscObject)mat)->comm,left);
8160:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8161:       VecSetBlockSize(*left,mat->rmap->bs);
8162:       VecSetType(*left,VECSTANDARD);
8163:       PetscLayoutReference(mat->rmap,&(*left)->map);
8164:     }
8165:   }
8166:   return(0);
8167: }

8171: /*@C
8172:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8173:      with default values.

8175:    Not Collective

8177:    Input Parameters:
8178: .    info - the MatFactorInfo data structure


8181:    Notes: The solvers are generally used through the KSP and PC objects, for example
8182:           PCLU, PCILU, PCCHOLESKY, PCICC

8184:    Level: developer

8186: .seealso: MatFactorInfo

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

8191: @*/

8193: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8194: {

8198:   PetscMemzero(info,sizeof(MatFactorInfo));
8199:   return(0);
8200: }

8204: /*@
8205:    MatPtAP - Creates the matrix product C = P^T * A * P

8207:    Neighbor-wise Collective on Mat

8209:    Input Parameters:
8210: +  A - the matrix
8211: .  P - the projection matrix
8212: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8213: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8215:    Output Parameters:
8216: .  C - the product matrix

8218:    Notes:
8219:    C will be created and must be destroyed by the user with MatDestroy().

8221:    This routine is currently only implemented for pairs of AIJ matrices and classes
8222:    which inherit from AIJ.  

8224:    Level: intermediate

8226: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8227: @*/
8228: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8229: {

8235:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8236:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8239:   MatCheckPreallocated(P,2);
8240:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8241:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8243:   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8244:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8245:   MatCheckPreallocated(A,1);

8247:   if (!A->ops->ptap) {
8248:     const MatType mattype;
8249:     MatGetType(A,&mattype);
8250:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8251:   }
8252:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8253:   (*A->ops->ptap)(A,P,scall,fill,C);
8254:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8255:   return(0);
8256: }

8260: /*@
8261:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8263:    Neighbor-wise Collective on Mat

8265:    Input Parameters:
8266: +  A - the matrix
8267: -  P - the projection matrix

8269:    Output Parameters:
8270: .  C - the product matrix

8272:    Notes:
8273:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8274:    the user using MatDeatroy().

8276:    This routine is currently only implemented for pairs of AIJ matrices and classes
8277:    which inherit from AIJ.  C will be of type MATAIJ.

8279:    Level: intermediate

8281: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8282: @*/
8283: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8284: {

8290:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8291:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8294:   MatCheckPreallocated(P,2);
8295:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8296:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8299:   MatCheckPreallocated(C,3);
8300:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8301:   if (P->cmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
8302:   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8303:   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8304:   if (P->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
8305:   MatCheckPreallocated(A,1);

8307:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8308:   (*A->ops->ptapnumeric)(A,P,C);
8309:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8310:   return(0);
8311: }

8315: /*@
8316:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8318:    Neighbor-wise Collective on Mat

8320:    Input Parameters:
8321: +  A - the matrix
8322: -  P - the projection matrix

8324:    Output Parameters:
8325: .  C - the (i,j) structure of the product matrix

8327:    Notes:
8328:    C will be created and must be destroyed by the user with MatDestroy().

8330:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8331:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8332:    this (i,j) structure by calling MatPtAPNumeric().

8334:    Level: intermediate

8336: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8337: @*/
8338: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8339: {

8345:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8346:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8347:   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8350:   MatCheckPreallocated(P,2);
8351:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8352:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8355:   if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
8356:   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8357:   MatCheckPreallocated(A,1);
8358:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8359:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8360:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8362:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */

8364:   return(0);
8365: }

8369: /*@
8370:    MatRARt - Creates the matrix product C = R * A * R^T

8372:    Neighbor-wise Collective on Mat

8374:    Input Parameters:
8375: +  A - the matrix
8376: .  R - the projection matrix
8377: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8378: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

8380:    Output Parameters:
8381: .  C - the product matrix

8383:    Notes:
8384:    C will be created and must be destroyed by the user with MatDestroy().

8386:    This routine is currently only implemented for pairs of AIJ matrices and classes
8387:    which inherit from AIJ.  

8389:    Level: intermediate

8391: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8392: @*/
8393: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8394: {

8400:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8401:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8404:   MatCheckPreallocated(R,2);
8405:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8406:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8408:   if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)R)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8409:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8410:   MatCheckPreallocated(A,1);

8412:   if (!A->ops->rart) {
8413:     const MatType mattype;
8414:     MatGetType(A,&mattype);
8415:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8416:   }
8417:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8418:   (*A->ops->rart)(A,R,scall,fill,C);
8419:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8420:   return(0);
8421: }

8425: /*@
8426:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8428:    Neighbor-wise Collective on Mat

8430:    Input Parameters:
8431: +  A - the matrix
8432: -  R - the projection matrix

8434:    Output Parameters:
8435: .  C - the product matrix

8437:    Notes:
8438:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8439:    the user using MatDeatroy().

8441:    This routine is currently only implemented for pairs of AIJ matrices and classes
8442:    which inherit from AIJ.  C will be of type MATAIJ.

8444:    Level: intermediate

8446: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8447: @*/
8448: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8449: {

8455:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8456:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8459:   MatCheckPreallocated(R,2);
8460:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8461:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8464:   MatCheckPreallocated(C,3);
8465:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8466:   if (R->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N);
8467:   if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8468:   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8469:   if (R->rmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N);
8470:   MatCheckPreallocated(A,1);

8472:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8473:   (*A->ops->rartnumeric)(A,R,C);
8474:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8475:   return(0);
8476: }

8480: /*@
8481:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8483:    Neighbor-wise Collective on Mat

8485:    Input Parameters:
8486: +  A - the matrix
8487: -  R - the projection matrix

8489:    Output Parameters:
8490: .  C - the (i,j) structure of the product matrix

8492:    Notes:
8493:    C will be created and must be destroyed by the user with MatDestroy().

8495:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8496:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8497:    this (i,j) structure by calling MatRARtNumeric().

8499:    Level: intermediate

8501: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8502: @*/
8503: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8504: {

8510:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8511:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8512:   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8515:   MatCheckPreallocated(R,2);
8516:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8517:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8520:   if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N);
8521:   if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
8522:   MatCheckPreallocated(A,1);
8523:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8524:   (*A->ops->rartsymbolic)(A,R,fill,C);
8525:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8527:   MatSetBlockSize(*C,A->rmap->bs);
8528:   return(0);
8529: }

8531: extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);

8535: /*@
8536:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8538:    Neighbor-wise Collective on Mat

8540:    Input Parameters:
8541: +  A - the left matrix
8542: .  B - the right matrix
8543: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8544: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8545:           if the result is a dense matrix this is irrelevent

8547:    Output Parameters:
8548: .  C - the product matrix

8550:    Notes:
8551:    Unless scall is MAT_REUSE_MATRIX C will be created.

8553:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8554:    
8555:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8556:    actually needed.

8558:    If you have many matrices with the same non-zero structure to multiply, you 
8559:    should either 
8560: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8561: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8563:    Level: intermediate

8565: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8566: @*/
8567: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8568: {
8570:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8571:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8572:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

8577:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8578:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8581:   MatCheckPreallocated(B,2);
8582:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8583:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8585:   if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8586:   if (scall == MAT_REUSE_MATRIX){
8589:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8590:     (*(*C)->ops->matmult)(A,B,scall,fill,C);
8591:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8592:   }
8593:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8594:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8595:   MatCheckPreallocated(A,1);

8597:   fA = A->ops->matmult;
8598:   fB = B->ops->matmult;
8599:   if (fB == fA) {
8600:     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8601:     mult = fB;
8602:   } else {
8603:     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8604:     char  multname[256];
8605:     PetscStrcpy(multname,"MatMatMult_");
8606:     PetscStrcat(multname,((PetscObject)A)->type_name);
8607:     PetscStrcat(multname,"_");
8608:     PetscStrcat(multname,((PetscObject)B)->type_name);
8609:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8610:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8611:     if(!mult){
8612:       /* dual dispatch using MatQueryOp */
8613:       MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8614:       if (!mult) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8615:     }
8616:   }
8617:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8618:   (*mult)(A,B,scall,fill,C);
8619:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8620:   return(0);
8621: }

8625: /*@
8626:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8627:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8629:    Neighbor-wise Collective on Mat

8631:    Input Parameters:
8632: +  A - the left matrix
8633: .  B - the right matrix
8634: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8635:       if C is a dense matrix this is irrelevent
8636:  
8637:    Output Parameters:
8638: .  C - the product matrix

8640:    Notes:
8641:    Unless scall is MAT_REUSE_MATRIX C will be created.

8643:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8644:    actually needed.

8646:    This routine is currently implemented for 
8647:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8648:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8649:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8651:    Level: intermediate

8653:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8654:      We should incorporate them into PETSc.

8656: .seealso: MatMatMult(), MatMatMultNumeric()
8657: @*/
8658: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8659: {
8661:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8662:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8663:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

8668:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8669:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8673:   MatCheckPreallocated(B,2);
8674:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8675:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8678:   if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8679:   if (fill == PETSC_DEFAULT) fill = 2.0;
8680:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8681:   MatCheckPreallocated(A,1);
8682: 
8683:   Asymbolic = A->ops->matmultsymbolic;
8684:   Bsymbolic = B->ops->matmultsymbolic;
8685:   if (Asymbolic == Bsymbolic){
8686:     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8687:     symbolic = Bsymbolic;
8688:   } else { /* dispatch based on the type of A and B */
8689:     char  symbolicname[256];
8690:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8691:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8692:     PetscStrcat(symbolicname,"_");
8693:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8694:     PetscStrcat(symbolicname,"_C");
8695:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8696:     if (!symbolic) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8697:   }
8698:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8699:   (*symbolic)(A,B,fill,C);
8700:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8701:   return(0);
8702: }

8706: /*@
8707:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8708:    Call this routine after first calling MatMatMultSymbolic().

8710:    Neighbor-wise Collective on Mat

8712:    Input Parameters:
8713: +  A - the left matrix
8714: -  B - the right matrix

8716:    Output Parameters:
8717: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8719:    Notes:
8720:    C must have been created with MatMatMultSymbolic().

8722:    This routine is currently implemented for 
8723:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8724:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8725:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8727:    Level: intermediate

8729: .seealso: MatMatMult(), MatMatMultSymbolic()
8730: @*/
8731: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8732: {
8734:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8735:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8736:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

8741:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8742:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8746:   MatCheckPreallocated(B,2);
8747:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8748:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8752:   MatCheckPreallocated(C,3);
8753:   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8754:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8756:   if (B->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
8757:   if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
8758:   if (A->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
8759:   MatCheckPreallocated(A,1);

8761:   Anumeric = A->ops->matmultnumeric;
8762:   Bnumeric = B->ops->matmultnumeric;
8763:   if (Anumeric == Bnumeric){
8764:     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8765:     numeric = Bnumeric;
8766:   } else {
8767:     char  numericname[256];
8768:     PetscStrcpy(numericname,"MatMatMultNumeric_");
8769:     PetscStrcat(numericname,((PetscObject)A)->type_name);
8770:     PetscStrcat(numericname,"_");
8771:     PetscStrcat(numericname,((PetscObject)B)->type_name);
8772:     PetscStrcat(numericname,"_C");
8773:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8774:     if (!numeric)
8775:       SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8776:   }
8777:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8778:   (*numeric)(A,B,C);
8779:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8780:   return(0);
8781: }

8785: /*@
8786:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

8788:    Neighbor-wise Collective on Mat

8790:    Input Parameters:
8791: +  A - the left matrix
8792: .  B - the right matrix
8793: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8794: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8796:    Output Parameters:
8797: .  C - the product matrix

8799:    Notes:
8800:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8802:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8804:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8805:    actually needed.

8807:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

8809:    Level: intermediate

8811: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8812: @*/
8813: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8814: {
8816:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8817:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8822:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8823:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8826:   MatCheckPreallocated(B,2);
8827:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8828:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8830:   if (B->cmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N);
8831:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8832:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8833:   MatCheckPreallocated(A,1);

8835:   fA = A->ops->mattransposemult;
8836:   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8837:   fB = B->ops->mattransposemult;
8838:   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8839:   if (fB!=fA) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

8841:   if (scall == MAT_INITIAL_MATRIX){
8842:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8843:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8844:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8845:   }
8846:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8847:   (*A->ops->mattransposemultnumeric)(A,B,*C);
8848:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8849:   return(0);
8850: }

8854: /*@
8855:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

8857:    Neighbor-wise Collective on Mat

8859:    Input Parameters:
8860: +  A - the left matrix
8861: .  B - the right matrix
8862: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8863: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8865:    Output Parameters:
8866: .  C - the product matrix

8868:    Notes:
8869:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8871:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8873:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8874:    actually needed.

8876:    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8877:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.

8879:    Level: intermediate

8881: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8882: @*/
8883: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8884: {
8886:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8887:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8888:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);

8893:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8894:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8897:   MatCheckPreallocated(B,2);
8898:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8899:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8901:   if (B->rmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
8902:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8903:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8904:   MatCheckPreallocated(A,1);

8906:   fA = A->ops->transposematmult;
8907:   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8908:   fB = B->ops->transposematmult;
8909:   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8910:   if (fB==fA) {
8911:     transposematmult = fA;
8912:   }
8913:   else {
8914:     /* dual dispatch using MatQueryOp */
8915:     MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8916:     if(!transposematmult)
8917:       SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8918:   }
8919:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8920:   (*transposematmult)(A,B,scall,fill,C);
8921:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8922:   return(0);
8923: }

8927: /*@C
8928:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 

8930:    Collective on Mat

8932:    Input Parameters:
8933: +  mat - the matrix
8934: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8935: .  subcomm - MPI communicator split from the communicator where mat resides in
8936: .  mlocal_red - number of local rows of the redundant matrix
8937: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

8939:    Output Parameter:
8940: .  matredundant - redundant matrix

8942:    Notes:
8943:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the 
8944:    original matrix has not changed from that last call to MatGetRedundantMatrix().

8946:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8947:    calling it. 

8949:    Only MPIAIJ matrix is supported. 
8950:    
8951:    Level: advanced

8953:    Concepts: subcommunicator
8954:    Concepts: duplicate matrix

8956: .seealso: MatDestroy()
8957: @*/
8958: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8959: {

8964:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8967:   }
8968:   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8969:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8970:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8971:   MatCheckPreallocated(mat,1);

8973:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8974:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8975:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8976:   return(0);
8977: }

8981: /*@C
8982:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8983:    a given 'mat' object. Each submatrix can span multiple procs.

8985:    Collective on Mat

8987:    Input Parameters:
8988: +  mat - the matrix
8989: .  subcomm - the subcommunicator obtained by com_split(comm)
8990: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

8992:    Output Parameter:
8993: .  subMat - 'parallel submatrices each spans a given subcomm

8995:   Notes:
8996:   The submatrix partition across processors is dicated by 'subComm' a
8997:   communicator obtained by com_split(comm). The comm_split
8998:   is not restriced to be grouped with consequitive original ranks.

9000:   Due the comm_split() usage, the parallel layout of the submatrices
9001:   map directly to the layout of the original matrix [wrt the local
9002:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9003:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9004:   the subMat. However the offDiagMat looses some columns - and this is
9005:   reconstructed with MatSetValues()

9007:   Level: advanced

9009:   Concepts: subcommunicator
9010:   Concepts: submatrices

9012: .seealso: MatGetSubMatrices()
9013: @*/
9014: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9015: {
9017:   PetscMPIInt    commsize,subCommSize;

9020:   MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
9021:   MPI_Comm_size(subComm,&subCommSize);
9022:   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9023: 
9024:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9025:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9026:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9027:   return(0);
9028: }

9032: /*@
9033:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9035:    Not Collective

9037:    Input Arguments:
9038:    mat - matrix to extract local submatrix from
9039:    isrow - local row indices for submatrix
9040:    iscol - local column indices for submatrix

9042:    Output Arguments:
9043:    submat - the submatrix

9045:    Level: intermediate

9047:    Notes:
9048:    The submat should be returned with MatRestoreLocalSubMatrix().

9050:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9051:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9053:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9054:    MatSetValuesBlockedLocal() will also be implemented.

9056: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9057: @*/
9058: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9059: {


9069:   if (mat->ops->getlocalsubmatrix) {
9070:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9071:   } else {
9072:     MatCreateLocalRef(mat,isrow,iscol,submat);
9073:   }
9074:   return(0);
9075: }

9079: /*@
9080:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9082:    Not Collective

9084:    Input Arguments:
9085:    mat - matrix to extract local submatrix from
9086:    isrow - local row indices for submatrix
9087:    iscol - local column indices for submatrix
9088:    submat - the submatrix

9090:    Level: intermediate

9092: .seealso: MatGetLocalSubMatrix()
9093: @*/
9094: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9095: {


9106:   if (mat->ops->restorelocalsubmatrix) {
9107:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9108:   } else {
9109:     MatDestroy(submat);
9110:   }
9111:   *submat = PETSC_NULL;
9112:   return(0);
9113: }

9115: /* --------------------------------------------------------*/
9118: /*@
9119:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9121:    Collective on Mat

9123:    Input Parameter:
9124: .  mat - the matrix

9126:    Output Parameter:
9127: .  is - if any rows have zero diagonals this contains the list of them

9129:    Level: developer

9131:    Concepts: matrix-vector product

9133: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9134: @*/
9135: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9136: {

9142:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9143:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9145:   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9146:   (*mat->ops->findzerodiagonals)(mat,is);
9147:   return(0);
9148: }

9152: /*@C
9153:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9155:   Collective on Mat

9157:   Input Parameters:
9158: . mat - the matrix

9160:   Output Parameters:
9161: . values - the block inverses in column major order (FORTRAN-like)

9163:    Note:
9164:    This routine is not available from Fortran.

9166:   Level: advanced
9167: @*/
9168: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9169: {

9174:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9175:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9176:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9177:   (*mat->ops->invertblockdiagonal)(mat,values);
9178:   return(0);
9179: }

9183: /*@C
9184:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9185:     via MatTransposeColoringCreate().

9187:     Collective on MatTransposeColoring

9189:     Input Parameter:
9190: .   c - coloring context

9192:     Level: intermediate

9194: .seealso: MatTransposeColoringCreate()
9195: @*/
9196: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9197: {
9198:   PetscErrorCode       ierr;
9199:   MatTransposeColoring matcolor=*c;

9202:   if (!matcolor) return(0);
9203:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9205:   PetscFree(matcolor->ncolumns);
9206:   PetscFree(matcolor->nrows);
9207:   PetscFree(matcolor->colorforrow);
9208:   PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9209:   PetscFree(matcolor->colorforcol);
9210:   PetscFree(matcolor->columns);
9211:   PetscHeaderDestroy(c);
9212:   return(0);
9213: }

9217: /*@C
9218:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 
9219:     a MatTransposeColoring context has been created, computes a dense B^T by Apply 
9220:     MatTransposeColoring to sparse B.

9222:     Collective on MatTransposeColoring

9224:     Input Parameters:
9225: +   B - sparse matrix B
9226: .   Btdense - symbolic dense matrix B^T
9227: -   coloring - coloring context created with MatTransposeColoringCreate()

9229:     Output Parameter:
9230: .   Btdense - dense matrix B^T 

9232:     Options Database Keys:
9233: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9234: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9235: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9237:     Level: intermediate

9239: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9241: .keywords: coloring
9242: @*/
9243: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9244: {

9251: 
9252:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9253:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9254:   return(0);
9255: }

9259: /*@C
9260:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 
9261:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9262:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 
9263:     Csp from Cden.

9265:     Collective on MatTransposeColoring

9267:     Input Parameters:
9268: +   coloring - coloring context created with MatTransposeColoringCreate()
9269: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9271:     Output Parameter:
9272: .   Csp - sparse matrix  

9274:     Options Database Keys:
9275: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9276: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9277: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9279:     Level: intermediate

9281: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9283: .keywords: coloring
9284: @*/
9285: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9286: {

9293: 
9294:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9295:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9296:   return(0);
9297: }

9301: /*@C
9302:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9304:    Collective on Mat

9306:    Input Parameters:
9307: +  mat - the matrix product C
9308: -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()

9310:     Output Parameter:
9311: .   color - the new coloring context
9312:    
9313:     Level: intermediate

9315: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9316:            MatTransColoringApplyDen()ToSp, MatTransposeColoringView(), 
9317: @*/
9318: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9319: {
9320:   MatTransposeColoring  c;
9321:   MPI_Comm              comm;
9322:   PetscErrorCode        ierr;

9325:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9326:   PetscObjectGetComm((PetscObject)mat,&comm);
9327:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,0,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9329:   c->ctype = iscoloring->ctype;
9330:   if (mat->ops->transposecoloringcreate) {
9331:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9332:   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");

9334:   *color = c;
9335:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9336:   return(0);
9337: }