Actual source code: matrix.c

petsc-3.3-p7 2013-05-11
  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=%lld, allocated nonzeros=%lld\n",(Petsc64bitInt)info.nz_used,(Petsc64bitInt)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

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.
5976: $  This function requires that the matrix be preallocated. If you have not preallocated, consider using
5977: $    PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
5978: $  and then MPI_Scan() to calculate prefix sums of the local sizes.

5980:    Level: beginner

5982:    Concepts: matrices^row ownership

5984: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()

5986: @*/
5987: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5988: {

5995:   MatCheckPreallocated(mat,1);
5996:   if (m) *m = mat->rmap->rstart;
5997:   if (n) *n = mat->rmap->rend;
5998:   return(0);
5999: }

6003: /*@C
6004:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
6005:    each process

6007:    Not Collective, unless matrix has not been allocated, then collective on Mat

6009:    Input Parameters:
6010: .  mat - the matrix

6012:    Output Parameters:
6013: .  ranges - start of each processors portion plus one more then the total length at the end

6015:    Level: beginner

6017:    Concepts: matrices^row ownership

6019: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

6021: @*/
6022: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6023: {

6029:   MatCheckPreallocated(mat,1);
6030:   PetscLayoutGetRanges(mat->rmap,ranges);
6031:   return(0);
6032: }

6036: /*@C
6037:    MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6038:    this processor. (The columns of the "diagonal blocks" for each process)

6040:    Not Collective, unless matrix has not been allocated, then collective on Mat

6042:    Input Parameters:
6043: .  mat - the matrix

6045:    Output Parameters:
6046: .  ranges - start of each processors portion plus one more then the total length at the end

6048:    Level: beginner

6050:    Concepts: matrices^column ownership

6052: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()

6054: @*/
6055: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6056: {

6062:   MatCheckPreallocated(mat,1);
6063:   PetscLayoutGetRanges(mat->cmap,ranges);
6064:   return(0);
6065: }

6069: /*@C
6070:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6071:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
6072:    to complete the factorization.

6074:    Collective on Mat

6076:    Input Parameters:
6077: +  mat - the matrix
6078: .  row - row permutation
6079: .  column - column permutation
6080: -  info - structure containing 
6081: $      levels - number of levels of fill.
6082: $      expected fill - as ratio of original fill.
6083: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6084:                 missing diagonal entries)

6086:    Output Parameters:
6087: .  fact - new matrix that has been symbolically factored

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

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

6097:    Level: developer

6099:   Concepts: matrices^symbolic LU factorization
6100:   Concepts: matrices^factorization
6101:   Concepts: LU^symbolic factorization

6103: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6104:           MatGetOrdering(), MatFactorInfo

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

6109: @*/
6110: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6111: {

6121:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6122:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6123:   if (!(fact)->ops->ilufactorsymbolic) {
6124:     const MatSolverPackage spackage;
6125:     MatFactorGetSolverPackage(fact,&spackage);
6126:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6127:   }
6128:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6129:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6130:   MatCheckPreallocated(mat,2);

6132:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6133:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6134:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6135:   return(0);
6136: }

6140: /*@C
6141:    MatICCFactorSymbolic - Performs symbolic incomplete
6142:    Cholesky factorization for a symmetric matrix.  Use 
6143:    MatCholeskyFactorNumeric() to complete the factorization.

6145:    Collective on Mat

6147:    Input Parameters:
6148: +  mat - the matrix
6149: .  perm - row and column permutation
6150: -  info - structure containing 
6151: $      levels - number of levels of fill.
6152: $      expected fill - as ratio of original fill.

6154:    Output Parameter:
6155: .  fact - the factored matrix

6157:    Notes:
6158:    Most users should employ the KSP interface for linear solvers
6159:    instead of working directly with matrix algebra routines such as this.
6160:    See, e.g., KSPCreate().

6162:    Level: developer

6164:   Concepts: matrices^symbolic incomplete Cholesky factorization
6165:   Concepts: matrices^factorization
6166:   Concepts: Cholsky^symbolic factorization

6168: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo

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

6173: @*/
6174: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6175: {

6184:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6185:   if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6186:   if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6187:   if (!(fact)->ops->iccfactorsymbolic) {
6188:     const MatSolverPackage spackage;
6189:     MatFactorGetSolverPackage(fact,&spackage);
6190:     SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6191:   }
6192:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6193:   MatCheckPreallocated(mat,2);

6195:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6196:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6197:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6198:   return(0);
6199: }

6203: /*@C
6204:    MatGetArray - Returns a pointer to the element values in the matrix.
6205:    The result of this routine is dependent on the underlying matrix data
6206:    structure, and may not even work for certain matrix types.  You MUST
6207:    call MatRestoreArray() when you no longer need to access the array.

6209:    Not Collective

6211:    Input Parameter:
6212: .  mat - the matrix

6214:    Output Parameter:
6215: .  v - the location of the values


6218:    Fortran Note:
6219:    This routine is used differently from Fortran, e.g.,
6220: .vb
6221:         Mat         mat
6222:         PetscScalar mat_array(1)
6223:         PetscOffset i_mat
6224:         PetscErrorCode ierr
6225:         call MatGetArray(mat,mat_array,i_mat,ierr)

6227:   C  Access first local entry in matrix; note that array is
6228:   C  treated as one dimensional
6229:         value = mat_array(i_mat + 1)

6231:         [... other code ...]
6232:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6233: .ve

6235:    See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a> and 
6236:    src/mat/examples/tests for details.

6238:    Level: advanced

6240:    Concepts: matrices^access array

6242: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
6243: @*/
6244: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
6245: {

6252:   if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6253:   MatCheckPreallocated(mat,1);
6254:   (*mat->ops->getarray)(mat,v);
6255:   CHKMEMQ;
6256:   return(0);
6257: }

6261: /*@C
6262:    MatRestoreArray - Restores the matrix after MatGetArray() has been called.

6264:    Not Collective

6266:    Input Parameter:
6267: +  mat - the matrix
6268: -  v - the location of the values

6270:    Fortran Note:
6271:    This routine is used differently from Fortran, e.g.,
6272: .vb
6273:         Mat         mat
6274:         PetscScalar mat_array(1)
6275:         PetscOffset i_mat
6276:         PetscErrorCode ierr
6277:         call MatGetArray(mat,mat_array,i_mat,ierr)

6279:   C  Access first local entry in matrix; note that array is
6280:   C  treated as one dimensional
6281:         value = mat_array(i_mat + 1)

6283:         [... other code ...]
6284:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
6285: .ve

6287:    See the <a href="../../docs/manual.pdf#Chapter 9 PETSc for Fortran Users">Fortran chapter of the users manual</a>
6288:    src/mat/examples/tests for details

6290:    Level: advanced

6292: .seealso: MatGetArray(), MatRestoreArrayF90()
6293: @*/
6294: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
6295: {

6302:   CHKMEMQ;
6303:   if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6304:   (*mat->ops->restorearray)(mat,v);
6305:   PetscObjectStateIncrease((PetscObject)mat);
6306: #if defined(PETSC_HAVE_CUSP)
6307:   if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6308:     mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6309:   }
6310: #endif
6311:   return(0);
6312: }

6316: /*@C
6317:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6318:    points to an array of valid matrices, they may be reused to store the new
6319:    submatrices.

6321:    Collective on Mat

6323:    Input Parameters:
6324: +  mat - the matrix
6325: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
6326: .  irow, icol - index sets of rows and columns to extract (must be sorted)
6327: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6329:    Output Parameter:
6330: .  submat - the array of submatrices

6332:    Notes:
6333:    MatGetSubMatrices() can extract ONLY sequential submatrices
6334:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
6335:    to extract a parallel submatrix.

6337:    Currently both row and column indices must be sorted to guarantee 
6338:    correctness with all matrix types.

6340:    When extracting submatrices from a parallel matrix, each processor can
6341:    form a different submatrix by setting the rows and columns of its
6342:    individual index sets according to the local submatrix desired.

6344:    When finished using the submatrices, the user should destroy
6345:    them with MatDestroyMatrices().

6347:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the 
6348:    original matrix has not changed from that last call to MatGetSubMatrices().

6350:    This routine creates the matrices in submat; you should NOT create them before
6351:    calling it. It also allocates the array of matrix pointers submat.

6353:    For BAIJ matrices the index sets must respect the block structure, that is if they
6354:    request one row/column in a block, they must request all rows/columns that are in
6355:    that block. For example, if the block size is 2 you cannot request just row 0 and 
6356:    column 0.

6358:    Fortran Note:
6359:    The Fortran interface is slightly different from that given below; it 
6360:    requires one to pass in  as submat a Mat (integer) array of size at least m.

6362:    Level: advanced

6364:    Concepts: matrices^accessing submatrices
6365:    Concepts: submatrices

6367: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6368: @*/
6369: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6370: {
6372:   PetscInt        i;
6373:   PetscBool       eq;

6378:   if (n) {
6383:   }
6385:   if (n && scall == MAT_REUSE_MATRIX) {
6388:   }
6389:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6390:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6391:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6392:   MatCheckPreallocated(mat,1);

6394:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6395:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6396:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6397:   for (i=0; i<n; i++) {
6398:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6399:       ISEqual(irow[i],icol[i],&eq);
6400:       if (eq) {
6401:         if (mat->symmetric){
6402:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6403:         } else if (mat->hermitian) {
6404:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6405:         } else if (mat->structurally_symmetric) {
6406:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6407:         }
6408:       }
6409:     }
6410:   }
6411:   return(0);
6412: }

6416: PetscErrorCode  MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6417: {
6419:   PetscInt        i;
6420:   PetscBool       eq;

6425:   if (n) {
6430:   }
6432:   if (n && scall == MAT_REUSE_MATRIX) {
6435:   }
6436:   if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6437:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6438:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6439:   MatCheckPreallocated(mat,1);

6441:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6442:   (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6443:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6444:   for (i=0; i<n; i++) {
6445:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6446:       ISEqual(irow[i],icol[i],&eq);
6447:       if (eq) {
6448:         if (mat->symmetric){
6449:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6450:         } else if (mat->hermitian) {
6451:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6452:         } else if (mat->structurally_symmetric) {
6453:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6454:         }
6455:       }
6456:     }
6457:   }
6458:   return(0);
6459: }

6463: /*@C
6464:    MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().

6466:    Collective on Mat

6468:    Input Parameters:
6469: +  n - the number of local matrices
6470: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6471:                        sequence of MatGetSubMatrices())

6473:    Level: advanced

6475:     Notes: Frees not only the matrices, but also the array that contains the matrices
6476:            In Fortran will not free the array.

6478: .seealso: MatGetSubMatrices()
6479: @*/
6480: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
6481: {
6483:   PetscInt       i;

6486:   if (!*mat) return(0);
6487:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6489:   for (i=0; i<n; i++) {
6490:     MatDestroy(&(*mat)[i]);
6491:   }
6492:   /* memory is allocated even if n = 0 */
6493:   PetscFree(*mat);
6494:   *mat = PETSC_NULL;
6495:   return(0);
6496: }

6500: /*@C
6501:    MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 

6503:    Collective on Mat

6505:    Input Parameters:
6506: .  mat - the matrix

6508:    Output Parameter:
6509: .  matstruct - the sequential matrix with the nonzero structure of mat

6511:   Level: intermediate

6513: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6514: @*/
6515: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6516: {

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

6527:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6528:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6529:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6530:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6531:   return(0);
6532: }

6536: /*@C
6537:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

6539:    Collective on Mat

6541:    Input Parameters:
6542: .  mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6543:                        sequence of MatGetSequentialNonzeroStructure())

6545:    Level: advanced

6547:     Notes: Frees not only the matrices, but also the array that contains the matrices

6549: .seealso: MatGetSeqNonzeroStructure()
6550: @*/
6551: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
6552: {

6557:   MatDestroy(mat);
6558:   return(0);
6559: }

6563: /*@
6564:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6565:    replaces the index sets by larger ones that represent submatrices with
6566:    additional overlap.

6568:    Collective on Mat

6570:    Input Parameters:
6571: +  mat - the matrix
6572: .  n   - the number of index sets
6573: .  is  - the array of index sets (these index sets will changed during the call)
6574: -  ov  - the additional overlap requested

6576:    Level: developer

6578:    Concepts: overlap
6579:    Concepts: ASM^computing overlap

6581: .seealso: MatGetSubMatrices()
6582: @*/
6583: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6584: {

6590:   if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6591:   if (n) {
6594:   }
6595:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6596:   if (mat->factortype)     SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6597:   MatCheckPreallocated(mat,1);

6599:   if (!ov) return(0);
6600:   if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6601:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6602:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
6603:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6604:   return(0);
6605: }

6609: /*@
6610:    MatGetBlockSize - Returns the matrix block size; useful especially for the
6611:    block row and block diagonal formats.
6612:    
6613:    Not Collective

6615:    Input Parameter:
6616: .  mat - the matrix

6618:    Output Parameter:
6619: .  bs - block size

6621:    Notes:
6622:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6624:    Level: intermediate

6626:    Concepts: matrices^block size

6628: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6629: @*/
6630: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
6631: {

6637:   MatCheckPreallocated(mat,1);
6638:   *bs = mat->rmap->bs;
6639:   return(0);
6640: }

6644: /*@
6645:    MatGetBlockSizes - Returns the matrix block row and column sizes; 
6646:    useful especially for the block row and block diagonal formats.
6647:    
6648:    Not Collective

6650:    Input Parameter:
6651: .  mat - the matrix

6653:    Output Parameter:
6654: .  rbs - row block size
6655: .  cbs - coumn block size

6657:    Notes:
6658:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

6660:    Level: intermediate

6662:    Concepts: matrices^block size

6664: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6665: @*/
6666: PetscErrorCode  MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6667: {

6674:   MatCheckPreallocated(mat,1);
6675:   if(rbs) *rbs = mat->rmap->bs;
6676:   if(cbs) *cbs = mat->cmap->bs;
6677:   return(0);
6678: }

6682: /*@
6683:    MatSetBlockSize - Sets the matrix block size.
6684:    
6685:    Logically Collective on Mat

6687:    Input Parameters:
6688: +  mat - the matrix
6689: -  bs - block size

6691:    Notes:
6692:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6694:    Level: intermediate

6696:    Concepts: matrices^block size

6698: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6699: @*/
6700: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
6701: {

6707:   PetscLayoutSetBlockSize(mat->rmap,bs);
6708:   PetscLayoutSetBlockSize(mat->cmap,bs);
6709:   return(0);
6710: }

6714: /*@
6715:    MatSetBlockSizes - Sets the matrix block row and column sizes.
6716:    
6717:    Logically Collective on Mat

6719:    Input Parameters:
6720: +  mat - the matrix
6721: -  rbs - row block size
6722: -  cbs - column block size

6724:    Notes:
6725:      This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later

6727:    Level: intermediate

6729:    Concepts: matrices^block size

6731: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6732: @*/
6733: PetscErrorCode  MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6734: {

6740:   PetscLayoutSetBlockSize(mat->rmap,rbs);
6741:   PetscLayoutSetBlockSize(mat->cmap,cbs);
6742:   return(0);
6743: }

6747: /*@C
6748:     MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.

6750:    Collective on Mat

6752:     Input Parameters:
6753: +   mat - the matrix
6754: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
6755: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be   symmetrized
6756: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
6757:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6758:                  always used.

6760:     Output Parameters:
6761: +   n - number of rows in the (possibly compressed) matrix
6762: .   ia - the row pointers [of length n+1]
6763: .   ja - the column indices
6764: -   done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6765:            are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set

6767:     Level: developer

6769:     Notes: You CANNOT change any of the ia[] or ja[] values.

6771:            Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values

6773:     Fortran Node

6775:            In Fortran use
6776: $           PetscInt ia(1), ja(1)
6777: $           PetscOffset iia, jja
6778: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6779: $
6780: $          or 
6781: $
6782: $           PetscScalar, pointer :: xx_v(:)
6783: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6784:   
6785:  
6786:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6788: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6789: @*/
6790: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6791: {

6801:   MatCheckPreallocated(mat,1);
6802:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6803:   else {
6804:     *done = PETSC_TRUE;
6805:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6806:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6807:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6808:   }
6809:   return(0);
6810: }

6814: /*@C
6815:     MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.

6817:     Collective on Mat

6819:     Input Parameters:
6820: +   mat - the matrix
6821: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6822: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6823:                 symmetrized
6824: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6825:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6826:                  always used.

6828:     Output Parameters:
6829: +   n - number of columns in the (possibly compressed) matrix
6830: .   ia - the column pointers
6831: .   ja - the row indices
6832: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6834:     Level: developer

6836: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6837: @*/
6838: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6839: {

6849:   MatCheckPreallocated(mat,1);
6850:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6851:   else {
6852:     *done = PETSC_TRUE;
6853:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6854:   }
6855:   return(0);
6856: }

6860: /*@C
6861:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6862:     MatGetRowIJ().

6864:     Collective on Mat

6866:     Input Parameters:
6867: +   mat - the matrix
6868: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6869: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6870:                 symmetrized
6871: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6872:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6873:                  always used.

6875:     Output Parameters:
6876: +   n - size of (possibly compressed) matrix
6877: .   ia - the row pointers
6878: .   ja - the column indices
6879: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6881:     Level: developer

6883: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6884: @*/
6885: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6886: {

6895:   MatCheckPreallocated(mat,1);

6897:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6898:   else {
6899:     *done = PETSC_TRUE;
6900:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6901:   }
6902:   return(0);
6903: }

6907: /*@C
6908:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6909:     MatGetColumnIJ().

6911:     Collective on Mat

6913:     Input Parameters:
6914: +   mat - the matrix
6915: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6916: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6917:                 symmetrized
6918: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6919:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6920:                  always used.

6922:     Output Parameters:
6923: +   n - size of (possibly compressed) matrix
6924: .   ia - the column pointers
6925: .   ja - the row indices
6926: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6928:     Level: developer

6930: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6931: @*/
6932: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool  symmetric,PetscBool  inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool  *done)
6933: {

6942:   MatCheckPreallocated(mat,1);

6944:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6945:   else {
6946:     *done = PETSC_TRUE;
6947:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6948:   }
6949:   return(0);
6950: }

6954: /*@C
6955:     MatColoringPatch -Used inside matrix coloring routines that 
6956:     use MatGetRowIJ() and/or MatGetColumnIJ().

6958:     Collective on Mat

6960:     Input Parameters:
6961: +   mat - the matrix
6962: .   ncolors - max color value
6963: .   n   - number of entries in colorarray
6964: -   colorarray - array indicating color for each column

6966:     Output Parameters:
6967: .   iscoloring - coloring generated using colorarray information

6969:     Level: developer

6971: .seealso: MatGetRowIJ(), MatGetColumnIJ()

6973: @*/
6974: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6975: {

6983:   MatCheckPreallocated(mat,1);

6985:   if (!mat->ops->coloringpatch){
6986:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6987:   } else {
6988:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6989:   }
6990:   return(0);
6991: }


6996: /*@
6997:    MatSetUnfactored - Resets a factored matrix to be treated as unfactored.

6999:    Logically Collective on Mat

7001:    Input Parameter:
7002: .  mat - the factored matrix to be reset

7004:    Notes: 
7005:    This routine should be used only with factored matrices formed by in-place
7006:    factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7007:    format).  This option can save memory, for example, when solving nonlinear
7008:    systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7009:    ILU(0) preconditioner.  

7011:    Note that one can specify in-place ILU(0) factorization by calling 
7012: .vb
7013:      PCType(pc,PCILU);
7014:      PCFactorSeUseInPlace(pc);
7015: .ve
7016:    or by using the options -pc_type ilu -pc_factor_in_place

7018:    In-place factorization ILU(0) can also be used as a local
7019:    solver for the blocks within the block Jacobi or additive Schwarz
7020:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion 
7021:    of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7022:    local solver options.

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

7028:    Level: developer

7030: .seealso: PCFactorSetUseInPlace()

7032:    Concepts: matrices^unfactored

7034: @*/
7035: PetscErrorCode  MatSetUnfactored(Mat mat)
7036: {

7042:   MatCheckPreallocated(mat,1);
7043:   mat->factortype = MAT_FACTOR_NONE;
7044:   if (!mat->ops->setunfactored) return(0);
7045:   (*mat->ops->setunfactored)(mat);
7046:   return(0);
7047: }

7049: /*MC
7050:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

7052:     Synopsis:
7053:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)

7055:     Not collective

7057:     Input Parameter:
7058: .   x - matrix

7060:     Output Parameters:
7061: +   xx_v - the Fortran90 pointer to the array
7062: -   ierr - error code

7064:     Example of Usage: 
7065: .vb
7066:       PetscScalar, pointer xx_v(:,:)
7067:       ....
7068:       call MatGetArrayF90(x,xx_v,ierr)
7069:       a = xx_v(3)
7070:       call MatRestoreArrayF90(x,xx_v,ierr)
7071: .ve

7073:     Notes:
7074:     Not yet supported for all F90 compilers

7076:     Level: advanced

7078: .seealso:  MatRestoreArrayF90(), MatGetArray(), MatRestoreArray()

7080:     Concepts: matrices^accessing array

7082: M*/

7084: /*MC
7085:     MatRestoreArrayF90 - Restores a matrix array that has been
7086:     accessed with MatGetArrayF90().

7088:     Synopsis:
7089:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

7091:     Not collective

7093:     Input Parameters:
7094: +   x - matrix
7095: -   xx_v - the Fortran90 pointer to the array

7097:     Output Parameter:
7098: .   ierr - error code

7100:     Example of Usage: 
7101: .vb
7102:        PetscScalar, pointer xx_v(:)
7103:        ....
7104:        call MatGetArrayF90(x,xx_v,ierr)
7105:        a = xx_v(3)
7106:        call MatRestoreArrayF90(x,xx_v,ierr)
7107: .ve
7108:    
7109:     Notes:
7110:     Not yet supported for all F90 compilers

7112:     Level: advanced

7114: .seealso:  MatGetArrayF90(), MatGetArray(), MatRestoreArray()

7116: M*/


7121: /*@
7122:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
7123:                       as the original matrix.

7125:     Collective on Mat

7127:     Input Parameters:
7128: +   mat - the original matrix
7129: .   isrow - parallel IS containing the rows this processor should obtain
7130: .   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.
7131: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7133:     Output Parameter:
7134: .   newmat - the new submatrix, of the same type as the old

7136:     Level: advanced

7138:     Notes:
7139:     The submatrix will be able to be multiplied with vectors using the same layout as iscol.

7141:     The rows in isrow will be sorted into the same order as the original matrix on each process.

7143:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7144:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7145:    to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX  
7146:    will reuse the matrix generated the first time.  You should call MatDestroy() on newmat when 
7147:    you are finished using it.

7149:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7150:     the input matrix.

7152:     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran).

7154:    Example usage:
7155:    Consider the following 8x8 matrix with 34 non-zero values, that is
7156:    assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7157:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7158:    as follows:

7160: .vb
7161:             1  2  0  |  0  3  0  |  0  4
7162:     Proc0   0  5  6  |  7  0  0  |  8  0
7163:             9  0 10  | 11  0  0  | 12  0
7164:     -------------------------------------
7165:            13  0 14  | 15 16 17  |  0  0
7166:     Proc1   0 18  0  | 19 20 21  |  0  0
7167:             0  0  0  | 22 23  0  | 24  0
7168:     -------------------------------------
7169:     Proc2  25 26 27  |  0  0 28  | 29  0
7170:            30  0  0  | 31 32 33  |  0 34
7171: .ve

7173:     Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6].  The resulting submatrix is

7175: .vb
7176:             2  0  |  0  3  0  |  0
7177:     Proc0   5  6  |  7  0  0  |  8
7178:     -------------------------------
7179:     Proc1  18  0  | 19 20 21  |  0
7180:     -------------------------------
7181:     Proc2  26 27  |  0  0 28  | 29
7182:             0  0  | 31 32 33  |  0
7183: .ve


7186:     Concepts: matrices^submatrices

7188: .seealso: MatGetSubMatrices()
7189: @*/
7190: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7191: {
7193:   PetscMPIInt    size;
7194:   Mat            *local;
7195:   IS             iscoltmp;

7204:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7205:   MatCheckPreallocated(mat,1);
7206:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

7208:   if (!iscol) {
7209:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7210:   } else {
7211:     iscoltmp = iscol;
7212:   }

7214:   /* if original matrix is on just one processor then use submatrix generated */
7215:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7216:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7217:     if (!iscol) {ISDestroy(&iscoltmp);}
7218:     return(0);
7219:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7220:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7221:     *newmat = *local;
7222:     PetscFree(local);
7223:     if (!iscol) {ISDestroy(&iscoltmp);}
7224:     return(0);
7225:   } else if (!mat->ops->getsubmatrix) {
7226:     /* Create a new matrix type that implements the operation using the full matrix */
7227:     switch (cll) {
7228:       case MAT_INITIAL_MATRIX:
7229:         MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7230:         break;
7231:       case MAT_REUSE_MATRIX:
7232:         MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7233:         break;
7234:       default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7235:     }
7236:     if (!iscol) {ISDestroy(&iscoltmp);}
7237:     return(0);
7238:   }

7240:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7241:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7242:   if (!iscol) {ISDestroy(&iscoltmp);}
7243:   if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7244:   return(0);
7245: }

7249: /*@
7250:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7251:    used during the assembly process to store values that belong to 
7252:    other processors.

7254:    Not Collective

7256:    Input Parameters:
7257: +  mat   - the matrix
7258: .  size  - the initial size of the stash.
7259: -  bsize - the initial size of the block-stash(if used).

7261:    Options Database Keys:
7262: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
7263: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

7265:    Level: intermediate

7267:    Notes: 
7268:      The block-stash is used for values set with MatSetValuesBlocked() while
7269:      the stash is used for values set with MatSetValues()

7271:      Run with the option -info and look for output of the form
7272:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7273:      to determine the appropriate value, MM, to use for size and 
7274:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7275:      to determine the value, BMM to use for bsize

7277:    Concepts: stash^setting matrix size
7278:    Concepts: matrices^stash

7280: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()

7282: @*/
7283: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7284: {

7290:   MatStashSetInitialSize_Private(&mat->stash,size);
7291:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
7292:   return(0);
7293: }

7297: /*@
7298:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
7299:      the matrix

7301:    Neighbor-wise Collective on Mat

7303:    Input Parameters:
7304: +  mat   - the matrix
7305: .  x,y - the vectors
7306: -  w - where the result is stored

7308:    Level: intermediate

7310:    Notes: 
7311:     w may be the same vector as y. 

7313:     This allows one to use either the restriction or interpolation (its transpose)
7314:     matrix to do the interpolation

7316:     Concepts: interpolation

7318: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7320: @*/
7321: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7322: {
7324:   PetscInt       M,N,Ny;

7332:   MatCheckPreallocated(A,1);
7333:   MatGetSize(A,&M,&N);
7334:   VecGetSize(y,&Ny);
7335:   if (M == Ny) {
7336:     MatMultAdd(A,x,y,w);
7337:   } else {
7338:     MatMultTransposeAdd(A,x,y,w);
7339:   }
7340:   return(0);
7341: }

7345: /*@
7346:    MatInterpolate - y = A*x or A'*x depending on the shape of 
7347:      the matrix

7349:    Neighbor-wise Collective on Mat

7351:    Input Parameters:
7352: +  mat   - the matrix
7353: -  x,y - the vectors

7355:    Level: intermediate

7357:    Notes: 
7358:     This allows one to use either the restriction or interpolation (its transpose)
7359:     matrix to do the interpolation

7361:    Concepts: matrices^interpolation

7363: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()

7365: @*/
7366: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
7367: {
7369:   PetscInt       M,N,Ny;

7376:   MatCheckPreallocated(A,1);
7377:   MatGetSize(A,&M,&N);
7378:   VecGetSize(y,&Ny);
7379:   if (M == Ny) {
7380:     MatMult(A,x,y);
7381:   } else {
7382:     MatMultTranspose(A,x,y);
7383:   }
7384:   return(0);
7385: }

7389: /*@
7390:    MatRestrict - y = A*x or A'*x

7392:    Neighbor-wise Collective on Mat

7394:    Input Parameters:
7395: +  mat   - the matrix
7396: -  x,y - the vectors

7398:    Level: intermediate

7400:    Notes: 
7401:     This allows one to use either the restriction or interpolation (its transpose)
7402:     matrix to do the restriction

7404:    Concepts: matrices^restriction

7406: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()

7408: @*/
7409: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
7410: {
7412:   PetscInt       M,N,Ny;

7419:   MatCheckPreallocated(A,1);

7421:   MatGetSize(A,&M,&N);
7422:   VecGetSize(y,&Ny);
7423:   if (M == Ny) {
7424:     MatMult(A,x,y);
7425:   } else {
7426:     MatMultTranspose(A,x,y);
7427:   }
7428:   return(0);
7429: }

7433: /*@
7434:    MatGetNullSpace - retrieves the null space to a matrix.

7436:    Logically Collective on Mat and MatNullSpace

7438:    Input Parameters:
7439: +  mat - the matrix
7440: -  nullsp - the null space object

7442:    Level: developer

7444:    Notes:
7445:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7447:    Concepts: null space^attaching to matrix

7449: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7450: @*/
7451: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7452: {
7457:   *nullsp = mat->nullsp;
7458:   return(0);
7459: }

7463: /*@
7464:    MatSetNullSpace - attaches a null space to a matrix.
7465:         This null space will be removed from the resulting vector whenever
7466:         MatMult() is called

7468:    Logically Collective on Mat and MatNullSpace

7470:    Input Parameters:
7471: +  mat - the matrix
7472: -  nullsp - the null space object

7474:    Level: advanced

7476:    Notes:
7477:       This null space is used by solvers. Overwrites any previous null space that may have been attached

7479:    Concepts: null space^attaching to matrix

7481: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7482: @*/
7483: PetscErrorCode  MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7484: {

7491:   MatCheckPreallocated(mat,1);
7492:   PetscObjectReference((PetscObject)nullsp);
7493:   MatNullSpaceDestroy(&mat->nullsp);
7494:   mat->nullsp = nullsp;
7495:   return(0);
7496: }

7500: /*@
7501:    MatSetNearNullSpace - attaches a null space to a matrix.
7502:         This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.

7504:    Logically Collective on Mat and MatNullSpace

7506:    Input Parameters:
7507: +  mat - the matrix
7508: -  nullsp - the null space object

7510:    Level: advanced

7512:    Notes:
7513:       Overwrites any previous near null space that may have been attached

7515:    Concepts: null space^attaching to matrix

7517: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7518: @*/
7519: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7520: {

7527:   MatCheckPreallocated(mat,1);
7528:   PetscObjectReference((PetscObject)nullsp);
7529:   MatNullSpaceDestroy(&mat->nearnullsp);
7530:   mat->nearnullsp = nullsp;
7531:   return(0);
7532: }

7536: /*@
7537:    MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()

7539:    Not Collective

7541:    Input Parameters:
7542: .  mat - the matrix

7544:    Output Parameters:
7545: .  nullsp - the null space object, PETSC_NULL if not set

7547:    Level: developer

7549:    Concepts: null space^attaching to matrix

7551: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7552: @*/
7553: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7554: {

7560:   MatCheckPreallocated(mat,1);
7561:   *nullsp = mat->nearnullsp;
7562:   return(0);
7563: }

7567: /*@C
7568:    MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.

7570:    Collective on Mat

7572:    Input Parameters:
7573: +  mat - the matrix
7574: .  row - row/column permutation
7575: .  fill - expected fill factor >= 1.0
7576: -  level - level of fill, for ICC(k)

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

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

7586:    Level: developer

7588:    Concepts: matrices^incomplete Cholesky factorization
7589:    Concepts: Cholesky factorization

7591: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()

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

7596: @*/
7597: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
7598: {

7606:   if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square");
7607:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7608:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7609:   if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7610:   MatCheckPreallocated(mat,1);
7611:   (*mat->ops->iccfactor)(mat,row,info);
7612:   PetscObjectStateIncrease((PetscObject)mat);
7613:   return(0);
7614: }

7618: /*@ 
7619:    MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix.

7621:    Not Collective

7623:    Input Parameters:
7624: +  mat - the matrix
7625: -  v - the values compute with ADIC

7627:    Level: developer

7629:    Notes:
7630:      Must call MatSetColoring() before using this routine. Also this matrix must already
7631:      have its nonzero pattern determined.

7633: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7634:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
7635: @*/
7636: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
7637: {


7645:   if (!mat->assembled) {
7646:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7647:   }
7648:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7649:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7650:   (*mat->ops->setvaluesadic)(mat,v);
7651:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7652:   MatView_Private(mat);
7653:   PetscObjectStateIncrease((PetscObject)mat);
7654:   return(0);
7655: }


7660: /*@ 
7661:    MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic()

7663:    Not Collective

7665:    Input Parameters:
7666: +  mat - the matrix
7667: -  coloring - the coloring

7669:    Level: developer

7671: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7672:           MatSetValues(), MatSetValuesAdic()
7673: @*/
7674: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
7675: {


7683:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7684:   if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7685:   (*mat->ops->setcoloring)(mat,coloring);
7686:   return(0);
7687: }

7691: /*@ 
7692:    MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.

7694:    Not Collective

7696:    Input Parameters:
7697: +  mat - the matrix
7698: .  nl - leading dimension of v
7699: -  v - the values compute with ADIFOR

7701:    Level: developer

7703:    Notes:
7704:      Must call MatSetColoring() before using this routine. Also this matrix must already
7705:      have its nonzero pattern determined.

7707: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7708:           MatSetValues(), MatSetColoring()
7709: @*/
7710: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7711: {


7719:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7720:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7721:   if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7722:   (*mat->ops->setvaluesadifor)(mat,nl,v);
7723:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7724:   PetscObjectStateIncrease((PetscObject)mat);
7725:   return(0);
7726: }

7730: /*@ 
7731:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
7732:          ghosted ones.

7734:    Not Collective

7736:    Input Parameters:
7737: +  mat - the matrix
7738: -  diag = the diagonal values, including ghost ones

7740:    Level: developer

7742:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
7743:       
7744: .seealso: MatDiagonalScale()
7745: @*/
7746: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
7747: {
7749:   PetscMPIInt    size;


7756:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7757:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7758:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
7759:   if (size == 1) {
7760:     PetscInt n,m;
7761:     VecGetSize(diag,&n);
7762:     MatGetSize(mat,0,&m);
7763:     if (m == n) {
7764:       MatDiagonalScale(mat,0,diag);
7765:     } else {
7766:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7767:     }
7768:   } else {
7769:     PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7770:   }
7771:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7772:   PetscObjectStateIncrease((PetscObject)mat);
7773:   return(0);
7774: }

7778: /*@ 
7779:    MatGetInertia - Gets the inertia from a factored matrix

7781:    Collective on Mat

7783:    Input Parameter:
7784: .  mat - the matrix

7786:    Output Parameters:
7787: +   nneg - number of negative eigenvalues
7788: .   nzero - number of zero eigenvalues
7789: -   npos - number of positive eigenvalues

7791:    Level: advanced

7793:    Notes: Matrix must have been factored by MatCholeskyFactor()


7796: @*/
7797: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7798: {

7804:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7805:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7806:   if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7807:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7808:   return(0);
7809: }

7811: /* ----------------------------------------------------------------*/
7814: /*@C
7815:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

7817:    Neighbor-wise Collective on Mat and Vecs

7819:    Input Parameters:
7820: +  mat - the factored matrix
7821: -  b - the right-hand-side vectors

7823:    Output Parameter:
7824: .  x - the result vectors

7826:    Notes:
7827:    The vectors b and x cannot be the same.  I.e., one cannot
7828:    call MatSolves(A,x,x).

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

7835:    Level: developer

7837:    Concepts: matrices^triangular solves

7839: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7840: @*/
7841: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
7842: {

7848:   if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7849:   if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7850:   if (!mat->rmap->N && !mat->cmap->N) return(0);

7852:   if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7853:   MatCheckPreallocated(mat,1);
7854:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7855:   (*mat->ops->solves)(mat,b,x);
7856:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7857:   return(0);
7858: }

7862: /*@
7863:    MatIsSymmetric - Test whether a matrix is symmetric

7865:    Collective on Mat

7867:    Input Parameter:
7868: +  A - the matrix to test
7869: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)

7871:    Output Parameters:
7872: .  flg - the result

7874:    Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results

7876:    Level: intermediate

7878:    Concepts: matrix^symmetry

7880: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7881: @*/
7882: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscBool  *flg)
7883: {


7890:   if (!A->symmetric_set) {
7891:     if (!A->ops->issymmetric) {
7892:       const MatType mattype;
7893:       MatGetType(A,&mattype);
7894:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7895:     }
7896:     (*A->ops->issymmetric)(A,tol,flg);
7897:     if (!tol) {
7898:       A->symmetric_set = PETSC_TRUE;
7899:       A->symmetric = *flg;
7900:       if (A->symmetric) {
7901:         A->structurally_symmetric_set = PETSC_TRUE;
7902:         A->structurally_symmetric     = PETSC_TRUE;
7903:       }
7904:     }
7905:   } else if (A->symmetric) {
7906:     *flg = PETSC_TRUE;
7907:   } else if (!tol) {
7908:     *flg = PETSC_FALSE;
7909:   } else {
7910:     if (!A->ops->issymmetric) {
7911:       const MatType mattype;
7912:       MatGetType(A,&mattype);
7913:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7914:     }
7915:     (*A->ops->issymmetric)(A,tol,flg);
7916:   }
7917:   return(0);
7918: }

7922: /*@
7923:    MatIsHermitian - Test whether a matrix is Hermitian

7925:    Collective on Mat

7927:    Input Parameter:
7928: +  A - the matrix to test
7929: -  tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)

7931:    Output Parameters:
7932: .  flg - the result

7934:    Level: intermediate

7936:    Concepts: matrix^symmetry

7938: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7939:           MatIsSymmetricKnown(), MatIsSymmetric()
7940: @*/
7941: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscBool  *flg)
7942: {


7949:   if (!A->hermitian_set) {
7950:     if (!A->ops->ishermitian) {
7951:       const MatType mattype;
7952:       MatGetType(A,&mattype);
7953:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7954:     }
7955:     (*A->ops->ishermitian)(A,tol,flg);
7956:     if (!tol) {
7957:       A->hermitian_set = PETSC_TRUE;
7958:       A->hermitian = *flg;
7959:       if (A->hermitian) {
7960:         A->structurally_symmetric_set = PETSC_TRUE;
7961:         A->structurally_symmetric     = PETSC_TRUE;
7962:       }
7963:     }
7964:   } else if (A->hermitian) {
7965:     *flg = PETSC_TRUE;
7966:   } else if (!tol) {
7967:     *flg = PETSC_FALSE;
7968:   } else {
7969:     if (!A->ops->ishermitian) {
7970:       const MatType mattype;
7971:       MatGetType(A,&mattype);
7972:       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7973:     }
7974:     (*A->ops->ishermitian)(A,tol,flg);
7975:   }
7976:   return(0);
7977: }

7981: /*@
7982:    MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.

7984:    Not Collective

7986:    Input Parameter:
7987: .  A - the matrix to check

7989:    Output Parameters:
7990: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7991: -  flg - the result

7993:    Level: advanced

7995:    Concepts: matrix^symmetry

7997:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7998:          if you want it explicitly checked

8000: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8001: @*/
8002: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8003: {
8008:   if (A->symmetric_set) {
8009:     *set = PETSC_TRUE;
8010:     *flg = A->symmetric;
8011:   } else {
8012:     *set = PETSC_FALSE;
8013:   }
8014:   return(0);
8015: }

8019: /*@
8020:    MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.

8022:    Not Collective

8024:    Input Parameter:
8025: .  A - the matrix to check

8027:    Output Parameters:
8028: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
8029: -  flg - the result

8031:    Level: advanced

8033:    Concepts: matrix^symmetry

8035:    Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8036:          if you want it explicitly checked

8038: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8039: @*/
8040: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscBool  *set,PetscBool  *flg)
8041: {
8046:   if (A->hermitian_set) {
8047:     *set = PETSC_TRUE;
8048:     *flg = A->hermitian;
8049:   } else {
8050:     *set = PETSC_FALSE;
8051:   }
8052:   return(0);
8053: }

8057: /*@
8058:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

8060:    Collective on Mat

8062:    Input Parameter:
8063: .  A - the matrix to test

8065:    Output Parameters:
8066: .  flg - the result

8068:    Level: intermediate

8070:    Concepts: matrix^symmetry

8072: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8073: @*/
8074: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscBool  *flg)
8075: {

8081:   if (!A->structurally_symmetric_set) {
8082:     if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8083:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8084:     A->structurally_symmetric_set = PETSC_TRUE;
8085:   }
8086:   *flg = A->structurally_symmetric;
8087:   return(0);
8088: }

8092: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8093: /*@ 
8094:    MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8095:        to be communicated to other processors during the MatAssemblyBegin/End() process

8097:     Not collective

8099:    Input Parameter:
8100: .   vec - the vector

8102:    Output Parameters:
8103: +   nstash   - the size of the stash
8104: .   reallocs - the number of additional mallocs incurred.
8105: .   bnstash   - the size of the block stash
8106: -   breallocs - the number of additional mallocs incurred.in the block stash
8107:  
8108:    Level: advanced

8110: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8111:   
8112: @*/
8113: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8114: {
8117:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8118:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8119:   return(0);
8120: }

8124: /*@C
8125:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
8126:      parallel layout
8127:    
8128:    Collective on Mat

8130:    Input Parameter:
8131: .  mat - the matrix

8133:    Output Parameter:
8134: +   right - (optional) vector that the matrix can be multiplied against
8135: -   left - (optional) vector that the matrix vector product can be stored in

8137:   Level: advanced

8139: .seealso: MatCreate()
8140: @*/
8141: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
8142: {

8148:   MatCheckPreallocated(mat,1);
8149:   if (mat->ops->getvecs) {
8150:     (*mat->ops->getvecs)(mat,right,left);
8151:   } else {
8152:     PetscMPIInt size;
8153:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
8154:     if (right) {
8155:       VecCreate(((PetscObject)mat)->comm,right);
8156:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8157:       VecSetBlockSize(*right,mat->rmap->bs);
8158:       VecSetType(*right,VECSTANDARD);
8159:       PetscLayoutReference(mat->cmap,&(*right)->map);
8160:     }
8161:     if (left) {
8162:       VecCreate(((PetscObject)mat)->comm,left);
8163:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8164:       VecSetBlockSize(*left,mat->rmap->bs);
8165:       VecSetType(*left,VECSTANDARD);
8166:       PetscLayoutReference(mat->rmap,&(*left)->map);
8167:     }
8168:   }
8169:   return(0);
8170: }

8174: /*@C
8175:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8176:      with default values.

8178:    Not Collective

8180:    Input Parameters:
8181: .    info - the MatFactorInfo data structure


8184:    Notes: The solvers are generally used through the KSP and PC objects, for example
8185:           PCLU, PCILU, PCCHOLESKY, PCICC

8187:    Level: developer

8189: .seealso: MatFactorInfo

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

8194: @*/

8196: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
8197: {

8201:   PetscMemzero(info,sizeof(MatFactorInfo));
8202:   return(0);
8203: }

8207: /*@
8208:    MatPtAP - Creates the matrix product C = P^T * A * P

8210:    Neighbor-wise Collective on Mat

8212:    Input Parameters:
8213: +  A - the matrix
8214: .  P - the projection matrix
8215: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8216: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))

8218:    Output Parameters:
8219: .  C - the product matrix

8221:    Notes:
8222:    C will be created and must be destroyed by the user with MatDestroy().

8224:    This routine is currently only implemented for pairs of AIJ matrices and classes
8225:    which inherit from AIJ.  

8227:    Level: intermediate

8229: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8230: @*/
8231: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8232: {

8238:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8239:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8242:   MatCheckPreallocated(P,2);
8243:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8244:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8246:   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);
8247:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8248:   MatCheckPreallocated(A,1);

8250:   if (!A->ops->ptap) {
8251:     const MatType mattype;
8252:     MatGetType(A,&mattype);
8253:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
8254:   }
8255:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8256:   (*A->ops->ptap)(A,P,scall,fill,C);
8257:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8258:   return(0);
8259: }

8263: /*@
8264:    MatPtAPNumeric - Computes the matrix product C = P^T * A * P

8266:    Neighbor-wise Collective on Mat

8268:    Input Parameters:
8269: +  A - the matrix
8270: -  P - the projection matrix

8272:    Output Parameters:
8273: .  C - the product matrix

8275:    Notes:
8276:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
8277:    the user using MatDeatroy().

8279:    This routine is currently only implemented for pairs of AIJ matrices and classes
8280:    which inherit from AIJ.  C will be of type MATAIJ.

8282:    Level: intermediate

8284: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8285: @*/
8286: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
8287: {

8293:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8294:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8297:   MatCheckPreallocated(P,2);
8298:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8299:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8302:   MatCheckPreallocated(C,3);
8303:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8304:   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);
8305:   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);
8306:   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);
8307:   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);
8308:   MatCheckPreallocated(A,1);

8310:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8311:   (*A->ops->ptapnumeric)(A,P,C);
8312:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8313:   return(0);
8314: }

8318: /*@
8319:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P

8321:    Neighbor-wise Collective on Mat

8323:    Input Parameters:
8324: +  A - the matrix
8325: -  P - the projection matrix

8327:    Output Parameters:
8328: .  C - the (i,j) structure of the product matrix

8330:    Notes:
8331:    C will be created and must be destroyed by the user with MatDestroy().

8333:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8334:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8335:    this (i,j) structure by calling MatPtAPNumeric().

8337:    Level: intermediate

8339: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8340: @*/
8341: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8342: {

8348:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8349:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8350:   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8353:   MatCheckPreallocated(P,2);
8354:   if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8355:   if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8358:   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);
8359:   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);
8360:   MatCheckPreallocated(A,1);
8361:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8362:   (*A->ops->ptapsymbolic)(A,P,fill,C);
8363:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

8365:   /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */

8367:   return(0);
8368: }

8372: /*@
8373:    MatRARt - Creates the matrix product C = R * A * R^T

8375:    Neighbor-wise Collective on Mat

8377:    Input Parameters:
8378: +  A - the matrix
8379: .  R - the projection matrix
8380: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8381: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

8383:    Output Parameters:
8384: .  C - the product matrix

8386:    Notes:
8387:    C will be created and must be destroyed by the user with MatDestroy().

8389:    This routine is currently only implemented for pairs of AIJ matrices and classes
8390:    which inherit from AIJ.  

8392:    Level: intermediate

8394: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8395: @*/
8396: PetscErrorCode  MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8397: {

8403:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8404:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8407:   MatCheckPreallocated(R,2);
8408:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8409:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8411:   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);
8412:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8413:   MatCheckPreallocated(A,1);

8415:   if (!A->ops->rart) {
8416:     const MatType mattype;
8417:     MatGetType(A,&mattype);
8418:     SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8419:   }
8420:   PetscLogEventBegin(MAT_RARt,A,R,0,0);
8421:   (*A->ops->rart)(A,R,scall,fill,C);
8422:   PetscLogEventEnd(MAT_RARt,A,R,0,0);
8423:   return(0);
8424: }

8428: /*@
8429:    MatRARtNumeric - Computes the matrix product C = R * A * R^T

8431:    Neighbor-wise Collective on Mat

8433:    Input Parameters:
8434: +  A - the matrix
8435: -  R - the projection matrix

8437:    Output Parameters:
8438: .  C - the product matrix

8440:    Notes:
8441:    C must have been created by calling MatRARtSymbolic and must be destroyed by
8442:    the user using MatDeatroy().

8444:    This routine is currently only implemented for pairs of AIJ matrices and classes
8445:    which inherit from AIJ.  C will be of type MATAIJ.

8447:    Level: intermediate

8449: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8450: @*/
8451: PetscErrorCode  MatRARtNumeric(Mat A,Mat R,Mat C)
8452: {

8458:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8459:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8462:   MatCheckPreallocated(R,2);
8463:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8464:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8467:   MatCheckPreallocated(C,3);
8468:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8469:   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);
8470:   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);
8471:   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);
8472:   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);
8473:   MatCheckPreallocated(A,1);

8475:   PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8476:   (*A->ops->rartnumeric)(A,R,C);
8477:   PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8478:   return(0);
8479: }

8483: /*@
8484:    MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T

8486:    Neighbor-wise Collective on Mat

8488:    Input Parameters:
8489: +  A - the matrix
8490: -  R - the projection matrix

8492:    Output Parameters:
8493: .  C - the (i,j) structure of the product matrix

8495:    Notes:
8496:    C will be created and must be destroyed by the user with MatDestroy().

8498:    This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8499:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.  The product is computed using
8500:    this (i,j) structure by calling MatRARtNumeric().

8502:    Level: intermediate

8504: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8505: @*/
8506: PetscErrorCode  MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8507: {

8513:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8514:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8515:   if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8518:   MatCheckPreallocated(R,2);
8519:   if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8520:   if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8523:   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);
8524:   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);
8525:   MatCheckPreallocated(A,1);
8526:   PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8527:   (*A->ops->rartsymbolic)(A,R,fill,C);
8528:   PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);

8530:   MatSetBlockSize(*C,A->rmap->bs);
8531:   return(0);
8532: }

8534: extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...);

8538: /*@
8539:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

8541:    Neighbor-wise Collective on Mat

8543:    Input Parameters:
8544: +  A - the left matrix
8545: .  B - the right matrix
8546: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8547: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8548:           if the result is a dense matrix this is irrelevent

8550:    Output Parameters:
8551: .  C - the product matrix

8553:    Notes:
8554:    Unless scall is MAT_REUSE_MATRIX C will be created.

8556:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8557:    
8558:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8559:    actually needed.

8561:    If you have many matrices with the same non-zero structure to multiply, you 
8562:    should either 
8563: $   1) use MAT_REUSE_MATRIX in all calls but the first or
8564: $   2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed

8566:    Level: intermediate

8568: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(),  MatMatTransposeMult(), MatPtAP()
8569: @*/
8570: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8571: {
8573:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8574:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8575:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

8580:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8581:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8584:   MatCheckPreallocated(B,2);
8585:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8586:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8588:   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);
8589:   if (scall == MAT_REUSE_MATRIX){
8592:     PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8593:     (*(*C)->ops->matmult)(A,B,scall,fill,C);
8594:     PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8595:   }
8596:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8597:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8598:   MatCheckPreallocated(A,1);

8600:   fA = A->ops->matmult;
8601:   fB = B->ops->matmult;
8602:   if (fB == fA) {
8603:     if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8604:     mult = fB;
8605:   } else {
8606:     /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */
8607:     char  multname[256];
8608:     PetscStrcpy(multname,"MatMatMult_");
8609:     PetscStrcat(multname,((PetscObject)A)->type_name);
8610:     PetscStrcat(multname,"_");
8611:     PetscStrcat(multname,((PetscObject)B)->type_name);
8612:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8613:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
8614:     if(!mult){
8615:       /* dual dispatch using MatQueryOp */
8616:       MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8617:       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);
8618:     }
8619:   }
8620:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8621:   (*mult)(A,B,scall,fill,C);
8622:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8623:   return(0);
8624: }

8628: /*@
8629:    MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8630:    of the matrix-matrix product C=A*B.  Call this routine before calling MatMatMultNumeric().

8632:    Neighbor-wise Collective on Mat

8634:    Input Parameters:
8635: +  A - the left matrix
8636: .  B - the right matrix
8637: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8638:       if C is a dense matrix this is irrelevent
8639:  
8640:    Output Parameters:
8641: .  C - the product matrix

8643:    Notes:
8644:    Unless scall is MAT_REUSE_MATRIX C will be created.

8646:    To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8647:    actually needed.

8649:    This routine is currently implemented for 
8650:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8651:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8652:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8654:    Level: intermediate

8656:    Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8657:      We should incorporate them into PETSc.

8659: .seealso: MatMatMult(), MatMatMultNumeric()
8660: @*/
8661: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8662: {
8664:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
8665:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
8666:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

8671:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8672:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8676:   MatCheckPreallocated(B,2);
8677:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8678:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8681:   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);
8682:   if (fill == PETSC_DEFAULT) fill = 2.0;
8683:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8684:   MatCheckPreallocated(A,1);
8685: 
8686:   Asymbolic = A->ops->matmultsymbolic;
8687:   Bsymbolic = B->ops->matmultsymbolic;
8688:   if (Asymbolic == Bsymbolic){
8689:     if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8690:     symbolic = Bsymbolic;
8691:   } else { /* dispatch based on the type of A and B */
8692:     char  symbolicname[256];
8693:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8694:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8695:     PetscStrcat(symbolicname,"_");
8696:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8697:     PetscStrcat(symbolicname,"_C");
8698:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
8699:     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);
8700:   }
8701:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8702:   (*symbolic)(A,B,fill,C);
8703:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8704:   return(0);
8705: }

8709: /*@
8710:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
8711:    Call this routine after first calling MatMatMultSymbolic().

8713:    Neighbor-wise Collective on Mat

8715:    Input Parameters:
8716: +  A - the left matrix
8717: -  B - the right matrix

8719:    Output Parameters:
8720: .  C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().

8722:    Notes:
8723:    C must have been created with MatMatMultSymbolic().

8725:    This routine is currently implemented for 
8726:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8727:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8728:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

8730:    Level: intermediate

8732: .seealso: MatMatMult(), MatMatMultSymbolic()
8733: @*/
8734: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
8735: {
8737:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
8738:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
8739:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

8744:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8745:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8749:   MatCheckPreallocated(B,2);
8750:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8751:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8755:   MatCheckPreallocated(C,3);
8756:   if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8757:   if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

8759:   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);
8760:   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);
8761:   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);
8762:   MatCheckPreallocated(A,1);

8764:   Anumeric = A->ops->matmultnumeric;
8765:   Bnumeric = B->ops->matmultnumeric;
8766:   if (Anumeric == Bnumeric){
8767:     if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
8768:     numeric = Bnumeric;
8769:   } else {
8770:     char  numericname[256];
8771:     PetscStrcpy(numericname,"MatMatMultNumeric_");
8772:     PetscStrcat(numericname,((PetscObject)A)->type_name);
8773:     PetscStrcat(numericname,"_");
8774:     PetscStrcat(numericname,((PetscObject)B)->type_name);
8775:     PetscStrcat(numericname,"_C");
8776:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
8777:     if (!numeric)
8778:       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);
8779:   }
8780:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8781:   (*numeric)(A,B,C);
8782:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8783:   return(0);
8784: }

8788: /*@
8789:    MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.

8791:    Neighbor-wise Collective on Mat

8793:    Input Parameters:
8794: +  A - the left matrix
8795: .  B - the right matrix
8796: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8797: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8799:    Output Parameters:
8800: .  C - the product matrix

8802:    Notes:
8803:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8805:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8807:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8808:    actually needed.

8810:    This routine is currently only implemented for pairs of SeqAIJ matrices.  C will be of type MATSEQAIJ.

8812:    Level: intermediate

8814: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8815: @*/
8816: PetscErrorCode  MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8817: {
8819:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8820:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

8825:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8826:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8829:   MatCheckPreallocated(B,2);
8830:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8831:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8833:   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);
8834:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8835:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8836:   MatCheckPreallocated(A,1);

8838:   fA = A->ops->mattransposemult;
8839:   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8840:   fB = B->ops->mattransposemult;
8841:   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8842:   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);

8844:   if (scall == MAT_INITIAL_MATRIX){
8845:     PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8846:     (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8847:     PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8848:   }
8849:   PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8850:   (*A->ops->mattransposemultnumeric)(A,B,*C);
8851:   PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8852:   return(0);
8853: }

8857: /*@
8858:    MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.

8860:    Neighbor-wise Collective on Mat

8862:    Input Parameters:
8863: +  A - the left matrix
8864: .  B - the right matrix
8865: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8866: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

8868:    Output Parameters:
8869: .  C - the product matrix

8871:    Notes:
8872:    C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().

8874:    MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call

8876:   To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8877:    actually needed.

8879:    This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes
8880:    which inherit from SeqAIJ.  C will be of type MATSEQAIJ.

8882:    Level: intermediate

8884: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8885: @*/
8886: PetscErrorCode  MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8887: {
8889:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8890:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8891:   PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*);

8896:   if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8897:   if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8900:   MatCheckPreallocated(B,2);
8901:   if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8902:   if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8904:   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);
8905:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8906:   if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8907:   MatCheckPreallocated(A,1);

8909:   fA = A->ops->transposematmult;
8910:   if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8911:   fB = B->ops->transposematmult;
8912:   if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8913:   if (fB==fA) {
8914:     transposematmult = fA;
8915:   }
8916:   else {
8917:     /* dual dispatch using MatQueryOp */
8918:     MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name);
8919:     if(!transposematmult)
8920:       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);
8921:   }
8922:   PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8923:   (*transposematmult)(A,B,scall,fill,C);
8924:   PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8925:   return(0);
8926: }

8930: /*@C
8931:    MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 

8933:    Collective on Mat

8935:    Input Parameters:
8936: +  mat - the matrix
8937: .  nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
8938: .  subcomm - MPI communicator split from the communicator where mat resides in
8939: .  mlocal_red - number of local rows of the redundant matrix
8940: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

8942:    Output Parameter:
8943: .  matredundant - redundant matrix

8945:    Notes:
8946:    MAT_REUSE_MATRIX can only be used when the nonzero structure of the 
8947:    original matrix has not changed from that last call to MatGetRedundantMatrix().

8949:    This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
8950:    calling it. 

8952:    Only MPIAIJ matrix is supported. 
8953:    
8954:    Level: advanced

8956:    Concepts: subcommunicator
8957:    Concepts: duplicate matrix

8959: .seealso: MatDestroy()
8960: @*/
8961: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
8962: {

8967:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
8970:   }
8971:   if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8972:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8973:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8974:   MatCheckPreallocated(mat,1);

8976:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
8977:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
8978:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
8979:   return(0);
8980: }

8984: /*@C
8985:    MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
8986:    a given 'mat' object. Each submatrix can span multiple procs.

8988:    Collective on Mat

8990:    Input Parameters:
8991: +  mat - the matrix
8992: .  subcomm - the subcommunicator obtained by com_split(comm)
8993: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

8995:    Output Parameter:
8996: .  subMat - 'parallel submatrices each spans a given subcomm

8998:   Notes:
8999:   The submatrix partition across processors is dicated by 'subComm' a
9000:   communicator obtained by com_split(comm). The comm_split
9001:   is not restriced to be grouped with consequitive original ranks.

9003:   Due the comm_split() usage, the parallel layout of the submatrices
9004:   map directly to the layout of the original matrix [wrt the local
9005:   row,col partitioning]. So the original 'DiagonalMat' naturally maps
9006:   into the 'DiagonalMat' of the subMat, hence it is used directly from
9007:   the subMat. However the offDiagMat looses some columns - and this is
9008:   reconstructed with MatSetValues()

9010:   Level: advanced

9012:   Concepts: subcommunicator
9013:   Concepts: submatrices

9015: .seealso: MatGetSubMatrices()
9016: @*/
9017: PetscErrorCode   MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat)
9018: {
9020:   PetscMPIInt    commsize,subCommSize;

9023:   MPI_Comm_size(((PetscObject)mat)->comm,&commsize);
9024:   MPI_Comm_size(subComm,&subCommSize);
9025:   if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9026: 
9027:   PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9028:   (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9029:   PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9030:   return(0);
9031: }

9035: /*@
9036:    MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering

9038:    Not Collective

9040:    Input Arguments:
9041:    mat - matrix to extract local submatrix from
9042:    isrow - local row indices for submatrix
9043:    iscol - local column indices for submatrix

9045:    Output Arguments:
9046:    submat - the submatrix

9048:    Level: intermediate

9050:    Notes:
9051:    The submat should be returned with MatRestoreLocalSubMatrix().

9053:    Depending on the format of mat, the returned submat may not implement MatMult().  Its communicator may be
9054:    the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.

9056:    The submat always implements MatSetValuesLocal().  If isrow and iscol have the same block size, then
9057:    MatSetValuesBlockedLocal() will also be implemented.

9059: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9060: @*/
9061: PetscErrorCode  MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9062: {


9072:   if (mat->ops->getlocalsubmatrix) {
9073:     (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9074:   } else {
9075:     MatCreateLocalRef(mat,isrow,iscol,submat);
9076:   }
9077:   return(0);
9078: }

9082: /*@
9083:    MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering

9085:    Not Collective

9087:    Input Arguments:
9088:    mat - matrix to extract local submatrix from
9089:    isrow - local row indices for submatrix
9090:    iscol - local column indices for submatrix
9091:    submat - the submatrix

9093:    Level: intermediate

9095: .seealso: MatGetLocalSubMatrix()
9096: @*/
9097: PetscErrorCode  MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9098: {


9109:   if (mat->ops->restorelocalsubmatrix) {
9110:     (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9111:   } else {
9112:     MatDestroy(submat);
9113:   }
9114:   *submat = PETSC_NULL;
9115:   return(0);
9116: }

9118: /* --------------------------------------------------------*/
9121: /*@
9122:    MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix

9124:    Collective on Mat

9126:    Input Parameter:
9127: .  mat - the matrix

9129:    Output Parameter:
9130: .  is - if any rows have zero diagonals this contains the list of them

9132:    Level: developer

9134:    Concepts: matrix-vector product

9136: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9137: @*/
9138: PetscErrorCode  MatFindZeroDiagonals(Mat mat,IS *is)
9139: {

9145:   if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9146:   if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

9148:   if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9149:   (*mat->ops->findzerodiagonals)(mat,is);
9150:   return(0);
9151: }

9155: /*@C
9156:   MatInvertBlockDiagonal - Inverts the block diagonal entries.

9158:   Collective on Mat

9160:   Input Parameters:
9161: . mat - the matrix

9163:   Output Parameters:
9164: . values - the block inverses in column major order (FORTRAN-like)

9166:    Note:
9167:    This routine is not available from Fortran.

9169:   Level: advanced
9170: @*/
9171: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9172: {

9177:   if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9178:   if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9179:   if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9180:   (*mat->ops->invertblockdiagonal)(mat,values);
9181:   return(0);
9182: }

9186: /*@C
9187:     MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9188:     via MatTransposeColoringCreate().

9190:     Collective on MatTransposeColoring

9192:     Input Parameter:
9193: .   c - coloring context

9195:     Level: intermediate

9197: .seealso: MatTransposeColoringCreate()
9198: @*/
9199: PetscErrorCode  MatTransposeColoringDestroy(MatTransposeColoring *c)
9200: {
9201:   PetscErrorCode       ierr;
9202:   MatTransposeColoring matcolor=*c;

9205:   if (!matcolor) return(0);
9206:   if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}

9208:   PetscFree(matcolor->ncolumns);
9209:   PetscFree(matcolor->nrows);
9210:   PetscFree(matcolor->colorforrow);
9211:   PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9212:   PetscFree(matcolor->colorforcol);
9213:   PetscFree(matcolor->columns);
9214:   PetscHeaderDestroy(c);
9215:   return(0);
9216: }

9220: /*@C
9221:     MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 
9222:     a MatTransposeColoring context has been created, computes a dense B^T by Apply 
9223:     MatTransposeColoring to sparse B.

9225:     Collective on MatTransposeColoring

9227:     Input Parameters:
9228: +   B - sparse matrix B
9229: .   Btdense - symbolic dense matrix B^T
9230: -   coloring - coloring context created with MatTransposeColoringCreate()

9232:     Output Parameter:
9233: .   Btdense - dense matrix B^T 

9235:     Options Database Keys:
9236: +    -mat_transpose_coloring_view - Activates basic viewing or coloring
9237: .    -mat_transpose_coloring_view_draw - Activates drawing of coloring
9238: -    -mat_transpose_coloring_view_info - Activates viewing of coloring info

9240:     Level: intermediate

9242: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()

9244: .keywords: coloring
9245: @*/
9246: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9247: {

9254: 
9255:   if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9256:   (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9257:   return(0);
9258: }

9262: /*@C
9263:     MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 
9264:     a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9265:     in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 
9266:     Csp from Cden.

9268:     Collective on MatTransposeColoring

9270:     Input Parameters:
9271: +   coloring - coloring context created with MatTransposeColoringCreate()
9272: -   Cden - matrix product of a sparse matrix and a dense matrix Btdense

9274:     Output Parameter:
9275: .   Csp - sparse matrix  

9277:     Options Database Keys:
9278: +    -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9279: .    -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9280: -    -mat_multtranspose_coloring_view_info - Activates viewing of coloring info

9282:     Level: intermediate

9284: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()

9286: .keywords: coloring
9287: @*/
9288: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9289: {

9296: 
9297:   if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9298:   (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9299:   return(0);
9300: }

9304: /*@C
9305:    MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.

9307:    Collective on Mat

9309:    Input Parameters:
9310: +  mat - the matrix product C
9311: -  iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()

9313:     Output Parameter:
9314: .   color - the new coloring context
9315:    
9316:     Level: intermediate

9318: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9319:            MatTransColoringApplyDen()ToSp, MatTransposeColoringView(), 
9320: @*/
9321: PetscErrorCode  MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9322: {
9323:   MatTransposeColoring  c;
9324:   MPI_Comm              comm;
9325:   PetscErrorCode        ierr;

9328:   PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9329:   PetscObjectGetComm((PetscObject)mat,&comm);
9330:   PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,0,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);

9332:   c->ctype = iscoloring->ctype;
9333:   if (mat->ops->transposecoloringcreate) {
9334:     (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9335:   } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type");

9337:   *color = c;
9338:   PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9339:   return(0);
9340: }