Actual source code: matrix.c

  1: #define PETSCMAT_DLL

  3: /*
  4:    This is where the abstract matrix operations are defined
  5: */

 7:  #include private/matimpl.h
 8:  #include private/vecimpl.h

 10: /* Logging support */
 11: PetscCookie  MAT_COOKIE;
 12: PetscCookie  MAT_FDCOLORING_COOKIE;

 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_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
 21: PetscLogEvent  MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
 22: PetscLogEvent  MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
 23: PetscLogEvent  MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric;
 24: PetscLogEvent  MAT_MatMultTranspose, MAT_MatMultTransposeSymbolic, MAT_MatMultTransposeNumeric;
 25: PetscLogEvent  MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
 26: PetscLogEvent  MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
 27: PetscLogEvent  MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
 28: PetscLogEvent  MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;

 30: /* nasty global values for MatSetValue() */
 31: PetscInt     MatSetValue_Row = 0;
 32: PetscInt     MatSetValue_Column = 0;
 33: PetscScalar  MatSetValue_Value = 0.0;

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

 40:    Not Collective

 42:    Input Parameters:
 43: +  mat - the matrix
 44: -  reuse - indicates you are passing in the a matrix and want it reused

 46:    Output Parameters:
 47: +   iscopy - indicates a copy of the diagonal matrix was created and you should use MatDestroy() on it
 48: -   a - the diagonal part (which is a SEQUENTIAL matrix)

 50:    Notes: see the manual page for MatCreateMPIAIJ() for more information on the "diagonal part" of the matrix

 52:    Level: advanced

 54: @*/
 55: PetscErrorCode  MatGetDiagonalBlock(Mat A,PetscTruth *iscopy,MatReuse reuse,Mat *a)
 56: {
 57:   PetscErrorCode ierr,(*f)(Mat,PetscTruth*,MatReuse,Mat*);
 58:   PetscMPIInt    size;

 65:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
 66:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
 67:   MPI_Comm_size(((PetscObject)A)->comm,&size);
 68:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);
 69:   if (f) {
 70:     (*f)(A,iscopy,reuse,a);
 71:   } else if (size == 1) {
 72:     *a = A;
 73:     *iscopy = PETSC_FALSE;
 74:   } else {
 75:     SETERRQ(PETSC_ERR_SUP,"Cannot get diagonal part for this matrix");
 76:   }
 77:   return(0);
 78: }

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

 85:    Collective on Mat

 87:    Input Parameters:
 88: .  mat - the matrix

 90:    Output Parameter:
 91: .   trace - the sum of the diagonal entries

 93:    Level: advanced

 95: @*/
 96: PetscErrorCode  MatGetTrace(Mat mat,PetscScalar *trace)
 97: {
 99:    Vec            diag;

102:    MatGetVecs(mat,&diag,PETSC_NULL);
103:    MatGetDiagonal(mat,diag);
104:    VecSum(diag,trace);
105:    VecDestroy(diag);
106:    return(0);
107: }

111: /*@
112:    MatRealPart - Zeros out the imaginary part of the matrix

114:    Collective on Mat

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

119:    Level: advanced


122: .seealso: MatImaginaryPart()
123: @*/
124: PetscErrorCode  MatRealPart(Mat mat)
125: {

131:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
132:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
133:   if (!mat->ops->realpart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
134:   MatPreallocated(mat);
135:   (*mat->ops->realpart)(mat);
136:   return(0);
137: }

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

144:    Collective on Mat

146:    Input Parameter:
147: .  mat - the matrix

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

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

155:    Level: advanced

157: @*/
158: PetscErrorCode  MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
159: {

165:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
166:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
167:   if (!mat->ops->getghosts) {
168:     if (nghosts) *nghosts = 0;
169:     if (ghosts) *ghosts = 0;
170:   } else {
171:     (*mat->ops->getghosts)(mat,nghosts,ghosts);
172:   }
173:   return(0);
174: }


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

182:    Collective on Mat

184:    Input Parameters:
185: .  mat - the matrix

187:    Level: advanced


190: .seealso: MatRealPart()
191: @*/
192: PetscErrorCode  MatImaginaryPart(Mat mat)
193: {

199:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
200:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
201:   if (!mat->ops->imaginarypart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
202:   MatPreallocated(mat);
203:   (*mat->ops->imaginarypart)(mat);
204:   return(0);
205: }

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

212:    Collective on Mat

214:    Input Parameter:
215: .  mat - the matrix

217:    Output Parameters:
218: +  missing - is any diagonal missing
219: -  dd - first diagonal entry that is missing (optional)

221:    Level: advanced


224: .seealso: MatRealPart()
225: @*/
226: PetscErrorCode  MatMissingDiagonal(Mat mat,PetscTruth *missing,PetscInt *dd)
227: {

233:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
234:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
235:   if (!mat->ops->missingdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
236:   (*mat->ops->missingdiagonal)(mat,missing,dd);
237:   return(0);
238: }

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

247:    Not Collective

249:    Input Parameters:
250: +  mat - the matrix
251: -  row - the row to get

253:    Output Parameters:
254: +  ncols -  if not NULL, the number of nonzeros in the row
255: .  cols - if not NULL, the column numbers
256: -  vals - if not NULL, the values

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

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

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

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

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

280:    Fortran Notes:
281:    The calling sequence from Fortran is 
282: .vb
283:    MatGetRow(matrix,row,ncols,cols,values,ierr)
284:          Mat     matrix (input)
285:          integer row    (input)
286:          integer ncols  (output)
287:          integer cols(maxcols) (output)
288:          double precision (or double complex) values(maxcols) output
289: .ve
290:    where maxcols >= maximum nonzeros in any row of the matrix.


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

297:    Level: advanced

299:    Concepts: matrices^row access

301: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
302: @*/
303: PetscErrorCode  MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
304: {
306:   PetscInt       incols;

311:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
312:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
313:   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
314:   MatPreallocated(mat);
315:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
316:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
317:   if (ncols) *ncols = incols;
318:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
319:   return(0);
320: }

324: /*@
325:    MatConjugate - replaces the matrix values with their complex conjugates

327:    Collective on Mat

329:    Input Parameters:
330: .  mat - the matrix

332:    Level: advanced

334: .seealso:  VecConjugate()
335: @*/
336: PetscErrorCode  MatConjugate(Mat mat)
337: {

342:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
343:   if (!mat->ops->conjugate) SETERRQ(PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
344:   (*mat->ops->conjugate)(mat);
345:   return(0);
346: }

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

353:    Not Collective

355:    Input Parameters:
356: +  mat - the matrix
357: .  row - the row to get
358: .  ncols, cols - the number of nonzeros and their columns
359: -  vals - if nonzero the column values

361:    Notes: 
362:    This routine should be called after you have finished examining the entries.

364:    Fortran Notes:
365:    The calling sequence from Fortran is 
366: .vb
367:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
368:       Mat     matrix (input)
369:       integer row    (input)
370:       integer ncols  (output)
371:       integer cols(maxcols) (output)
372:       double precision (or double complex) values(maxcols) output
373: .ve
374:    Where maxcols >= maximum nonzeros in any row of the matrix. 

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

379:    Level: advanced

381: .seealso:  MatGetRow()
382: @*/
383: PetscErrorCode  MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
384: {

390:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
391:   if (!mat->ops->restorerow) return(0);
392:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
393:   return(0);
394: }

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

402:    Not Collective

404:    Input Parameters:
405: +  mat - the matrix

407:    Notes:
408:    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.

410:    Level: advanced

412:    Concepts: matrices^row access

414: .seealso: MatRestoreRowRowUpperTriangular()
415: @*/
416: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
417: {

423:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
424:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
425:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
426:   MatPreallocated(mat);
427:   (*mat->ops->getrowuppertriangular)(mat);
428:   return(0);
429: }

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

436:    Not Collective

438:    Input Parameters:
439: +  mat - the matrix

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


445:    Level: advanced

447: .seealso:  MatGetRowUpperTriangular()
448: @*/
449: PetscErrorCode  MatRestoreRowUpperTriangular(Mat mat)
450: {

455:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
456:   if (!mat->ops->restorerowuppertriangular) return(0);
457:   (*mat->ops->restorerowuppertriangular)(mat);
458:   return(0);
459: }

463: /*@C
464:    MatSetOptionsPrefix - Sets the prefix used for searching for all 
465:    Mat options in the database.

467:    Collective on Mat

469:    Input Parameter:
470: +  A - the Mat context
471: -  prefix - the prefix to prepend to all option names

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

477:    Level: advanced

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

481: .seealso: MatSetFromOptions()
482: @*/
483: PetscErrorCode  MatSetOptionsPrefix(Mat A,const char prefix[])
484: {

489:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
490:   return(0);
491: }

495: /*@C
496:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all 
497:    Mat options in the database.

499:    Collective on Mat

501:    Input Parameters:
502: +  A - the Mat context
503: -  prefix - the prefix to prepend to all option names

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

509:    Level: advanced

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

513: .seealso: MatGetOptionsPrefix()
514: @*/
515: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
516: {
518: 
521:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
522:   return(0);
523: }

527: /*@C
528:    MatGetOptionsPrefix - Sets the prefix used for searching for all 
529:    Mat options in the database.

531:    Not Collective

533:    Input Parameter:
534: .  A - the Mat context

536:    Output Parameter:
537: .  prefix - pointer to the prefix string used

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

542:    Level: advanced

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

546: .seealso: MatAppendOptionsPrefix()
547: @*/
548: PetscErrorCode  MatGetOptionsPrefix(Mat A,const char *prefix[])
549: {

554:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
555:   return(0);
556: }

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

563:    Collective on Mat

565:    Input Parameters:
566: .  A - the Mat context

568:    Notes:
569:    For basic use of the Mat classes the user need not explicitly call
570:    MatSetUp(), since these actions will happen automatically.

572:    Level: advanced

574: .keywords: Mat, setup

576: .seealso: MatCreate(), MatDestroy()
577: @*/
578: PetscErrorCode  MatSetUp(Mat A)
579: {
580:   PetscMPIInt    size;

585:   if (!((PetscObject)A)->type_name) {
586:     MPI_Comm_size(((PetscObject)A)->comm, &size);
587:     if (size == 1) {
588:       MatSetType(A, MATSEQAIJ);
589:     } else {
590:       MatSetType(A, MATMPIAIJ);
591:     }
592:   }
593:   MatSetUpPreallocation(A);
594:   return(0);
595: }

599: /*@C
600:    MatView - Visualizes a matrix object.

602:    Collective on Mat

604:    Input Parameters:
605: +  mat - the matrix
606: -  viewer - visualization context

608:   Notes:
609:   The available visualization contexts include
610: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
611: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
612:         output where only the first processor opens
613:         the file.  All other processors send their 
614:         data to the first processor to print. 
615: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

617:    The user can open alternative visualization contexts with
618: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
619: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
620:          specified file; corresponding input uses MatLoad()
621: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to 
622:          an X window display
623: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
624:          Currently only the sequential dense and AIJ
625:          matrix types support the Socket viewer.

627:    The user can call PetscViewerSetFormat() to specify the output
628:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
629:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
630: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
631: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
632: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
633: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 
634:          format common among all matrix types
635: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 
636:          format (which is in many cases the same as the default)
637: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
638:          size and structure (not the matrix entries)
639: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
640:          the matrix structure

642:    Options Database Keys:
643: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
644: .  -mat_view_info_detailed - Prints more detailed info
645: .  -mat_view - Prints matrix in ASCII format
646: .  -mat_view_matlab - Prints matrix in Matlab format
647: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
648: .  -display <name> - Sets display name (default is host)
649: .  -draw_pause <sec> - Sets number of seconds to pause after display
650: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
651: .  -viewer_socket_machine <machine>
652: .  -viewer_socket_port <port>
653: .  -mat_view_binary - save matrix to file in binary format
654: -  -viewer_binary_filename <name>
655:    Level: beginner

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

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

663:    Concepts: matrices^viewing
664:    Concepts: matrices^plotting
665:    Concepts: matrices^printing

667: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 
668:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
669: @*/
670: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
671: {
672:   PetscErrorCode    ierr;
673:   PetscInt          rows,cols;
674:   PetscTruth        iascii;
675:   const MatType     cstr;
676:   PetscViewerFormat format;

681:   if (!viewer) {
682:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
683:   }
686:   if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
687:   MatPreallocated(mat);

689:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
690:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
691:   if (iascii) {
692:     PetscViewerGetFormat(viewer,&format);
693:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
694:       if (((PetscObject)mat)->prefix) {
695:         PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",((PetscObject)mat)->prefix);
696:       } else {
697:         PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");
698:       }
699:       PetscViewerASCIIPushTab(viewer);
700:       MatGetType(mat,&cstr);
701:       MatGetSize(mat,&rows,&cols);
702:       PetscViewerASCIIPrintf(viewer,"type=%s, rows=%D, cols=%D\n",cstr,rows,cols);
703:       if (mat->factor) {
704:         const MatSolverPackage solver;
705:         MatFactorGetSolverPackage(mat,&solver);
706:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
707:       }
708:       if (mat->ops->getinfo) {
709:         MatInfo info;
710:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
711:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
712:       }
713:     }
714:   }
715:   if (mat->ops->view) {
716:     PetscViewerASCIIPushTab(viewer);
717:     (*mat->ops->view)(mat,viewer);
718:     PetscViewerASCIIPopTab(viewer);
719:   } else if (!iascii) {
720:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
721:   }
722:   if (iascii) {
723:     PetscViewerGetFormat(viewer,&format);
724:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
725:       PetscViewerASCIIPopTab(viewer);
726:     }
727:   }
728:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
729:   return(0);
730: }

734: /*@
735:    MatScaleSystem - Scale a vector solution and right hand side to 
736:    match the scaling of a scaled matrix.
737:   
738:    Collective on Mat

740:    Input Parameter:
741: +  mat - the matrix
742: .  b - right hand side vector (or PETSC_NULL)
743: -  x - solution vector (or PETSC_NULL)


746:    Notes: 
747:    For AIJ, and BAIJ matrix formats, the matrices are not 
748:    internally scaled, so this does nothing. 

750:    The KSP methods automatically call this routine when required
751:    (via PCPreSolve()) so it is rarely used directly.

753:    Level: Developer            

755:    Concepts: matrices^scaling

757: .seealso: MatUseScaledForm(), MatUnScaleSystem()
758: @*/
759: PetscErrorCode  MatScaleSystem(Mat mat,Vec b,Vec x)
760: {

766:   MatPreallocated(mat);

770:   if (mat->ops->scalesystem) {
771:     (*mat->ops->scalesystem)(mat,b,x);
772:   }
773:   return(0);
774: }

778: /*@
779:    MatUnScaleSystem - Unscales a vector solution and right hand side to 
780:    match the original scaling of a scaled matrix.
781:   
782:    Collective on Mat

784:    Input Parameter:
785: +  mat - the matrix
786: .  b - right hand side vector (or PETSC_NULL)
787: -  x - solution vector (or PETSC_NULL)


790:    Notes: 
791:    For AIJ and BAIJ matrix formats, the matrices are not 
792:    internally scaled, so this does nothing. 

794:    The KSP methods automatically call this routine when required
795:    (via PCPreSolve()) so it is rarely used directly.

797:    Level: Developer            

799: .seealso: MatUseScaledForm(), MatScaleSystem()
800: @*/
801: PetscErrorCode  MatUnScaleSystem(Mat mat,Vec b,Vec x)
802: {

808:   MatPreallocated(mat);
811:   if (mat->ops->unscalesystem) {
812:     (*mat->ops->unscalesystem)(mat,b,x);
813:   }
814:   return(0);
815: }

819: /*@
820:    MatUseScaledForm - For matrix storage formats that scale the 
821:    matrix indicates matrix operations (MatMult() etc) are 
822:    applied using the scaled matrix.
823:   
824:    Collective on Mat

826:    Input Parameter:
827: +  mat - the matrix
828: -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for 
829:             applying the original matrix

831:    Notes: 
832:    For scaled matrix formats, applying the original, unscaled matrix
833:    will be slightly more expensive

835:    Level: Developer            

837: .seealso: MatScaleSystem(), MatUnScaleSystem()
838: @*/
839: PetscErrorCode  MatUseScaledForm(Mat mat,PetscTruth scaled)
840: {

846:   MatPreallocated(mat);
847:   if (mat->ops->usescaledform) {
848:     (*mat->ops->usescaledform)(mat,scaled);
849:   }
850:   return(0);
851: }

855: /*@
856:    MatDestroy - Frees space taken by a matrix.
857:   
858:    Collective on Mat

860:    Input Parameter:
861: .  A - the matrix

863:    Level: beginner

865: @*/
866: PetscErrorCode  MatDestroy(Mat A)
867: {
871:   if (--((PetscObject)A)->refct > 0) return(0);
872:   MatPreallocated(A);
873:   /* if memory was published with AMS then destroy it */
874:   PetscObjectDepublish(A);
875:   if (A->ops->destroy) {
876:     (*A->ops->destroy)(A);
877:   }
878:   if (A->mapping) {
879:     ISLocalToGlobalMappingDestroy(A->mapping);
880:   }
881:   if (A->bmapping) {
882:     ISLocalToGlobalMappingDestroy(A->bmapping);
883:   }

885:   if (A->spptr){PetscFree(A->spptr);}
886:   PetscLayoutDestroy(A->rmap);
887:   PetscLayoutDestroy(A->cmap);
888:   PetscHeaderDestroy(A);
889:   return(0);
890: }

894: /*@
895:    MatValid - Checks whether a matrix object is valid.

897:    Collective on Mat

899:    Input Parameter:
900: .  m - the matrix to check 

902:    Output Parameter:
903:    flg - flag indicating matrix status, either
904:    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.

906:    Level: developer

908:    Concepts: matrices^validity
909: @*/
910: PetscErrorCode  MatValid(Mat m,PetscTruth *flg)
911: {
914:   if (!m)                                          *flg = PETSC_FALSE;
915:   else if (((PetscObject)m)->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
916:   else                                             *flg = PETSC_TRUE;
917:   return(0);
918: }

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

927:    Not Collective

929:    Input Parameters:
930: +  mat - the matrix
931: .  v - a logically two-dimensional array of values
932: .  m, idxm - the number of rows and their global indices 
933: .  n, idxn - the number of columns and their global indices
934: -  addv - either ADD_VALUES or INSERT_VALUES, where
935:    ADD_VALUES adds values to any existing entries, and
936:    INSERT_VALUES replaces existing entries with new values

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

941:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 
942:    options cannot be mixed without intervening calls to the assembly
943:    routines.

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

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

953:    Efficiency Alert:
954:    The routine MatSetValuesBlocked() may offer much better efficiency
955:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

957:    Level: beginner

959:    Concepts: matrices^putting entries in

961: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
962:           InsertMode, INSERT_VALUES, ADD_VALUES
963: @*/
964: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
965: {

971:   if (!m || !n) return(0); /* no values to insert */
975:   MatPreallocated(mat);
976:   if (mat->insertmode == NOT_SET_VALUES) {
977:     mat->insertmode = addv;
978:   }
979: #if defined(PETSC_USE_DEBUG)
980:   else if (mat->insertmode != addv) {
981:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
982:   }
983:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
984: #endif

986:   if (mat->assembled) {
987:     mat->was_assembled = PETSC_TRUE;
988:     mat->assembled     = PETSC_FALSE;
989:   }
990:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
991:   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
992:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
993:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
994:   return(0);
995: }


1000: /*@ 
1001:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1002:         values into a matrix

1004:    Not Collective

1006:    Input Parameters:
1007: +  mat - the matrix
1008: .  row - the (block) row to set
1009: -  v - a logically two-dimensional array of values

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

1014:    All the nonzeros in the row must be provided

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

1018:    The row must belong to this process

1020:    Level: intermediate

1022:    Concepts: matrices^putting entries in

1024: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1025:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1026: @*/
1027: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1028: {

1035:   MatSetValuesRow(mat, mat->mapping->indices[row],v);
1036:   return(0);
1037: }

1041: /*@ 
1042:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1043:         values into a matrix

1045:    Not Collective

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

1052:    Notes:
1053:    The values, v, are column-oriented for the block version.

1055:    All the nonzeros in the row must be provided

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

1059:    The row must belong to this process

1061:    Level: advanced

1063:    Concepts: matrices^putting entries in

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

1076: #if defined(PETSC_USE_DEBUG)
1077:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1078:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1079: #endif
1080:   mat->insertmode = INSERT_VALUES;

1082:   if (mat->assembled) {
1083:     mat->was_assembled = PETSC_TRUE;
1084:     mat->assembled     = PETSC_FALSE;
1085:   }
1086:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1087:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1088:   (*mat->ops->setvaluesrow)(mat,row,v);
1089:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1090:   return(0);
1091: }

1095: /*@
1096:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1097:      Using structured grid indexing

1099:    Not Collective

1101:    Input Parameters:
1102: +  mat - the matrix
1103: .  m - number of rows being entered
1104: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1105: .  n - number of columns being entered
1106: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 
1107: .  v - a logically two-dimensional array of values
1108: -  addv - either ADD_VALUES or INSERT_VALUES, where
1109:    ADD_VALUES adds values to any existing entries, and
1110:    INSERT_VALUES replaces existing entries with new values

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

1115:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 
1116:    options cannot be mixed without intervening calls to the assembly
1117:    routines.

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

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

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

1126:    In order to use this routine you must either obtain the matrix with DAGetMatrix()
1127:    or call MatSetLocalToGlobalMapping() and MatSetStencil() first.

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

1135:    In Fortran idxm and idxn should be declared as
1136: $     MatStencil idxm(4,m),idxn(4,n)
1137:    and the values inserted using
1138: $    idxm(MatStencil_i,1) = i
1139: $    idxm(MatStencil_j,1) = j
1140: $    idxm(MatStencil_k,1) = k
1141: $    idxm(MatStencil_c,1) = c
1142:    etc

1144:    For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 
1145:    obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1146:    etc to obtain values that obtained by wrapping the values from the left edge. This does not work for the DA_NONPERIODIC
1147:    wrap.

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

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

1155:    Efficiency Alert:
1156:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1157:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1159:    Level: beginner

1161:    Concepts: matrices^putting entries in

1163: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1164:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil
1165: @*/
1166: PetscErrorCode  MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1167: {
1169:   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1170:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1180:   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1181:   if (n > 256) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);

1183:   for (i=0; i<m; i++) {
1184:     for (j=0; j<3-sdim; j++) dxm++;
1185:     tmp = *dxm++ - starts[0];
1186:     for (j=0; j<dim-1; j++) {
1187:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1188:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1189:     }
1190:     if (mat->stencil.noc) dxm++;
1191:     jdxm[i] = tmp;
1192:   }
1193:   for (i=0; i<n; i++) {
1194:     for (j=0; j<3-sdim; j++) dxn++;
1195:     tmp = *dxn++ - starts[0];
1196:     for (j=0; j<dim-1; j++) {
1197:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1198:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1199:     }
1200:     if (mat->stencil.noc) dxn++;
1201:     jdxn[i] = tmp;
1202:   }
1203:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1204:   return(0);
1205: }

1209: /*@C 
1210:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1211:      Using structured grid indexing

1213:    Not Collective

1215:    Input Parameters:
1216: +  mat - the matrix
1217: .  m - number of rows being entered
1218: .  idxm - grid coordinates for matrix rows being entered
1219: .  n - number of columns being entered
1220: .  idxn - grid coordinates for matrix columns being entered 
1221: .  v - a logically two-dimensional array of values
1222: -  addv - either ADD_VALUES or INSERT_VALUES, where
1223:    ADD_VALUES adds values to any existing entries, and
1224:    INSERT_VALUES replaces existing entries with new values

1226:    Notes:
1227:    By default the values, v, are row-oriented and unsorted.
1228:    See MatSetOption() for other options.

1230:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 
1231:    options cannot be mixed without intervening calls to the assembly
1232:    routines.

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

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

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

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

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

1250:    In Fortran idxm and idxn should be declared as
1251: $     MatStencil idxm(4,m),idxn(4,n)
1252:    and the values inserted using
1253: $    idxm(MatStencil_i,1) = i
1254: $    idxm(MatStencil_j,1) = j
1255: $    idxm(MatStencil_k,1) = k
1256:    etc

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

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

1266:    Level: beginner

1268:    Concepts: matrices^putting entries in

1270: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1271:           MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DAGetMatrix(), DAVecGetArray(), MatStencil,
1272:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1273: @*/
1274: PetscErrorCode  MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1275: {
1277:   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1278:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

1288:   if (m > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 128 rows at a time; trying to set %D",m);
1289:   if (n > 128) SETERRQ1(PETSC_ERR_SUP,"Can only set 256 columns at a time; trying to set %D",n);

1291:   for (i=0; i<m; i++) {
1292:     for (j=0; j<3-sdim; j++) dxm++;
1293:     tmp = *dxm++ - starts[0];
1294:     for (j=0; j<sdim-1; j++) {
1295:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1296:       else                                      tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1297:     }
1298:     dxm++;
1299:     jdxm[i] = tmp;
1300:   }
1301:   for (i=0; i<n; i++) {
1302:     for (j=0; j<3-sdim; j++) dxn++;
1303:     tmp = *dxn++ - starts[0];
1304:     for (j=0; j<sdim-1; j++) {
1305:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1306:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1307:     }
1308:     dxn++;
1309:     jdxn[i] = tmp;
1310:   }
1311:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1312:   return(0);
1313: }

1317: /*@ 
1318:    MatSetStencil - Sets the grid information for setting values into a matrix via
1319:         MatSetValuesStencil()

1321:    Not Collective

1323:    Input Parameters:
1324: +  mat - the matrix
1325: .  dim - dimension of the grid 1, 2, or 3
1326: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1327: .  starts - starting point of ghost nodes on your processor in x, y, and z direction 
1328: -  dof - number of degrees of freedom per node


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

1334:    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1335:    user.
1336:    
1337:    Level: beginner

1339:    Concepts: matrices^putting entries in

1341: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1342:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1343: @*/
1344: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1345: {
1346:   PetscInt i;


1353:   mat->stencil.dim = dim + (dof > 1);
1354:   for (i=0; i<dim; i++) {
1355:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1356:     mat->stencil.starts[i] = starts[dim-i-1];
1357:   }
1358:   mat->stencil.dims[dim]   = dof;
1359:   mat->stencil.starts[dim] = 0;
1360:   mat->stencil.noc         = (PetscTruth)(dof == 1);
1361:   return(0);
1362: }

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

1369:    Not Collective

1371:    Input Parameters:
1372: +  mat - the matrix
1373: .  v - a logically two-dimensional array of values
1374: .  m, idxm - the number of block rows and their global block indices 
1375: .  n, idxn - the number of block columns and their global block indices
1376: -  addv - either ADD_VALUES or INSERT_VALUES, where
1377:    ADD_VALUES adds values to any existing entries, and
1378:    INSERT_VALUES replaces existing entries with new values

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

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

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

1393:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
1394:    options cannot be mixed without intervening calls to the assembly
1395:    routines.

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

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

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

1411:    Example:
1412: $   Suppose m=n=2 and block size(bs) = 2 The array is 
1413: $
1414: $   1  2  | 3  4
1415: $   5  6  | 7  8
1416: $   - - - | - - -
1417: $   9  10 | 11 12
1418: $   13 14 | 15 16
1419: $
1420: $   v[] should be passed in like
1421: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1422: $
1423: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1424: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1426:    Level: intermediate

1428:    Concepts: matrices^putting entries in blocked

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

1439:   if (!m || !n) return(0); /* no values to insert */
1443:   MatPreallocated(mat);
1444:   if (mat->insertmode == NOT_SET_VALUES) {
1445:     mat->insertmode = addv;
1446:   }
1447: #if defined(PETSC_USE_DEBUG) 
1448:   else if (mat->insertmode != addv) {
1449:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1450:   }
1451:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1452: #endif

1454:   if (mat->assembled) {
1455:     mat->was_assembled = PETSC_TRUE;
1456:     mat->assembled     = PETSC_FALSE;
1457:   }
1458:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1459:   if (mat->ops->setvaluesblocked) {
1460:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1461:   } else {
1462:     PetscInt buf[4096],*ibufm=0,*ibufn=0;
1463:     PetscInt i,j,*iidxm,*iidxn,bs=mat->rmap->bs;
1464:     if ((m+n)*bs <= 4096) {
1465:       iidxm = buf; iidxn = buf + m*bs;
1466:     } else {
1467:       PetscMalloc2(m*bs,PetscInt,&ibufm,n*bs,PetscInt,&ibufn);
1468:       iidxm = ibufm; iidxn = ibufn;
1469:     }
1470:     for (i=0; i<m; i++) {
1471:       for (j=0; j<bs; j++) {
1472:         iidxm[i*bs+j] = bs*idxm[i] + j;
1473:       }
1474:     }
1475:     for (i=0; i<n; i++) {
1476:       for (j=0; j<bs; j++) {
1477:         iidxn[i*bs+j] = bs*idxn[i] + j;
1478:       }
1479:     }
1480:     MatSetValues(mat,bs*m,iidxm,bs*n,iidxn,v,addv);
1481:     PetscFree2(ibufm,ibufn);
1482:   }
1483:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1484:   return(0);
1485: }

1489: /*@ 
1490:    MatGetValues - Gets a block of values from a matrix.

1492:    Not Collective; currently only returns a local block

1494:    Input Parameters:
1495: +  mat - the matrix
1496: .  v - a logically two-dimensional array for storing the values
1497: .  m, idxm - the number of rows and their global indices 
1498: -  n, idxn - the number of columns and their global indices

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

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

1508:    MatGetValues() requires that the matrix has been assembled
1509:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1510:    MatSetValues() and MatGetValues() CANNOT be made in succession
1511:    without intermediate matrix assembly.

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

1516:    Level: advanced

1518:    Concepts: matrices^accessing values

1520: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1521: @*/
1522: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1523: {

1532:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1533:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1534:   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1535:   MatPreallocated(mat);

1537:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1538:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1539:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1540:   return(0);
1541: }

1545: /*@
1546:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1547:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1548:    using a local (per-processor) numbering.

1550:    Not Collective

1552:    Input Parameters:
1553: +  x - the matrix
1554: -  mapping - mapping created with ISLocalToGlobalMappingCreate() 
1555:              or ISLocalToGlobalMappingCreateIS()

1557:    Level: intermediate

1559:    Concepts: matrices^local to global mapping
1560:    Concepts: local to global mapping^for matrices

1562: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1563: @*/
1564: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1565: {
1571:   if (x->mapping) {
1572:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1573:   }
1574:   MatPreallocated(x);

1576:   if (x->ops->setlocaltoglobalmapping) {
1577:     (*x->ops->setlocaltoglobalmapping)(x,mapping);
1578:   } else {
1579:     PetscObjectReference((PetscObject)mapping);
1580:     if (x->mapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1581:     x->mapping = mapping;
1582:   }
1583:   return(0);
1584: }

1588: /*@
1589:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1590:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1591:    entries using a local (per-processor) numbering.

1593:    Not Collective

1595:    Input Parameters:
1596: +  x - the matrix
1597: -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
1598:              ISLocalToGlobalMappingCreateIS()

1600:    Level: intermediate

1602:    Concepts: matrices^local to global mapping blocked
1603:    Concepts: local to global mapping^for matrices, blocked

1605: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1606:            MatSetValuesBlocked(), MatSetValuesLocal()
1607: @*/
1608: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1609: {
1615:   if (x->bmapping) {
1616:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1617:   }
1618:   PetscObjectReference((PetscObject)mapping);
1619:   if (x->bmapping) { ISLocalToGlobalMappingDestroy(x->bmapping); }
1620:   x->bmapping = mapping;
1621:   return(0);
1622: }

1626: /*@
1627:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1628:    using a local ordering of the nodes. 

1630:    Not Collective

1632:    Input Parameters:
1633: +  x - the matrix
1634: .  nrow, irow - number of rows and their local indices
1635: .  ncol, icol - number of columns and their local indices
1636: .  y -  a logically two-dimensional array of values
1637: -  addv - either INSERT_VALUES or ADD_VALUES, where
1638:    ADD_VALUES adds values to any existing entries, and
1639:    INSERT_VALUES replaces existing entries with new values

1641:    Notes:
1642:    Before calling MatSetValuesLocal(), the user must first set the
1643:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

1645:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
1646:    options cannot be mixed without intervening calls to the assembly
1647:    routines.

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

1652:    Level: intermediate

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

1656: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1657:            MatSetValueLocal()
1658: @*/
1659: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1660: {
1662:   PetscInt       irowm[2048],icolm[2048];

1667:   if (!nrow || !ncol) return(0); /* no values to insert */
1671:   MatPreallocated(mat);
1672:   if (mat->insertmode == NOT_SET_VALUES) {
1673:     mat->insertmode = addv;
1674:   }
1675: #if defined(PETSC_USE_DEBUG) 
1676:   else if (mat->insertmode != addv) {
1677:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1678:   }
1679:   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1680:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1681:   }
1682:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1683: #endif

1685:   if (mat->assembled) {
1686:     mat->was_assembled = PETSC_TRUE;
1687:     mat->assembled     = PETSC_FALSE;
1688:   }
1689:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1690:   if (!mat->ops->setvalueslocal) {
1691:     ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);
1692:     ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);
1693:     (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);
1694:   } else {
1695:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1696:   }
1697:   mat->same_nonzero = PETSC_FALSE;
1698:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1699:   return(0);
1700: }

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

1708:    Not Collective

1710:    Input Parameters:
1711: +  x - the matrix
1712: .  nrow, irow - number of rows and their local indices
1713: .  ncol, icol - number of columns and their local indices
1714: .  y -  a logically two-dimensional array of values
1715: -  addv - either INSERT_VALUES or ADD_VALUES, where
1716:    ADD_VALUES adds values to any existing entries, and
1717:    INSERT_VALUES replaces existing entries with new values

1719:    Notes:
1720:    Before calling MatSetValuesBlockedLocal(), the user must first set the
1721:    block size using MatSetBlockSize(), and the local-to-global mapping by
1722:    calling MatSetLocalToGlobalMappingBlock(), where the mapping MUST be
1723:    set for matrix blocks, not for matrix elements.

1725:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
1726:    options cannot be mixed without intervening calls to the assembly
1727:    routines.

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

1732:    Level: intermediate

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

1736: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
1737:            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1738: @*/
1739: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1740: {
1742:   PetscInt       irowm[2048],icolm[2048];

1747:   if (!nrow || !ncol) return(0); /* no values to insert */
1751:   MatPreallocated(mat);
1752:   if (mat->insertmode == NOT_SET_VALUES) {
1753:     mat->insertmode = addv;
1754:   }
1755: #if defined(PETSC_USE_DEBUG) 
1756:   else if (mat->insertmode != addv) {
1757:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1758:   }
1759:   if (!mat->bmapping) {
1760:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1761:   }
1762:   if (nrow > 2048 || ncol > 2048) {
1763:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1764:   }
1765:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1766: #endif

1768:   if (mat->assembled) {
1769:     mat->was_assembled = PETSC_TRUE;
1770:     mat->assembled     = PETSC_FALSE;
1771:   }
1772:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1773:   ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);
1774:   ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);
1775:   if (mat->ops->setvaluesblocked) {
1776:     (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);
1777:   } else {
1778:     PetscInt buf[4096],*ibufm=0,*ibufn=0;
1779:     PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
1780:     if ((nrow+ncol)*bs <= 4096) {
1781:       iirowm = buf; iicolm = buf + nrow*bs;
1782:     } else {
1783:       PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);
1784:       iirowm = ibufm; iicolm = ibufn;
1785:     }
1786:     for (i=0; i<nrow; i++) {
1787:       for (j=0; j<bs; j++) {
1788:         iirowm[i*bs+j] = bs*irowm[i] + j;
1789:       }
1790:     }
1791:     for (i=0; i<ncol; i++) {
1792:       for (j=0; j<bs; j++) {
1793:         iicolm[i*bs+j] = bs*icolm[i] + j;
1794:       }
1795:     }
1796:     MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);
1797:     PetscFree2(ibufm,ibufn);
1798:   }
1799:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1800:   return(0);
1801: }

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

1808:    Collective on Mat and Vec

1810:    Input Parameters:
1811: +  mat - the matrix
1812: -  x   - the vector to be multiplied

1814:    Output Parameters:
1815: .  y - the result

1817:    Notes:
1818:    The vectors x and y cannot be the same.  I.e., one cannot
1819:    call MatMult(A,y,y).

1821:    Level: developer

1823:    Concepts: matrix-vector product

1825: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1826: @*/
1827: PetscErrorCode  MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
1828: {


1837:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1838:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1839:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1840:   MatPreallocated(mat);

1842:   if (!mat->ops->multdiagonalblock) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1843:   (*mat->ops->multdiagonalblock)(mat,x,y);
1844:   PetscObjectStateIncrease((PetscObject)y);
1845:   return(0);
1846: }

1848: /* --------------------------------------------------------*/
1851: /*@
1852:    MatMult - Computes the matrix-vector product, y = Ax.

1854:    Collective on Mat and Vec

1856:    Input Parameters:
1857: +  mat - the matrix
1858: -  x   - the vector to be multiplied

1860:    Output Parameters:
1861: .  y - the result

1863:    Notes:
1864:    The vectors x and y cannot be the same.  I.e., one cannot
1865:    call MatMult(A,y,y).

1867:    Level: beginner

1869:    Concepts: matrix-vector product

1871: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1872: @*/
1873: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
1874: {


1883:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1884:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1885:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1886: #ifndef PETSC_HAVE_CONSTRAINTS
1887:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
1888:   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
1889:   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);
1890: #endif
1891:   MatPreallocated(mat);

1893:   if (mat->nullsp) {
1894:     MatNullSpaceRemove(mat->nullsp,x,&x);
1895:   }

1897:   if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1898:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1899:   (*mat->ops->mult)(mat,x,y);
1900:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);

1902:   if (mat->nullsp) {
1903:     MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1904:   }
1905:   PetscObjectStateIncrease((PetscObject)y);
1906:   return(0);
1907: }

1911: /*@
1912:    MatMultTranspose - Computes matrix transpose times a vector.

1914:    Collective on Mat and Vec

1916:    Input Parameters:
1917: +  mat - the matrix
1918: -  x   - the vector to be multilplied

1920:    Output Parameters:
1921: .  y - the result

1923:    Notes:
1924:    The vectors x and y cannot be the same.  I.e., one cannot
1925:    call MatMultTranspose(A,y,y).

1927:    Level: beginner

1929:    Concepts: matrix vector product^transpose

1931: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1932: @*/
1933: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
1934: {


1943:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1944:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1945:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1946: #ifndef PETSC_HAVE_CONSTRAINTS
1947:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
1948:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
1949: #endif
1950:   MatPreallocated(mat);

1952:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1953:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1954:   (*mat->ops->multtranspose)(mat,x,y);
1955:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1956:   PetscObjectStateIncrease((PetscObject)y);
1957:   return(0);
1958: }

1962: /*@
1963:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

1965:    Collective on Mat and Vec

1967:    Input Parameters:
1968: +  mat - the matrix
1969: -  x   - the vector to be multilplied

1971:    Output Parameters:
1972: .  y - the result

1974:    Notes:
1975:    The vectors x and y cannot be the same.  I.e., one cannot
1976:    call MatMultHermitianTranspose(A,y,y).

1978:    Level: beginner

1980:    Concepts: matrix vector product^transpose

1982: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
1983: @*/
1984: PetscErrorCode  MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
1985: {


1994:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1995:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1996:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1997: #ifndef PETSC_HAVE_CONSTRAINTS
1998:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
1999:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2000: #endif
2001:   MatPreallocated(mat);

2003:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2004:   PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2005:   (*mat->ops->multhermitiantranspose)(mat,x,y);
2006:   PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2007:   PetscObjectStateIncrease((PetscObject)y);
2008:   return(0);
2009: }

2013: /*@
2014:     MatMultAdd -  Computes v3 = v2 + A * v1.

2016:     Collective on Mat and Vec

2018:     Input Parameters:
2019: +   mat - the matrix
2020: -   v1, v2 - the vectors

2022:     Output Parameters:
2023: .   v3 - the result

2025:     Notes:
2026:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
2027:     call MatMultAdd(A,v1,v2,v1).

2029:     Level: beginner

2031:     Concepts: matrix vector product^addition

2033: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2034: @*/
2035: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2036: {


2046:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2047:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2048:   if (mat->cmap->N != v1->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N);
2049:   /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N);
2050:      if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */
2051:   if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n);
2052:   if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n);
2053:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2054:   MatPreallocated(mat);

2056:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2057:   (*mat->ops->multadd)(mat,v1,v2,v3);
2058:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2059:   PetscObjectStateIncrease((PetscObject)v3);
2060:   return(0);
2061: }

2065: /*@
2066:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2068:    Collective on Mat and Vec

2070:    Input Parameters:
2071: +  mat - the matrix
2072: -  v1, v2 - the vectors

2074:    Output Parameters:
2075: .  v3 - the result

2077:    Notes:
2078:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2079:    call MatMultTransposeAdd(A,v1,v2,v1).

2081:    Level: beginner

2083:    Concepts: matrix vector product^transpose and addition

2085: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2086: @*/
2087: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2088: {


2098:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2099:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2100:   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2101:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2102:   if (mat->rmap->N != v1->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2103:   if (mat->cmap->N != v2->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2104:   if (mat->cmap->N != v3->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2105:   MatPreallocated(mat);

2107:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2108:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2109:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2110:   PetscObjectStateIncrease((PetscObject)v3);
2111:   return(0);
2112: }

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

2119:    Collective on Mat and Vec

2121:    Input Parameters:
2122: +  mat - the matrix
2123: -  v1, v2 - the vectors

2125:    Output Parameters:
2126: .  v3 - the result

2128:    Notes:
2129:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
2130:    call MatMultHermitianTransposeAdd(A,v1,v2,v1).

2132:    Level: beginner

2134:    Concepts: matrix vector product^transpose and addition

2136: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2137: @*/
2138: PetscErrorCode  MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2139: {


2149:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2150:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2151:   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2152:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2153:   if (mat->rmap->N != v1->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N);
2154:   if (mat->cmap->N != v2->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N);
2155:   if (mat->cmap->N != v3->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N);
2156:   MatPreallocated(mat);

2158:   PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2159:   (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2160:   PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2161:   PetscObjectStateIncrease((PetscObject)v3);
2162:   return(0);
2163: }

2167: /*@
2168:    MatMultConstrained - The inner multiplication routine for a
2169:    constrained matrix P^T A P.

2171:    Collective on Mat and Vec

2173:    Input Parameters:
2174: +  mat - the matrix
2175: -  x   - the vector to be multilplied

2177:    Output Parameters:
2178: .  y - the result

2180:    Notes:
2181:    The vectors x and y cannot be the same.  I.e., one cannot
2182:    call MatMult(A,y,y).

2184:    Level: beginner

2186: .keywords: matrix, multiply, matrix-vector product, constraint
2187: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2188: @*/
2189: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
2190: {

2197:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2198:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2199:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2200:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2201:   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
2202:   if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n);

2204:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2205:   (*mat->ops->multconstrained)(mat,x,y);
2206:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2207:   PetscObjectStateIncrease((PetscObject)y);

2209:   return(0);
2210: }

2214: /*@
2215:    MatMultTransposeConstrained - The inner multiplication routine for a
2216:    constrained matrix P^T A^T P.

2218:    Collective on Mat and Vec

2220:    Input Parameters:
2221: +  mat - the matrix
2222: -  x   - the vector to be multilplied

2224:    Output Parameters:
2225: .  y - the result

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

2231:    Level: beginner

2233: .keywords: matrix, multiply, matrix-vector product, constraint
2234: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2235: @*/
2236: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2237: {

2244:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2245:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2246:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2247:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2248:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);

2250:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2251:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2252:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2253:   PetscObjectStateIncrease((PetscObject)y);

2255:   return(0);
2256: }

2260: /*@C
2261:    MatGetFactorType - gets the type of factorization it is

2263:    Note Collective
2264:    as the flag

2266:    Input Parameters:
2267: .  mat - the matrix

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

2272:     Level: intermediate

2274: .seealso:    MatFactorType, MatGetFactor()
2275: @*/
2276: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2277: {
2281:   *t = mat->factor;
2282:   return(0);
2283: }

2285: /* ------------------------------------------------------------*/
2288: /*@C
2289:    MatGetInfo - Returns information about matrix storage (number of
2290:    nonzeros, memory, etc.).

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

2295:    Input Parameters:
2296: .  mat - the matrix

2298:    Output Parameters:
2299: +  flag - flag indicating the type of parameters to be returned
2300:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2301:    MAT_GLOBAL_SUM - sum over all processors)
2302: -  info - matrix information context

2304:    Notes:
2305:    The MatInfo context contains a variety of matrix data, including
2306:    number of nonzeros allocated and used, number of mallocs during
2307:    matrix assembly, etc.  Additional information for factored matrices
2308:    is provided (such as the fill ratio, number of mallocs during
2309:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2310:    when using the runtime options 
2311: $       -info -mat_view_info

2313:    Example for C/C++ Users:
2314:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2315:    data within the MatInfo context.  For example, 
2316: .vb
2317:       MatInfo info;
2318:       Mat     A;
2319:       double  mal, nz_a, nz_u;

2321:       MatGetInfo(A,MAT_LOCAL,&info);
2322:       mal  = info.mallocs;
2323:       nz_a = info.nz_allocated;
2324: .ve

2326:    Example for Fortran Users:
2327:    Fortran users should declare info as a double precision
2328:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2329:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2330:    a complete list of parameter names.
2331: .vb
2332:       double  precision info(MAT_INFO_SIZE)
2333:       double  precision mal, nz_a
2334:       Mat     A
2335:       integer ierr

2337:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2338:       mal = info(MAT_INFO_MALLOCS)
2339:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2340: .ve

2342:     Level: intermediate

2344:     Concepts: matrices^getting information on
2345:     
2346:     Developer Note: fortran interface is not autogenerated as the f90
2347:     interface defintion cannot be generated correctly [due to MatInfo]
2348:  
2349: @*/
2350: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2351: {

2358:   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2359:   MatPreallocated(mat);
2360:   (*mat->ops->getinfo)(mat,flag,info);
2361:   return(0);
2362: }

2364: /* ----------------------------------------------------------*/

2368: /*@C
2369:    MatLUFactor - Performs in-place LU factorization of matrix.

2371:    Collective on Mat

2373:    Input Parameters:
2374: +  mat - the matrix
2375: .  row - row permutation
2376: .  col - column permutation
2377: -  info - options for factorization, includes 
2378: $          fill - expected fill as ratio of original fill.
2379: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2380: $                   Run with the option -info to determine an optimal value to use

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

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

2390:    Level: developer

2392:    Concepts: matrices^LU factorization

2394: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2395:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo

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

2400: @*/
2401: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2402: {

2411:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2412:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2413:   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2414:   MatPreallocated(mat);

2416:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2417:   (*mat->ops->lufactor)(mat,row,col,info);
2418:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2419:   PetscObjectStateIncrease((PetscObject)mat);
2420:   return(0);
2421: }

2425: /*@C
2426:    MatILUFactor - Performs in-place ILU factorization of matrix.

2428:    Collective on Mat

2430:    Input Parameters:
2431: +  mat - the matrix
2432: .  row - row permutation
2433: .  col - column permutation
2434: -  info - structure containing 
2435: $      levels - number of levels of fill.
2436: $      expected fill - as ratio of original fill.
2437: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2438:                 missing diagonal entries)

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

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

2448:    Level: developer

2450:    Concepts: matrices^ILU factorization

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

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

2457: @*/
2458: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2459: {

2468:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2469:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2470:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2471:   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2472:   MatPreallocated(mat);

2474:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2475:   (*mat->ops->ilufactor)(mat,row,col,info);
2476:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2477:   PetscObjectStateIncrease((PetscObject)mat);
2478:   return(0);
2479: }

2483: /*@C
2484:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2485:    Call this routine before calling MatLUFactorNumeric().

2487:    Collective on Mat

2489:    Input Parameters:
2490: +  fact - the factor matrix obtained with MatGetFactor()
2491: .  mat - the matrix
2492: .  row, col - row and column permutations
2493: -  info - options for factorization, includes 
2494: $          fill - expected fill as ratio of original fill.
2495: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2496: $                   Run with the option -info to determine an optimal value to use


2499:    Notes:
2500:    See the users manual for additional information about
2501:    choosing the fill factor for better efficiency.

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

2507:    Level: developer

2509:    Concepts: matrices^LU symbolic factorization

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

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

2516: @*/
2517: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2518: {

2528:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2529:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2530:   if (!(fact)->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic LU",((PetscObject)mat)->type_name);
2531:   MatPreallocated(mat);

2533:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2534:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2535:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2536:   PetscObjectStateIncrease((PetscObject)fact);
2537:   return(0);
2538: }

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

2546:    Collective on Mat

2548:    Input Parameters:
2549: +  fact - the factor matrix obtained with MatGetFactor()
2550: .  mat - the matrix
2551: -  info - options for factorization

2553:    Notes:
2554:    See MatLUFactor() for in-place factorization.  See 
2555:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

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

2561:    Level: developer

2563:    Concepts: matrices^LU numeric factorization

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

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

2570: @*/
2571: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2572: {

2580:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2581:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2582:     SETERRQ4(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);
2583:   }
2584:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2585:   MatPreallocated(mat);
2586:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2587:   (fact->ops->lufactornumeric)(fact,mat,info);
2588:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

2590:   MatView_Private(fact);
2591:   PetscObjectStateIncrease((PetscObject)fact);
2592:   return(0);
2593: }

2597: /*@C
2598:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2599:    symmetric matrix. 

2601:    Collective on Mat

2603:    Input Parameters:
2604: +  mat - the matrix
2605: .  perm - row and column permutations
2606: -  f - expected fill as ratio of original fill

2608:    Notes:
2609:    See MatLUFactor() for the nonsymmetric case.  See also
2610:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2616:    Level: developer

2618:    Concepts: matrices^Cholesky factorization

2620: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2621:           MatGetOrdering()

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

2626: @*/
2627: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2628: {

2636:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2637:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2638:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2639:   if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2640:   MatPreallocated(mat);

2642:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2643:   (*mat->ops->choleskyfactor)(mat,perm,info);
2644:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2645:   PetscObjectStateIncrease((PetscObject)mat);
2646:   return(0);
2647: }

2651: /*@C
2652:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2653:    of a symmetric matrix. 

2655:    Collective on Mat

2657:    Input Parameters:
2658: +  fact - the factor matrix obtained with MatGetFactor()
2659: .  mat - the matrix
2660: .  perm - row and column permutations
2661: -  info - options for factorization, includes 
2662: $          fill - expected fill as ratio of original fill.
2663: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2664: $                   Run with the option -info to determine an optimal value to use

2666:    Notes:
2667:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2668:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2674:    Level: developer

2676:    Concepts: matrices^Cholesky symbolic factorization

2678: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2679:           MatGetOrdering()

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

2684: @*/
2685: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2686: {

2695:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
2696:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2697:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2698:   if (!(fact)->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2699:   MatPreallocated(mat);

2701:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2702:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2703:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2704:   PetscObjectStateIncrease((PetscObject)fact);
2705:   return(0);
2706: }

2710: /*@C
2711:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2712:    of a symmetric matrix. Call this routine after first calling
2713:    MatCholeskyFactorSymbolic().

2715:    Collective on Mat

2717:    Input Parameters:
2718: +  fact - the factor matrix obtained with MatGetFactor()
2719: .  mat - the initial matrix
2720: .  info - options for factorization
2721: -  fact - the symbolic factor of mat


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

2729:    Level: developer

2731:    Concepts: matrices^Cholesky numeric factorization

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

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

2738: @*/
2739: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2740: {

2748:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2749:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2750:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2751:     SETERRQ4(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);
2752:   }
2753:   MatPreallocated(mat);

2755:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2756:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
2757:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

2759:   MatView_Private(fact);
2760:   PetscObjectStateIncrease((PetscObject)fact);
2761:   return(0);
2762: }

2764: /* ----------------------------------------------------------------*/
2767: /*@
2768:    MatSolve - Solves A x = b, given a factored matrix.

2770:    Collective on Mat and Vec

2772:    Input Parameters:
2773: +  mat - the factored matrix
2774: -  b - the right-hand-side vector

2776:    Output Parameter:
2777: .  x - the result vector

2779:    Notes:
2780:    The vectors b and x cannot be the same.  I.e., one cannot
2781:    call MatSolve(A,x,x).

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

2788:    Level: developer

2790:    Concepts: matrices^triangular solves

2792: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2793: @*/
2794: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
2795: {

2805:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2806:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2807:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2808:   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2809:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2810:   if (!mat->rmap->N && !mat->cmap->N) return(0);
2811:   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2812:   MatPreallocated(mat);

2814:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2815:   (*mat->ops->solve)(mat,b,x);
2816:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2817:   PetscObjectStateIncrease((PetscObject)x);
2818:   return(0);
2819: }

2823: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
2824: {
2826:   Vec            b,x;
2827:   PetscInt       m,N,i;
2828:   PetscScalar    *bb,*xx;

2831:   MatGetArray(B,&bb);
2832:   MatGetArray(X,&xx);
2833:   MatGetLocalSize(B,&m,PETSC_NULL);  /* number local rows */
2834:   MatGetSize(B,PETSC_NULL,&N);       /* total columns in dense matrix */
2835:   MatGetVecs(A,&x,&b);
2836:   for (i=0; i<N; i++) {
2837:     VecPlaceArray(b,bb + i*m);
2838:     VecPlaceArray(x,xx + i*m);
2839:     MatSolve(A,b,x);
2840:     VecResetArray(x);
2841:     VecResetArray(b);
2842:   }
2843:   VecDestroy(b);
2844:   VecDestroy(x);
2845:   MatRestoreArray(B,&bb);
2846:   MatRestoreArray(X,&xx);
2847:   return(0);
2848: }

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

2855:    Collective on Mat 

2857:    Input Parameters:
2858: +  mat - the factored matrix
2859: -  B - the right-hand-side matrix  (dense matrix)

2861:    Output Parameter:
2862: .  X - the result matrix (dense matrix)

2864:    Notes:
2865:    The matrices b and x cannot be the same.  I.e., one cannot
2866:    call MatMatSolve(A,x,x).

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

2874:    Level: developer

2876:    Concepts: matrices^triangular solves

2878: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2879: @*/
2880: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
2881: {

2891:   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2892:   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2893:   if (A->cmap->N != X->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N);
2894:   if (A->rmap->N != B->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N);
2895:   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n);
2896:   if (!A->rmap->N && !A->cmap->N) return(0);
2897:   MatPreallocated(A);

2899:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
2900:   if (!A->ops->matsolve) {
2901:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
2902:     MatMatSolve_Basic(A,B,X);
2903:   } else {
2904:     (*A->ops->matsolve)(A,B,X);
2905:   }
2906:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
2907:   PetscObjectStateIncrease((PetscObject)X);
2908:   return(0);
2909: }


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

2918:    Collective on Mat and Vec

2920:    Input Parameters:
2921: +  mat - the factored matrix
2922: -  b - the right-hand-side vector

2924:    Output Parameter:
2925: .  x - the result vector

2927:    Notes:
2928:    MatSolve() should be used for most applications, as it performs
2929:    a forward solve followed by a backward solve.

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

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

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

2944:    Level: developer

2946:    Concepts: matrices^forward solves

2948: .seealso: MatSolve(), MatBackwardSolve()
2949: @*/
2950: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
2951: {

2961:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2962:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2963:   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2964:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
2965:   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
2966:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
2967:   MatPreallocated(mat);
2968:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2969:   (*mat->ops->forwardsolve)(mat,b,x);
2970:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2971:   PetscObjectStateIncrease((PetscObject)x);
2972:   return(0);
2973: }

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

2981:    Collective on Mat and Vec

2983:    Input Parameters:
2984: +  mat - the factored matrix
2985: -  b - the right-hand-side vector

2987:    Output Parameter:
2988: .  x - the result vector

2990:    Notes:
2991:    MatSolve() should be used for most applications, as it performs
2992:    a forward solve followed by a backward solve.

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

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

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

3007:    Level: developer

3009:    Concepts: matrices^backward solves

3011: .seealso: MatSolve(), MatForwardSolve()
3012: @*/
3013: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
3014: {

3024:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3025:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3026:   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3027:   if (mat->cmap->N != x->map->N) SETERRQ2(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(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_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3030:   MatPreallocated(mat);

3032:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3033:   (*mat->ops->backwardsolve)(mat,b,x);
3034:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3035:   PetscObjectStateIncrease((PetscObject)x);
3036:   return(0);
3037: }

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

3044:    Collective on Mat and Vec

3046:    Input Parameters:
3047: +  mat - the factored matrix
3048: .  b - the right-hand-side vector
3049: -  y - the vector to be added to 

3051:    Output Parameter:
3052: .  x - the result vector

3054:    Notes:
3055:    The vectors b and x cannot be the same.  I.e., one cannot
3056:    call MatSolveAdd(A,x,y,x).

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

3062:    Level: developer

3064:    Concepts: matrices^triangular solves

3066: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3067: @*/
3068: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3069: {
3070:   PetscScalar    one = 1.0;
3071:   Vec            tmp;

3083:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3084:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3085:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3086:   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3087:   if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N);
3088:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3089:   if (x->map->n != y->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3090:   MatPreallocated(mat);

3092:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3093:   if (mat->ops->solveadd)  {
3094:     (*mat->ops->solveadd)(mat,b,y,x);
3095:   } else {
3096:     /* do the solve then the add manually */
3097:     if (x != y) {
3098:       MatSolve(mat,b,x);
3099:       VecAXPY(x,one,y);
3100:     } else {
3101:       VecDuplicate(x,&tmp);
3102:       PetscLogObjectParent(mat,tmp);
3103:       VecCopy(x,tmp);
3104:       MatSolve(mat,b,x);
3105:       VecAXPY(x,one,tmp);
3106:       VecDestroy(tmp);
3107:     }
3108:   }
3109:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3110:   PetscObjectStateIncrease((PetscObject)x);
3111:   return(0);
3112: }

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

3119:    Collective on Mat and Vec

3121:    Input Parameters:
3122: +  mat - the factored matrix
3123: -  b - the right-hand-side vector

3125:    Output Parameter:
3126: .  x - the result vector

3128:    Notes:
3129:    The vectors b and x cannot be the same.  I.e., one cannot
3130:    call MatSolveTranspose(A,x,x).

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

3136:    Level: developer

3138:    Concepts: matrices^triangular solves

3140: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3141: @*/
3142: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3143: {

3153:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3154:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3155:   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3156:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3157:   if (mat->cmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3158:   MatPreallocated(mat);
3159:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3160:   (*mat->ops->solvetranspose)(mat,b,x);
3161:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3162:   PetscObjectStateIncrease((PetscObject)x);
3163:   return(0);
3164: }

3168: /*@
3169:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
3170:                       factored matrix. 

3172:    Collective on Mat and Vec

3174:    Input Parameters:
3175: +  mat - the factored matrix
3176: .  b - the right-hand-side vector
3177: -  y - the vector to be added to 

3179:    Output Parameter:
3180: .  x - the result vector

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

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

3190:    Level: developer

3192:    Concepts: matrices^triangular solves

3194: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3195: @*/
3196: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3197: {
3198:   PetscScalar    one = 1.0;
3200:   Vec            tmp;

3211:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3212:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3213:   if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
3214:   if (mat->cmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N);
3215:   if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
3216:   if (x->map->n != y->map->n)   SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n);
3217:   MatPreallocated(mat);

3219:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3220:   if (mat->ops->solvetransposeadd) {
3221:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3222:   } else {
3223:     /* do the solve then the add manually */
3224:     if (x != y) {
3225:       MatSolveTranspose(mat,b,x);
3226:       VecAXPY(x,one,y);
3227:     } else {
3228:       VecDuplicate(x,&tmp);
3229:       PetscLogObjectParent(mat,tmp);
3230:       VecCopy(x,tmp);
3231:       MatSolveTranspose(mat,b,x);
3232:       VecAXPY(x,one,tmp);
3233:       VecDestroy(tmp);
3234:     }
3235:   }
3236:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3237:   PetscObjectStateIncrease((PetscObject)x);
3238:   return(0);
3239: }
3240: /* ----------------------------------------------------------------*/

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

3247:    Collective on Mat and Vec

3249:    Input Parameters:
3250: +  mat - the matrix
3251: .  b - the right hand side
3252: .  omega - the relaxation factor
3253: .  flag - flag indicating the type of SOR (see below)
3254: .  shift -  diagonal shift
3255: .  its - the number of iterations
3256: -  lits - the number of local iterations 

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

3261:    SOR Flags:
3262: .     SOR_FORWARD_SWEEP - forward SOR
3263: .     SOR_BACKWARD_SWEEP - backward SOR
3264: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3265: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
3266: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
3267: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3268: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
3269:          upper/lower triangular part of matrix to
3270:          vector (with omega)
3271: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3273:    Notes:
3274:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3275:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3276:    on each processor. 

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

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

3283:    Notes for Advanced Users:
3284:    The flags are implemented as bitwise inclusive or operations.
3285:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3286:    to specify a zero initial guess for SSOR.

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


3293:    Level: developer

3295:    Concepts: matrices^relaxation
3296:    Concepts: matrices^SOR
3297:    Concepts: matrices^Gauss-Seidel

3299: @*/
3300: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3301: {

3311:   if (!mat->ops->sor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3312:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3313:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3314:   if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N);
3315:   if (mat->rmap->N != b->map->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N);
3316:   if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3317:   if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3318:   if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);

3320:   MatPreallocated(mat);
3321:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3322:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3323:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3324:   PetscObjectStateIncrease((PetscObject)x);
3325:   return(0);
3326: }

3330: /*
3331:       Default matrix copy routine.
3332: */
3333: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3334: {
3335:   PetscErrorCode    ierr;
3336:   PetscInt          i,rstart = 0,rend = 0,nz;
3337:   const PetscInt    *cwork;
3338:   const PetscScalar *vwork;

3341:   if (B->assembled) {
3342:     MatZeroEntries(B);
3343:   }
3344:   MatGetOwnershipRange(A,&rstart,&rend);
3345:   for (i=rstart; i<rend; i++) {
3346:     MatGetRow(A,i,&nz,&cwork,&vwork);
3347:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3348:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3349:   }
3350:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3351:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3352:   PetscObjectStateIncrease((PetscObject)B);
3353:   return(0);
3354: }

3358: /*@
3359:    MatCopy - Copys a matrix to another matrix.

3361:    Collective on Mat

3363:    Input Parameters:
3364: +  A - the matrix
3365: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3367:    Output Parameter:
3368: .  B - where the copy is put

3370:    Notes:
3371:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
3372:    same nonzero pattern or the routine will crash.

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

3378:    Level: intermediate
3379:    
3380:    Concepts: matrices^copying

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

3384: @*/
3385: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3386: {
3388:   PetscInt       i;

3396:   MatPreallocated(B);
3397:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3398:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3399:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(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);
3400:   MatPreallocated(A);

3402:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3403:   if (A->ops->copy) {
3404:     (*A->ops->copy)(A,B,str);
3405:   } else { /* generic conversion */
3406:     MatCopy_Basic(A,B,str);
3407:   }
3408:   if (A->mapping) {
3409:     if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
3410:     MatSetLocalToGlobalMapping(B,A->mapping);
3411:   }
3412:   if (A->bmapping) {
3413:     if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
3414:     MatSetLocalToGlobalMappingBlock(B,A->mapping);
3415:   }

3417:   B->stencil.dim = A->stencil.dim;
3418:   B->stencil.noc = A->stencil.noc;
3419:   for (i=0; i<=A->stencil.dim; i++) {
3420:     B->stencil.dims[i]   = A->stencil.dims[i];
3421:     B->stencil.starts[i] = A->stencil.starts[i];
3422:   }

3424:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3425:   PetscObjectStateIncrease((PetscObject)B);
3426:   return(0);
3427: }

3431: /*@C  
3432:    MatConvert - Converts a matrix to another matrix, either of the same
3433:    or different type.

3435:    Collective on Mat

3437:    Input Parameters:
3438: +  mat - the matrix
3439: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3440:    same type as the original matrix.
3441: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3442:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3443:    MAT_INITIAL_MATRIX.

3445:    Output Parameter:
3446: .  M - pointer to place new matrix

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

3453:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3454:    the MPI communicator of the generated matrix is always the same as the communicator
3455:    of the input matrix.

3457:    Level: intermediate

3459:    Concepts: matrices^converting between storage formats

3461: .seealso: MatCopy(), MatDuplicate()
3462: @*/
3463: PetscErrorCode  MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3464: {
3465:   PetscErrorCode         ierr;
3466:   PetscTruth             sametype,issame,flg;
3467:   char                   convname[256],mtype[256];
3468:   Mat                    B;

3474:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3475:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3476:   MatPreallocated(mat);

3478:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3479:   if (flg) {
3480:     newtype = mtype;
3481:   }
3482:   PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3483:   PetscStrcmp(newtype,"same",&issame);
3484:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3485:     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3486:   }

3488:   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3489: 
3490:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3491:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3492:   } else {
3493:     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3494:     const char     *prefix[3] = {"seq","mpi",""};
3495:     PetscInt       i;
3496:     /* 
3497:        Order of precedence:
3498:        1) See if a specialized converter is known to the current matrix.
3499:        2) See if a specialized converter is known to the desired matrix class.
3500:        3) See if a good general converter is registered for the desired class
3501:           (as of 6/27/03 only MATMPIADJ falls into this category).
3502:        4) See if a good general converter is known for the current matrix.
3503:        5) Use a really basic converter.
3504:     */
3505: 
3506:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3507:     for (i=0; i<3; i++) {
3508:       PetscStrcpy(convname,"MatConvert_");
3509:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3510:       PetscStrcat(convname,"_");
3511:       PetscStrcat(convname,prefix[i]);
3512:       PetscStrcat(convname,newtype);
3513:       PetscStrcat(convname,"_C");
3514:       PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3515:       if (conv) goto foundconv;
3516:     }

3518:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3519:     MatCreate(((PetscObject)mat)->comm,&B);
3520:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3521:     MatSetType(B,newtype);
3522:     for (i=0; i<3; i++) {
3523:       PetscStrcpy(convname,"MatConvert_");
3524:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3525:       PetscStrcat(convname,"_");
3526:       PetscStrcat(convname,prefix[i]);
3527:       PetscStrcat(convname,newtype);
3528:       PetscStrcat(convname,"_C");
3529:       PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3530:       if (conv) {
3531:         MatDestroy(B);
3532:         goto foundconv;
3533:       }
3534:     }

3536:     /* 3) See if a good general converter is registered for the desired class */
3537:     conv = B->ops->convertfrom;
3538:     MatDestroy(B);
3539:     if (conv) goto foundconv;

3541:     /* 4) See if a good general converter is known for the current matrix */
3542:     if (mat->ops->convert) {
3543:       conv = mat->ops->convert;
3544:     }
3545:     if (conv) goto foundconv;

3547:     /* 5) Use a really basic converter. */
3548:     conv = MatConvert_Basic;

3550:     foundconv:
3551:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3552:     (*conv)(mat,newtype,reuse,M);
3553:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3554:   }
3555:   PetscObjectStateIncrease((PetscObject)*M);
3556:   return(0);
3557: }

3561: /*@C  
3562:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3564:    Not Collective

3566:    Input Parameter:
3567: .  mat - the matrix, must be a factored matrix

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

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

3576:    Level: intermediate

3578: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3579: @*/
3580: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3581: {
3582:   PetscErrorCode         ierr;
3583:   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);

3588:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3589:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3590:   if (!conv) {
3591:     *type = MAT_SOLVER_PETSC;
3592:   } else {
3593:     (*conv)(mat,type);
3594:   }
3595:   return(0);
3596: }

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

3603:    Collective on Mat

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

3610:    Output Parameters:
3611: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

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

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

3619:    Level: intermediate

3621: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3622: @*/
3623: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3624: {
3625:   PetscErrorCode         ierr;
3626:   char                   convname[256];
3627:   PetscErrorCode         (*conv)(Mat,MatFactorType,Mat*);


3633:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3634:   MatPreallocated(mat);

3636:   PetscStrcpy(convname,"MatGetFactor_");
3637:   PetscStrcat(convname,type);
3638:   PetscStrcat(convname,"_C");
3639:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3640:   if (!conv) {
3641:     PetscTruth flag;
3642:     PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);
3643:     if (flag) {
3644:       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3645:     } else {
3646:       SETERRQ3(PETSC_ERR_SUP,"Matrix format %s does not have a solver %s. Perhaps you must config/configure.py with --download-%s",((PetscObject)mat)->type_name,type,type);
3647:     }
3648:   }
3649:   (*conv)(mat,ftype,f);
3650:   return(0);
3651: }

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

3658:    Collective on Mat

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

3665:    Output Parameter:
3666: .    flg - PETSC_TRUE if the factorization is available

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

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

3674:    Level: intermediate

3676: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3677: @*/
3678: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3679: {
3680:   PetscErrorCode         ierr;
3681:   char                   convname[256];
3682:   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscTruth*);


3688:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3689:   MatPreallocated(mat);

3691:   PetscStrcpy(convname,"MatGetFactorAvailable_");
3692:   PetscStrcat(convname,type);
3693:   PetscStrcat(convname,"_C");
3694:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3695:   if (!conv) {
3696:     *flg = PETSC_FALSE;
3697:   } else {
3698:     (*conv)(mat,ftype,flg);
3699:   }
3700:   return(0);
3701: }


3706: /*@
3707:    MatDuplicate - Duplicates a matrix including the non-zero structure.

3709:    Collective on Mat

3711:    Input Parameters:
3712: +  mat - the matrix
3713: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3714:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

3716:    Output Parameter:
3717: .  M - pointer to place new matrix

3719:    Level: intermediate

3721:    Concepts: matrices^duplicating

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

3725: .seealso: MatCopy(), MatConvert()
3726: @*/
3727: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3728: {
3730:   Mat            B;
3731:   PetscInt       i;

3737:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3738:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3739:   MatPreallocated(mat);

3741:   *M  = 0;
3742:   if (!mat->ops->duplicate) {
3743:     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3744:   }
3745:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3746:   (*mat->ops->duplicate)(mat,op,M);
3747:   B = *M;
3748:   if (mat->mapping) {
3749:     MatSetLocalToGlobalMapping(B,mat->mapping);
3750:   }
3751:   if (mat->bmapping) {
3752:     MatSetLocalToGlobalMappingBlock(B,mat->bmapping);
3753:   }
3754:   PetscLayoutCopy(mat->rmap,&B->rmap);
3755:   PetscLayoutCopy(mat->cmap,&B->cmap);
3756: 
3757:   B->stencil.dim = mat->stencil.dim;
3758:   B->stencil.noc = mat->stencil.noc;
3759:   for (i=0; i<=mat->stencil.dim; i++) {
3760:     B->stencil.dims[i]   = mat->stencil.dims[i];
3761:     B->stencil.starts[i] = mat->stencil.starts[i];
3762:   }

3764:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3765:   PetscObjectStateIncrease((PetscObject)B);
3766:   return(0);
3767: }

3771: /*@ 
3772:    MatGetDiagonal - Gets the diagonal of a matrix.

3774:    Collective on Mat and Vec

3776:    Input Parameters:
3777: +  mat - the matrix
3778: -  v - the vector for storing the diagonal

3780:    Output Parameter:
3781: .  v - the diagonal of the matrix

3783:    Level: intermediate

3785:    Concepts: matrices^accessing diagonals

3787: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3788: @*/
3789: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
3790: {

3797:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3798:   if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3799:   MatPreallocated(mat);

3801:   (*mat->ops->getdiagonal)(mat,v);
3802:   PetscObjectStateIncrease((PetscObject)v);
3803:   return(0);
3804: }

3808: /*@ 
3809:    MatGetRowMin - Gets the minimum value (of the real part) of each
3810:         row of the matrix

3812:    Collective on Mat and Vec

3814:    Input Parameters:
3815: .  mat - the matrix

3817:    Output Parameter:
3818: +  v - the vector for storing the maximums
3819: -  idx - the indices of the column found for each row (optional)

3821:    Level: intermediate

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

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

3828:    Concepts: matrices^getting row maximums

3830: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3831:           MatGetRowMax()
3832: @*/
3833: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3834: {

3841:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3842:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3843:   MatPreallocated(mat);

3845:   (*mat->ops->getrowmin)(mat,v,idx);
3846:   PetscObjectStateIncrease((PetscObject)v);
3847:   return(0);
3848: }

3852: /*@ 
3853:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3854:         row of the matrix

3856:    Collective on Mat and Vec

3858:    Input Parameters:
3859: .  mat - the matrix

3861:    Output Parameter:
3862: +  v - the vector for storing the minimums
3863: -  idx - the indices of the column found for each row (optional)

3865:    Level: intermediate

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

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

3872:    Concepts: matrices^getting row maximums

3874: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3875: @*/
3876: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3877: {

3884:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3885:   if (!mat->ops->getrowminabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3886:   MatPreallocated(mat);
3887:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

3889:   (*mat->ops->getrowminabs)(mat,v,idx);
3890:   PetscObjectStateIncrease((PetscObject)v);
3891:   return(0);
3892: }

3896: /*@ 
3897:    MatGetRowMax - Gets the maximum value (of the real part) of each
3898:         row of the matrix

3900:    Collective on Mat and Vec

3902:    Input Parameters:
3903: .  mat - the matrix

3905:    Output Parameter:
3906: +  v - the vector for storing the maximums
3907: -  idx - the indices of the column found for each row (optional)

3909:    Level: intermediate

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

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

3916:    Concepts: matrices^getting row maximums

3918: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3919: @*/
3920: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3921: {

3928:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3929:   if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3930:   MatPreallocated(mat);

3932:   (*mat->ops->getrowmax)(mat,v,idx);
3933:   PetscObjectStateIncrease((PetscObject)v);
3934:   return(0);
3935: }

3939: /*@ 
3940:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3941:         row of the matrix

3943:    Collective on Mat and Vec

3945:    Input Parameters:
3946: .  mat - the matrix

3948:    Output Parameter:
3949: +  v - the vector for storing the maximums
3950: -  idx - the indices of the column found for each row (optional)

3952:    Level: intermediate

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

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

3959:    Concepts: matrices^getting row maximums

3961: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3962: @*/
3963: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3964: {

3971:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3972:   if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3973:   MatPreallocated(mat);
3974:   if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}

3976:   (*mat->ops->getrowmaxabs)(mat,v,idx);
3977:   PetscObjectStateIncrease((PetscObject)v);
3978:   return(0);
3979: }

3983: /*@ 
3984:    MatGetRowSum - Gets the sum of each row of the matrix

3986:    Collective on Mat and Vec

3988:    Input Parameters:
3989: .  mat - the matrix

3991:    Output Parameter:
3992: .  v - the vector for storing the sum of rows

3994:    Level: intermediate

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

3998:    Concepts: matrices^getting row sums

4000: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4001: @*/
4002: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
4003: {
4004:   PetscInt       start = 0, end = 0, row;
4005:   PetscScalar   *array;

4012:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4013:   MatPreallocated(mat);
4014:   MatGetOwnershipRange(mat, &start, &end);
4015:   VecGetArray(v, &array);
4016:   for(row = start; row < end; ++row) {
4017:     PetscInt           ncols, col;
4018:     const PetscInt    *cols;
4019:     const PetscScalar *vals;

4021:     array[row - start] = 0.0;
4022:     MatGetRow(mat, row, &ncols, &cols, &vals);
4023:     for(col = 0; col < ncols; col++) {
4024:       array[row - start] += vals[col];
4025:     }
4026:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4027:   }
4028:   VecRestoreArray(v, &array);
4029:   PetscObjectStateIncrease((PetscObject) v);
4030:   return(0);
4031: }

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

4038:    Collective on Mat

4040:    Input Parameter:
4041: +  mat - the matrix to transpose
4042: -  reuse - store the transpose matrix in the provided B

4044:    Output Parameters:
4045: .  B - the transpose 

4047:    Notes:
4048:      If you  pass in &mat for B the transpose will be done in place

4050:    Level: intermediate

4052:    Concepts: matrices^transposing

4054: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4055: @*/
4056: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4057: {

4063:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4064:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4065:   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4066:   MatPreallocated(mat);

4068:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4069:   (*mat->ops->transpose)(mat,reuse,B);
4070:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4071:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4072:   return(0);
4073: }

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

4081:    Collective on Mat

4083:    Input Parameter:
4084: +  A - the matrix to test
4085: -  B - the matrix to test against, this can equal the first parameter

4087:    Output Parameters:
4088: .  flg - the result

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

4095:    Level: intermediate

4097:    Concepts: matrices^transposing, matrix^symmetry

4099: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4100: @*/
4101: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4102: {
4103:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

4109:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4110:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4111:   if (f && g) {
4112:     if (f==g) {
4113:       (*f)(A,B,tol,flg);
4114:     } else {
4115:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4116:     }
4117:   }
4118:   return(0);
4119: }

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

4126:    Collective on Mat

4128:    Input Parameter:
4129: +  mat - the matrix to transpose and complex conjugate
4130: -  reuse - store the transpose matrix in the provided B

4132:    Output Parameters:
4133: .  B - the Hermitian

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

4138:    Level: intermediate

4140:    Concepts: matrices^transposing, complex conjugatex

4142: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4143: @*/
4144: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4145: {

4149:   MatTranspose(mat,reuse,B);
4150: #if defined(PETSC_USE_COMPLEX)
4151:   MatConjugate(*B);
4152: #endif
4153:   return(0);
4154: }

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

4161:    Collective on Mat

4163:    Input Parameter:
4164: +  A - the matrix to test
4165: -  B - the matrix to test against, this can equal the first parameter

4167:    Output Parameters:
4168: .  flg - the result

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

4175:    Level: intermediate

4177:    Concepts: matrices^transposing, matrix^symmetry

4179: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4180: @*/
4181: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4182: {
4183:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

4189:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4190:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4191:   if (f && g) {
4192:     if (f==g) {
4193:       (*f)(A,B,tol,flg);
4194:     } else {
4195:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4196:     }
4197:   }
4198:   return(0);
4199: }

4203: /*@
4204:    MatPermute - Creates a new matrix with rows and columns permuted from the 
4205:    original.

4207:    Collective on Mat

4209:    Input Parameters:
4210: +  mat - the matrix to permute
4211: .  row - row permutation, each processor supplies only the permutation for its rows
4212: -  col - column permutation, each processor needs the entire column permutation, that is
4213:          this is the same size as the total number of columns in the matrix. It can often
4214:          be obtained with ISAllGather() on the row permutation

4216:    Output Parameters:
4217: .  B - the permuted matrix

4219:    Level: advanced

4221:    Concepts: matrices^permuting

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

4225: @*/
4226: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4227: {

4236:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4237:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4238:   if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4239:   MatPreallocated(mat);

4241:   (*mat->ops->permute)(mat,row,col,B);
4242:   PetscObjectStateIncrease((PetscObject)*B);
4243:   return(0);
4244: }

4248: /*@
4249:   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the 
4250:   original and sparsified to the prescribed tolerance.

4252:   Collective on Mat

4254:   Input Parameters:
4255: + A    - The matrix to permute
4256: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4257: . frac - The half-bandwidth as a fraction of the total size, or 0.0
4258: . tol  - The drop tolerance
4259: . rowp - The row permutation
4260: - colp - The column permutation

4262:   Output Parameter:
4263: . B    - The permuted, sparsified matrix

4265:   Level: advanced

4267:   Note:
4268:   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4269:   restrict the half-bandwidth of the resulting matrix to 5% of the
4270:   total matrix size.

4272: .keywords: matrix, permute, sparsify

4274: .seealso: MatGetOrdering(), MatPermute()
4275: @*/
4276: PetscErrorCode  MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4277: {
4278:   IS                irowp, icolp;
4279:   const PetscInt    *rows, *cols;
4280:   PetscInt          M, N, locRowStart = 0, locRowEnd = 0;
4281:   PetscInt          nz, newNz;
4282:   const PetscInt    *cwork;
4283:   PetscInt          *cnew;
4284:   const PetscScalar *vwork;
4285:   PetscScalar       *vnew;
4286:   PetscInt          bw, issize;
4287:   PetscInt          row, locRow, newRow, col, newCol;
4288:   PetscErrorCode    ierr;

4295:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4296:   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4297:   if (!A->ops->permutesparsify) {
4298:     MatGetSize(A, &M, &N);
4299:     MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
4300:     ISGetSize(rowp, &issize);
4301:     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4302:     ISGetSize(colp, &issize);
4303:     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4304:     ISInvertPermutation(rowp, 0, &irowp);
4305:     ISGetIndices(irowp, &rows);
4306:     ISInvertPermutation(colp, 0, &icolp);
4307:     ISGetIndices(icolp, &cols);
4308:     PetscMalloc(N*sizeof(PetscInt),&cnew);
4309:     PetscMalloc(N*sizeof(PetscScalar),&vnew);

4311:     /* Setup bandwidth to include */
4312:     if (band == PETSC_DECIDE) {
4313:       if (frac <= 0.0)
4314:         bw = (PetscInt) (M * 0.05);
4315:       else
4316:         bw = (PetscInt) (M * frac);
4317:     } else {
4318:       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4319:       bw = band;
4320:     }

4322:     /* Put values into new matrix */
4323:     MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
4324:     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4325:       MatGetRow(A, row, &nz, &cwork, &vwork);
4326:       newRow   = rows[locRow]+locRowStart;
4327:       for(col = 0, newNz = 0; col < nz; col++) {
4328:         newCol = cols[cwork[col]];
4329:         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4330:           cnew[newNz] = newCol;
4331:           vnew[newNz] = vwork[col];
4332:           newNz++;
4333:         }
4334:       }
4335:       MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
4336:       MatRestoreRow(A, row, &nz, &cwork, &vwork);
4337:     }
4338:     PetscFree(cnew);
4339:     PetscFree(vnew);
4340:     MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
4341:     MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
4342:     ISRestoreIndices(irowp, &rows);
4343:     ISRestoreIndices(icolp, &cols);
4344:     ISDestroy(irowp);
4345:     ISDestroy(icolp);
4346:   } else {
4347:     (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
4348:   }
4349:   PetscObjectStateIncrease((PetscObject)*B);
4350:   return(0);
4351: }

4355: /*@
4356:    MatEqual - Compares two matrices.

4358:    Collective on Mat

4360:    Input Parameters:
4361: +  A - the first matrix
4362: -  B - the second matrix

4364:    Output Parameter:
4365: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4367:    Level: intermediate

4369:    Concepts: matrices^equality between
4370: @*/
4371: PetscErrorCode  MatEqual(Mat A,Mat B,PetscTruth *flg)
4372: {

4382:   MatPreallocated(B);
4383:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4384:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4385:   if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(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);
4386:   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4387:   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4388:   if (A->ops->equal != B->ops->equal) SETERRQ2(PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
4389:   MatPreallocated(A);

4391:   (*A->ops->equal)(A,B,flg);
4392:   return(0);
4393: }

4397: /*@
4398:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4399:    matrices that are stored as vectors.  Either of the two scaling
4400:    matrices can be PETSC_NULL.

4402:    Collective on Mat

4404:    Input Parameters:
4405: +  mat - the matrix to be scaled
4406: .  l - the left scaling vector (or PETSC_NULL)
4407: -  r - the right scaling vector (or PETSC_NULL)

4409:    Notes:
4410:    MatDiagonalScale() computes A = LAR, where
4411:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)

4413:    Level: intermediate

4415:    Concepts: matrices^diagonal scaling
4416:    Concepts: diagonal scaling of matrices

4418: .seealso: MatScale()
4419: @*/
4420: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4421: {

4427:   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4430:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4431:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4432:   MatPreallocated(mat);

4434:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4435:   (*mat->ops->diagonalscale)(mat,l,r);
4436:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4437:   PetscObjectStateIncrease((PetscObject)mat);
4438:   return(0);
4439: }

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

4446:     Collective on Mat

4448:     Input Parameters:
4449: +   mat - the matrix to be scaled
4450: -   a  - the scaling value

4452:     Output Parameter:
4453: .   mat - the scaled matrix

4455:     Level: intermediate

4457:     Concepts: matrices^scaling all entries

4459: .seealso: MatDiagonalScale()
4460: @*/
4461: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4462: {

4468:   if (a != 1.0 && !mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4469:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4470:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4471:   MatPreallocated(mat);

4473:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4474:   if (a != 1.0) {
4475:     (*mat->ops->scale)(mat,a);
4476:     PetscObjectStateIncrease((PetscObject)mat);
4477:   }
4478:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4479:   return(0);
4480: }

4484: /*@ 
4485:    MatNorm - Calculates various norms of a matrix.

4487:    Collective on Mat

4489:    Input Parameters:
4490: +  mat - the matrix
4491: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4493:    Output Parameters:
4494: .  nrm - the resulting norm 

4496:    Level: intermediate

4498:    Concepts: matrices^norm
4499:    Concepts: norm^of matrix
4500: @*/
4501: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4502: {


4510:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4511:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4512:   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4513:   MatPreallocated(mat);

4515:   (*mat->ops->norm)(mat,type,nrm);
4516:   return(0);
4517: }

4519: /* 
4520:      This variable is used to prevent counting of MatAssemblyBegin() that
4521:    are called from within a MatAssemblyEnd().
4522: */
4523: static PetscInt MatAssemblyEnd_InUse = 0;
4526: /*@
4527:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4528:    be called after completing all calls to MatSetValues().

4530:    Collective on Mat

4532:    Input Parameters:
4533: +  mat - the matrix 
4534: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4535:  
4536:    Notes: 
4537:    MatSetValues() generally caches the values.  The matrix is ready to
4538:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4539:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4540:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4541:    using the matrix.

4543:    Level: beginner

4545:    Concepts: matrices^assembling

4547: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4548: @*/
4549: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4550: {

4556:   MatPreallocated(mat);
4557:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4558:   if (mat->assembled) {
4559:     mat->was_assembled = PETSC_TRUE;
4560:     mat->assembled     = PETSC_FALSE;
4561:   }
4562:   if (!MatAssemblyEnd_InUse) {
4563:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4564:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4565:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4566:   } else {
4567:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4568:   }
4569:   return(0);
4570: }

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

4578:    Collective on Mat

4580:    Input Parameter:
4581: .  mat - the matrix 

4583:    Output Parameter:
4584: .  assembled - PETSC_TRUE or PETSC_FALSE

4586:    Level: advanced

4588:    Concepts: matrices^assembled?

4590: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4591: @*/
4592: PetscErrorCode  MatAssembled(Mat mat,PetscTruth *assembled)
4593: {
4598:   *assembled = mat->assembled;
4599:   return(0);
4600: }

4604: /*
4605:     Processes command line options to determine if/how a matrix
4606:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4607: */
4608: PetscErrorCode MatView_Private(Mat mat)
4609: {
4610:   PetscErrorCode    ierr;
4611:   PetscTruth        flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4612:   static PetscTruth incall = PETSC_FALSE;
4613: #if defined(PETSC_USE_SOCKET_VIEWER)
4614:   PetscTruth        flg5 = PETSC_FALSE;
4615: #endif

4618:   if (incall) return(0);
4619:   incall = PETSC_TRUE;
4620:   PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");
4621:     PetscOptionsTruth("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4622:     PetscOptionsTruth("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4623:     PetscOptionsTruth("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4624:     PetscOptionsTruth("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4625: #if defined(PETSC_USE_SOCKET_VIEWER)
4626:     PetscOptionsTruth("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4627: #endif
4628:     PetscOptionsTruth("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4629:     PetscOptionsTruth("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4630:   PetscOptionsEnd();

4632:   if (flg1) {
4633:     PetscViewer viewer;

4635:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4636:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4637:     MatView(mat,viewer);
4638:     PetscViewerPopFormat(viewer);
4639:   }
4640:   if (flg2) {
4641:     PetscViewer viewer;

4643:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4644:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4645:     MatView(mat,viewer);
4646:     PetscViewerPopFormat(viewer);
4647:   }
4648:   if (flg3) {
4649:     PetscViewer viewer;

4651:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4652:     MatView(mat,viewer);
4653:   }
4654:   if (flg4) {
4655:     PetscViewer viewer;

4657:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4658:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4659:     MatView(mat,viewer);
4660:     PetscViewerPopFormat(viewer);
4661:   }
4662: #if defined(PETSC_USE_SOCKET_VIEWER)
4663:   if (flg5) {
4664:     MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4665:     PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4666:   }
4667: #endif
4668:   if (flg6) {
4669:     MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4670:     PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4671:   }
4672:   if (flg7) {
4673:     PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4674:     if (flg8) {
4675:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4676:     }
4677:     MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4678:     PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4679:     if (flg8) {
4680:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4681:     }
4682:   }
4683:   incall = PETSC_FALSE;
4684:   return(0);
4685: }

4689: /*@
4690:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4691:    be called after MatAssemblyBegin().

4693:    Collective on Mat

4695:    Input Parameters:
4696: +  mat - the matrix 
4697: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4699:    Options Database Keys:
4700: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4701: .  -mat_view_info_detailed - Prints more detailed info
4702: .  -mat_view - Prints matrix in ASCII format
4703: .  -mat_view_matlab - Prints matrix in Matlab format
4704: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4705: .  -display <name> - Sets display name (default is host)
4706: .  -draw_pause <sec> - Sets number of seconds to pause after display
4707: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4708: .  -viewer_socket_machine <machine>
4709: .  -viewer_socket_port <port>
4710: .  -mat_view_binary - save matrix to file in binary format
4711: -  -viewer_binary_filename <name>

4713:    Notes: 
4714:    MatSetValues() generally caches the values.  The matrix is ready to
4715:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4716:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4717:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4718:    using the matrix.

4720:    Level: beginner

4722: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4723: @*/
4724: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4725: {
4726:   PetscErrorCode  ierr;
4727:   static PetscInt inassm = 0;
4728:   PetscTruth      flg = PETSC_FALSE;


4734:   inassm++;
4735:   MatAssemblyEnd_InUse++;
4736:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4737:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4738:     if (mat->ops->assemblyend) {
4739:       (*mat->ops->assemblyend)(mat,type);
4740:     }
4741:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4742:   } else {
4743:     if (mat->ops->assemblyend) {
4744:       (*mat->ops->assemblyend)(mat,type);
4745:     }
4746:   }

4748:   /* Flush assembly is not a true assembly */
4749:   if (type != MAT_FLUSH_ASSEMBLY) {
4750:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4751:   }
4752:   mat->insertmode = NOT_SET_VALUES;
4753:   MatAssemblyEnd_InUse--;
4754:   PetscObjectStateIncrease((PetscObject)mat);
4755:   if (!mat->symmetric_eternal) {
4756:     mat->symmetric_set              = PETSC_FALSE;
4757:     mat->hermitian_set              = PETSC_FALSE;
4758:     mat->structurally_symmetric_set = PETSC_FALSE;
4759:   }
4760:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4761:     MatView_Private(mat);
4762:     PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);
4763:     if (flg) {
4764:       PetscReal tol = 0.0;
4765:       PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4766:       MatIsSymmetric(mat,tol,&flg);
4767:       if (flg) {
4768:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4769:       } else {
4770:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4771:       }
4772:     }
4773:   }
4774:   inassm--;
4775:   return(0);
4776: }

4780: /*@
4781:    MatSetOption - Sets a parameter option for a matrix. Some options
4782:    may be specific to certain storage formats.  Some options
4783:    determine how values will be inserted (or added). Sorted, 
4784:    row-oriented input will generally assemble the fastest. The default
4785:    is row-oriented, nonsorted input. 

4787:    Collective on Mat

4789:    Input Parameters:
4790: +  mat - the matrix 
4791: .  option - the option, one of those listed below (and possibly others),
4792: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

4794:   Options Describing Matrix Structure:
4795: +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4796: .    MAT_HERMITIAN - transpose is the complex conjugation
4797: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4798: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4799:                             you set to be kept with all future use of the matrix
4800:                             including after MatAssemblyBegin/End() which could
4801:                             potentially change the symmetry structure, i.e. you 
4802:                             KNOW the matrix will ALWAYS have the property you set.


4805:    Options For Use with MatSetValues():
4806:    Insert a logically dense subblock, which can be
4807: .    MAT_ROW_ORIENTED - row-oriented (default)

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

4813:    When (re)assembling a matrix, we can restrict the input for
4814:    efficiency/debugging purposes.  These options include
4815: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4816:         allowed if they generate a new nonzero
4817: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4818: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4819: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4820: -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly

4822:    Notes:
4823:    Some options are relevant only for particular matrix types and
4824:    are thus ignored by others.  Other options are not supported by
4825:    certain matrix types and will generate an error message if set.

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

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

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

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

4850:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
4851:    other processors should be dropped, rather than stashed.
4852:    This is useful if you know that the "owning" processor is also 
4853:    always generating the correct matrix entries, so that PETSc need
4854:    not transfer duplicate entries generated on another processor.
4855:    
4856:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4857:    searches during matrix assembly. When this flag is set, the hash table
4858:    is created during the first Matrix Assembly. This hash table is
4859:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4860:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 
4861:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4862:    supported by MATMPIBAIJ format only.

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

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

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

4873:    Level: intermediate

4875:    Concepts: matrices^setting options

4877: @*/
4878: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4879: {

4885:   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4886:   MatPreallocated(mat);
4887:   switch (op) {
4888:   case MAT_SYMMETRIC:
4889:     mat->symmetric                  = flg;
4890:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4891:     mat->symmetric_set              = PETSC_TRUE;
4892:     mat->structurally_symmetric_set = flg;
4893:     break;
4894:   case MAT_HERMITIAN:
4895:     mat->hermitian                  = flg;
4896:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4897:     mat->hermitian_set              = PETSC_TRUE;
4898:     mat->structurally_symmetric_set = flg;
4899:     break;
4900:   case MAT_STRUCTURALLY_SYMMETRIC:
4901:     mat->structurally_symmetric     = flg;
4902:     mat->structurally_symmetric_set = PETSC_TRUE;
4903:     break;
4904:   case MAT_SYMMETRY_ETERNAL:
4905:     mat->symmetric_eternal          = flg;
4906:     break;
4907:   default:
4908:     break;
4909:   }
4910:   if (mat->ops->setoption) {
4911:     (*mat->ops->setoption)(mat,op,flg);
4912:   }
4913:   return(0);
4914: }

4918: /*@
4919:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4920:    this routine retains the old nonzero structure.

4922:    Collective on Mat

4924:    Input Parameters:
4925: .  mat - the matrix 

4927:    Level: intermediate

4929:    Concepts: matrices^zeroing

4931: .seealso: MatZeroRows()
4932: @*/
4933: PetscErrorCode  MatZeroEntries(Mat mat)
4934: {

4940:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4941:   if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled");
4942:   if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4943:   MatPreallocated(mat);

4945:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
4946:   (*mat->ops->zeroentries)(mat);
4947:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
4948:   PetscObjectStateIncrease((PetscObject)mat);
4949:   return(0);
4950: }

4954: /*@C
4955:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4956:    of a set of rows of a matrix.

4958:    Collective on Mat

4960:    Input Parameters:
4961: +  mat - the matrix
4962: .  numRows - the number of rows to remove
4963: .  rows - the global row indices
4964: -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)

4966:    Notes:
4967:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4968:    but does not release memory.  For the dense and block diagonal
4969:    formats this does not alter the nonzero structure.

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

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

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

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

4987:    Level: intermediate

4989:    Concepts: matrices^zeroing rows

4991: .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4992: @*/
4993: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4994: {

5001:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5002:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5003:   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5004:   MatPreallocated(mat);

5006:   (*mat->ops->zerorows)(mat,numRows,rows,diag);
5007:   MatView_Private(mat);
5008:   PetscObjectStateIncrease((PetscObject)mat);
5009:   return(0);
5010: }

5014: /*@C
5015:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5016:    of a set of rows of a matrix.

5018:    Collective on Mat

5020:    Input Parameters:
5021: +  mat - the matrix
5022: .  is - index set of rows to remove
5023: -  diag - value put in all diagonals of eliminated rows

5025:    Notes:
5026:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5027:    but does not release memory.  For the dense and block diagonal
5028:    formats this does not alter the nonzero structure.

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

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

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

5043:    Each processor should list the rows that IT wants zeroed

5045:    Level: intermediate

5047:    Concepts: matrices^zeroing rows

5049: .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5050: @*/
5051: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
5052: {
5053:   PetscInt       numRows;
5054:   const PetscInt *rows;

5061:   ISGetLocalSize(is,&numRows);
5062:   ISGetIndices(is,&rows);
5063:   MatZeroRows(mat,numRows,rows,diag);
5064:   ISRestoreIndices(is,&rows);
5065:   return(0);
5066: }

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

5074:    Collective on Mat

5076:    Input Parameters:
5077: +  mat - the matrix
5078: .  numRows - the number of rows to remove
5079: .  rows - the global row indices
5080: -  diag - value put in all diagonals of eliminated rows

5082:    Notes:
5083:    Before calling MatZeroRowsLocal(), the user must first set the
5084:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5086:    For the AIJ matrix formats this removes the old nonzero structure,
5087:    but does not release memory.  For the dense and block diagonal
5088:    formats this does not alter the nonzero structure.

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

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

5098:    Level: intermediate

5100:    Concepts: matrices^zeroing

5102: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5103: @*/
5104: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
5105: {

5112:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5113:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5114:   MatPreallocated(mat);

5116:   if (mat->ops->zerorowslocal) {
5117:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);
5118:   } else {
5119:     IS             is, newis;
5120:     const PetscInt *newRows;

5122:     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5123:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);
5124:     ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
5125:     ISGetIndices(newis,&newRows);
5126:     (*mat->ops->zerorows)(mat,numRows,newRows,diag);
5127:     ISRestoreIndices(newis,&newRows);
5128:     ISDestroy(newis);
5129:     ISDestroy(is);
5130:   }
5131:   PetscObjectStateIncrease((PetscObject)mat);
5132:   return(0);
5133: }

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

5141:    Collective on Mat

5143:    Input Parameters:
5144: +  mat - the matrix
5145: .  is - index set of rows to remove
5146: -  diag - value put in all diagonals of eliminated rows

5148:    Notes:
5149:    Before calling MatZeroRowsLocalIS(), the user must first set the
5150:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5152:    For the AIJ matrix formats this removes the old nonzero structure,
5153:    but does not release memory.  For the dense and block diagonal
5154:    formats this does not alter the nonzero structure.

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

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

5164:    Level: intermediate

5166:    Concepts: matrices^zeroing

5168: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5169: @*/
5170: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5171: {
5173:   PetscInt       numRows;
5174:   const PetscInt *rows;

5180:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5181:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5182:   MatPreallocated(mat);

5184:   ISGetLocalSize(is,&numRows);
5185:   ISGetIndices(is,&rows);
5186:   MatZeroRowsLocal(mat,numRows,rows,diag);
5187:   ISRestoreIndices(is,&rows);
5188:   return(0);
5189: }

5193: /*@
5194:    MatGetSize - Returns the numbers of rows and columns in a matrix.

5196:    Not Collective

5198:    Input Parameter:
5199: .  mat - the matrix

5201:    Output Parameters:
5202: +  m - the number of global rows
5203: -  n - the number of global columns

5205:    Note: both output parameters can be PETSC_NULL on input.

5207:    Level: beginner

5209:    Concepts: matrices^size

5211: .seealso: MatGetLocalSize()
5212: @*/
5213: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5214: {
5217:   if (m) *m = mat->rmap->N;
5218:   if (n) *n = mat->cmap->N;
5219:   return(0);
5220: }

5224: /*@
5225:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5226:    stored locally.  This information may be implementation dependent, so
5227:    use with care.

5229:    Not Collective

5231:    Input Parameters:
5232: .  mat - the matrix

5234:    Output Parameters:
5235: +  m - the number of local rows
5236: -  n - the number of local columns

5238:    Note: both output parameters can be PETSC_NULL on input.

5240:    Level: beginner

5242:    Concepts: matrices^local size

5244: .seealso: MatGetSize()
5245: @*/
5246: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5247: {
5252:   if (m) *m = mat->rmap->n;
5253:   if (n) *n = mat->cmap->n;
5254:   return(0);
5255: }

5259: /*@
5260:    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5261:    this processor.

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

5265:    Input Parameters:
5266: .  mat - the matrix

5268:    Output Parameters:
5269: +  m - the global index of the first local column
5270: -  n - one more than the global index of the last local column

5272:    Notes: both output parameters can be PETSC_NULL on input.

5274:    Level: developer

5276:    Concepts: matrices^column ownership

5278: .seealso:  MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()

5280: @*/
5281: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5282: {

5290:   MatPreallocated(mat);
5291:   if (m) *m = mat->cmap->rstart;
5292:   if (n) *n = mat->cmap->rend;
5293:   return(0);
5294: }

5298: /*@
5299:    MatGetOwnershipRange - Returns the range of matrix rows owned by
5300:    this processor, assuming that the matrix is laid out with the first
5301:    n1 rows on the first processor, the next n2 rows on the second, etc.
5302:    For certain parallel layouts this range may not be well defined.

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

5306:    Input Parameters:
5307: .  mat - the matrix

5309:    Output Parameters:
5310: +  m - the global index of the first local row
5311: -  n - one more than the global index of the last local row

5313:    Note: both output parameters can be PETSC_NULL on input.

5315:    Level: beginner

5317:    Concepts: matrices^row ownership

5319: .seealso:   MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()

5321: @*/
5322: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5323: {

5331:   MatPreallocated(mat);
5332:   if (m) *m = mat->rmap->rstart;
5333:   if (n) *n = mat->rmap->rend;
5334:   return(0);
5335: }

5339: /*@C
5340:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5341:    each process

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

5345:    Input Parameters:
5346: .  mat - the matrix

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

5351:    Level: beginner

5353:    Concepts: matrices^row ownership

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

5357: @*/
5358: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5359: {

5365:   MatPreallocated(mat);
5366:   PetscLayoutGetRanges(mat->rmap,ranges);
5367:   return(0);
5368: }

5372: /*@C
5373:    MatGetOwnershipRangesColumn - Returns the range of local columns for each process

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

5377:    Input Parameters:
5378: .  mat - the matrix

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

5383:    Level: beginner

5385:    Concepts: matrices^column ownership

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

5389: @*/
5390: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5391: {

5397:   MatPreallocated(mat);
5398:   PetscLayoutGetRanges(mat->cmap,ranges);
5399:   return(0);
5400: }

5404: /*@C
5405:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5406:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
5407:    to complete the factorization.

5409:    Collective on Mat

5411:    Input Parameters:
5412: +  mat - the matrix
5413: .  row - row permutation
5414: .  column - column permutation
5415: -  info - structure containing 
5416: $      levels - number of levels of fill.
5417: $      expected fill - as ratio of original fill.
5418: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5419:                 missing diagonal entries)

5421:    Output Parameters:
5422: .  fact - new matrix that has been symbolically factored

5424:    Notes:
5425:    See the users manual for additional information about
5426:    choosing the fill factor for better efficiency.

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

5432:    Level: developer

5434:   Concepts: matrices^symbolic LU factorization
5435:   Concepts: matrices^factorization
5436:   Concepts: LU^symbolic factorization

5438: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5439:           MatGetOrdering(), MatFactorInfo

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

5444: @*/
5445: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5446: {

5456:   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
5457:   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5458:   if (!(fact)->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ILU",((PetscObject)mat)->type_name);
5459:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5460:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5461:   MatPreallocated(mat);

5463:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
5464:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
5465:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
5466:   return(0);
5467: }

5471: /*@C
5472:    MatICCFactorSymbolic - Performs symbolic incomplete
5473:    Cholesky factorization for a symmetric matrix.  Use 
5474:    MatCholeskyFactorNumeric() to complete the factorization.

5476:    Collective on Mat

5478:    Input Parameters:
5479: +  mat - the matrix
5480: .  perm - row and column permutation
5481: -  info - structure containing 
5482: $      levels - number of levels of fill.
5483: $      expected fill - as ratio of original fill.

5485:    Output Parameter:
5486: .  fact - the factored matrix

5488:    Notes:
5489:    Most users should employ the KSP interface for linear solvers
5490:    instead of working directly with matrix algebra routines such as this.
5491:    See, e.g., KSPCreate().

5493:    Level: developer

5495:   Concepts: matrices^symbolic incomplete Cholesky factorization
5496:   Concepts: matrices^factorization
5497:   Concepts: Cholsky^symbolic factorization

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

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

5504: @*/
5505: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5506: {

5515:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5516:   if (info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
5517:   if (info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
5518:   if (!(fact)->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s  symbolic ICC",((PetscObject)mat)->type_name);
5519:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5520:   MatPreallocated(mat);

5522:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
5523:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
5524:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
5525:   return(0);
5526: }

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

5536:    Not Collective

5538:    Input Parameter:
5539: .  mat - the matrix

5541:    Output Parameter:
5542: .  v - the location of the values


5545:    Fortran Note:
5546:    This routine is used differently from Fortran, e.g.,
5547: .vb
5548:         Mat         mat
5549:         PetscScalar mat_array(1)
5550:         PetscOffset i_mat
5551:         PetscErrorCode ierr
5552:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5558:         [... other code ...]
5559:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5560: .ve

5562:    See the Fortran chapter of the users manual and 
5563:    petsc/src/mat/examples/tests for details.

5565:    Level: advanced

5567:    Concepts: matrices^access array

5569: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5570: @*/
5571: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
5572: {

5579:   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5580:   MatPreallocated(mat);
5581:   (*mat->ops->getarray)(mat,v);
5582:   CHKMEMQ;
5583:   return(0);
5584: }

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

5591:    Not Collective

5593:    Input Parameter:
5594: +  mat - the matrix
5595: -  v - the location of the values

5597:    Fortran Note:
5598:    This routine is used differently from Fortran, e.g.,
5599: .vb
5600:         Mat         mat
5601:         PetscScalar mat_array(1)
5602:         PetscOffset i_mat
5603:         PetscErrorCode ierr
5604:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5610:         [... other code ...]
5611:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5612: .ve

5614:    See the Fortran chapter of the users manual and 
5615:    petsc/src/mat/examples/tests for details

5617:    Level: advanced

5619: .seealso: MatGetArray(), MatRestoreArrayF90()
5620: @*/
5621: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
5622: {

5629: #if defined(PETSC_USE_DEBUG)
5630:   CHKMEMQ;
5631: #endif
5632:   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5633:   (*mat->ops->restorearray)(mat,v);
5634:   PetscObjectStateIncrease((PetscObject)mat);
5635:   return(0);
5636: }

5640: /*@C
5641:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5642:    points to an array of valid matrices, they may be reused to store the new
5643:    submatrices.

5645:    Collective on Mat

5647:    Input Parameters:
5648: +  mat - the matrix
5649: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5650: .  irow, icol - index sets of rows and columns to extract
5651: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

5653:    Output Parameter:
5654: .  submat - the array of submatrices

5656:    Notes:
5657:    MatGetSubMatrices() can extract ONLY sequential submatrices
5658:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5659:    to extract a parallel submatrix.

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

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

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

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

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

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

5683:    Level: advanced

5685:    Concepts: matrices^accessing submatrices
5686:    Concepts: submatrices

5688: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5689: @*/
5690: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5691: {
5693:   PetscInt        i;
5694:   PetscTruth      eq;

5699:   if (n) {
5704:   }
5706:   if (n && scall == MAT_REUSE_MATRIX) {
5709:   }
5710:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5711:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5712:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5713:   MatPreallocated(mat);

5715:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
5716:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
5717:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
5718:   for (i=0; i<n; i++) {
5719:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5720:       ISEqual(irow[i],icol[i],&eq);
5721:       if (eq) {
5722:         if (mat->symmetric){
5723:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
5724:         } else if (mat->hermitian) {
5725:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
5726:         } else if (mat->structurally_symmetric) {
5727:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
5728:         }
5729:       }
5730:     }
5731:   }
5732:   return(0);
5733: }

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

5740:    Collective on Mat

5742:    Input Parameters:
5743: +  n - the number of local matrices
5744: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5745:                        sequence of MatGetSubMatrices())

5747:    Level: advanced

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

5752: .seealso: MatGetSubMatrices()
5753: @*/
5754: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
5755: {
5757:   PetscInt       i;

5760:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5762:   for (i=0; i<n; i++) {
5763:     MatDestroy((*mat)[i]);
5764:   }
5765:   /* memory is allocated even if n = 0 */
5766:   PetscFree(*mat);
5767:   return(0);
5768: }

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

5775:    Collective on Mat

5777:    Input Parameters:
5778: .  mat - the matrix

5780:    Output Parameter:
5781: .  matstruct - the sequential matrix with the nonzero structure of mat

5783:   Level: intermediate

5785: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5786: @*/
5787: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
5788: {

5794: 
5796:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5797:   MatPreallocated(mat);

5799:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
5800:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5801:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5802:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5803:   return(0);
5804: }

5808: /*@C
5809:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

5811:    Collective on Mat

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

5817:    Level: advanced

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

5821: .seealso: MatGetSeqNonzeroStructure()
5822: @*/
5823: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
5824: {

5829:   MatDestroy(*mat);
5830:   return(0);
5831: }

5835: /*@
5836:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5837:    replaces the index sets by larger ones that represent submatrices with
5838:    additional overlap.

5840:    Collective on Mat

5842:    Input Parameters:
5843: +  mat - the matrix
5844: .  n   - the number of index sets
5845: .  is  - the array of index sets (these index sets will changed during the call)
5846: -  ov  - the additional overlap requested

5848:    Level: developer

5850:    Concepts: overlap
5851:    Concepts: ASM^computing overlap

5853: .seealso: MatGetSubMatrices()
5854: @*/
5855: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5856: {

5862:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5863:   if (n) {
5866:   }
5867:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5868:   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5869:   MatPreallocated(mat);

5871:   if (!ov) return(0);
5872:   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5873:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5874:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
5875:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5876:   return(0);
5877: }

5881: /*@
5882:    MatGetBlockSize - Returns the matrix block size; useful especially for the
5883:    block row and block diagonal formats.
5884:    
5885:    Not Collective

5887:    Input Parameter:
5888: .  mat - the matrix

5890:    Output Parameter:
5891: .  bs - block size

5893:    Notes:
5894:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

5896:    Level: intermediate

5898:    Concepts: matrices^block size

5900: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5901: @*/
5902: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
5903: {

5910:   MatPreallocated(mat);
5911:   *bs = mat->rmap->bs;
5912:   return(0);
5913: }

5917: /*@
5918:    MatSetBlockSize - Sets the matrix block size; for many matrix types you 
5919:      cannot use this and MUST set the blocksize when you preallocate the matrix
5920:    
5921:    Collective on Mat

5923:    Input Parameters:
5924: +  mat - the matrix
5925: -  bs - block size

5927:    Notes:
5928:      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
5929:      it is not possible to change BAIJ block sizes after preallocation.

5931:    Level: intermediate

5933:    Concepts: matrices^block size

5935: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5936: @*/
5937: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
5938: {

5944:   MatPreallocated(mat);
5945:   if (bs < 1) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Block size %d, must be positive",bs);
5946:   if (mat->ops->setblocksize) {
5947:     (*mat->ops->setblocksize)(mat,bs);
5948:   } else {
5949:     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5950:   }
5951:   return(0);
5952: }

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

5959:    Collective on Mat

5961:     Input Parameters:
5962: +   mat - the matrix
5963: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5964: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5965:                 symmetrized
5966: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5967:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
5968:                  always used.

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

5977:     Level: developer

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

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

5983:     Fortran Node

5985:            In Fortran use
5986: $           PetscInt ia(1), ja(1)
5987: $           PetscOffset iia, jja
5988: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
5989: $
5990: $          or 
5991: $
5992: $           PetscScalar, pointer :: xx_v(:)
5993: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
5994:   
5995:  
5996:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

5998: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5999: @*/
6000: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6001: {

6011:   MatPreallocated(mat);
6012:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6013:   else {
6014:     *done = PETSC_TRUE;
6015:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6016:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6017:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6018:   }
6019:   return(0);
6020: }

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

6027:     Collective on Mat

6029:     Input Parameters:
6030: +   mat - the matrix
6031: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6032: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6033:                 symmetrized
6034: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6035:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6036:                  always used.

6038:     Output Parameters:
6039: +   n - number of columns in the (possibly compressed) matrix
6040: .   ia - the column pointers
6041: .   ja - the row indices
6042: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6044:     Level: developer

6046: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6047: @*/
6048: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6049: {

6059:   MatPreallocated(mat);
6060:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6061:   else {
6062:     *done = PETSC_TRUE;
6063:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6064:   }
6065:   return(0);
6066: }

6070: /*@C
6071:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6072:     MatGetRowIJ().

6074:     Collective on Mat

6076:     Input Parameters:
6077: +   mat - the matrix
6078: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6079: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6080:                 symmetrized
6081: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6082:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6083:                  always used.

6085:     Output Parameters:
6086: +   n - size of (possibly compressed) matrix
6087: .   ia - the row pointers
6088: .   ja - the column indices
6089: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6091:     Level: developer

6093: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6094: @*/
6095: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6096: {

6105:   MatPreallocated(mat);

6107:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6108:   else {
6109:     *done = PETSC_TRUE;
6110:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6111:   }
6112:   return(0);
6113: }

6117: /*@C
6118:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6119:     MatGetColumnIJ().

6121:     Collective on Mat

6123:     Input Parameters:
6124: +   mat - the matrix
6125: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6126: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6127:                 symmetrized
6128: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6129:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6130:                  always used.

6132:     Output Parameters:
6133: +   n - size of (possibly compressed) matrix
6134: .   ia - the column pointers
6135: .   ja - the row indices
6136: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6138:     Level: developer

6140: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6141: @*/
6142: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6143: {

6152:   MatPreallocated(mat);

6154:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6155:   else {
6156:     *done = PETSC_TRUE;
6157:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6158:   }
6159:   return(0);
6160: }

6164: /*@C
6165:     MatColoringPatch -Used inside matrix coloring routines that 
6166:     use MatGetRowIJ() and/or MatGetColumnIJ().

6168:     Collective on Mat

6170:     Input Parameters:
6171: +   mat - the matrix
6172: .   ncolors - max color value
6173: .   n   - number of entries in colorarray
6174: -   colorarray - array indicating color for each column

6176:     Output Parameters:
6177: .   iscoloring - coloring generated using colorarray information

6179:     Level: developer

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

6183: @*/
6184: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6185: {

6193:   MatPreallocated(mat);

6195:   if (!mat->ops->coloringpatch){
6196:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6197:   } else {
6198:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6199:   }
6200:   return(0);
6201: }


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

6209:    Collective on Mat

6211:    Input Parameter:
6212: .  mat - the factored matrix to be reset

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

6221:    Note that one can specify in-place ILU(0) factorization by calling 
6222: .vb
6223:      PCType(pc,PCILU);
6224:      PCFactorSeUseInPlace(pc);
6225: .ve
6226:    or by using the options -pc_type ilu -pc_factor_in_place

6228:    In-place factorization ILU(0) can also be used as a local
6229:    solver for the blocks within the block Jacobi or additive Schwarz
6230:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion 
6231:    of these preconditioners in the users manual for details on setting
6232:    local solver options.

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

6238:    Level: developer

6240: .seealso: PCFactorSetUseInPlace()

6242:    Concepts: matrices^unfactored

6244: @*/
6245: PetscErrorCode  MatSetUnfactored(Mat mat)
6246: {

6252:   MatPreallocated(mat);
6253:   mat->factor = MAT_FACTOR_NONE;
6254:   if (!mat->ops->setunfactored) return(0);
6255:   (*mat->ops->setunfactored)(mat);
6256:   return(0);
6257: }

6259: /*MC
6260:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

6262:     Synopsis:
6263:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6265:     Not collective

6267:     Input Parameter:
6268: .   x - matrix

6270:     Output Parameters:
6271: +   xx_v - the Fortran90 pointer to the array
6272: -   ierr - error code

6274:     Example of Usage: 
6275: .vb
6276:       PetscScalar, pointer xx_v(:)
6277:       ....
6278:       call MatGetArrayF90(x,xx_v,ierr)
6279:       a = xx_v(3)
6280:       call MatRestoreArrayF90(x,xx_v,ierr)
6281: .ve

6283:     Notes:
6284:     Not yet supported for all F90 compilers

6286:     Level: advanced

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

6290:     Concepts: matrices^accessing array

6292: M*/

6294: /*MC
6295:     MatRestoreArrayF90 - Restores a matrix array that has been
6296:     accessed with MatGetArrayF90().

6298:     Synopsis:
6299:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6301:     Not collective

6303:     Input Parameters:
6304: +   x - matrix
6305: -   xx_v - the Fortran90 pointer to the array

6307:     Output Parameter:
6308: .   ierr - error code

6310:     Example of Usage: 
6311: .vb
6312:        PetscScalar, pointer xx_v(:)
6313:        ....
6314:        call MatGetArrayF90(x,xx_v,ierr)
6315:        a = xx_v(3)
6316:        call MatRestoreArrayF90(x,xx_v,ierr)
6317: .ve
6318:    
6319:     Notes:
6320:     Not yet supported for all F90 compilers

6322:     Level: advanced

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

6326: M*/


6331: /*@
6332:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6333:                       as the original matrix.

6335:     Collective on Mat

6337:     Input Parameters:
6338: +   mat - the original matrix
6339: .   isrow - parallel IS containing the rows this processor should obtain
6340: .   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.
6341: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6343:     Output Parameter:
6344: .   newmat - the new submatrix, of the same type as the old

6346:     Level: advanced

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

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

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

6359:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6360:     the input matrix.

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

6364:    Example usage:
6365:    Consider the following 8x8 matrix with 34 non-zero values, that is
6366:    assembled across 3 processors. Lets assume that proc0 owns 3 rows,
6367:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6368:    as follows:

6370: .vb
6371:             1  2  0  |  0  3  0  |  0  4
6372:     Proc0   0  5  6  |  7  0  0  |  8  0
6373:             9  0 10  | 11  0  0  | 12  0
6374:     -------------------------------------
6375:            13  0 14  | 15 16 17  |  0  0
6376:     Proc1   0 18  0  | 19 20 21  |  0  0
6377:             0  0  0  | 22 23  0  | 24  0
6378:     -------------------------------------
6379:     Proc2  25 26 27  |  0  0 28  | 29  0
6380:            30  0  0  | 31 32 33  |  0 34
6381: .ve

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

6385: .vb
6386:             2  0  |  0  3  0  |  0
6387:     Proc0   5  6  |  7  0  0  |  8
6388:     -------------------------------
6389:     Proc1  18  0  | 19 20 21  |  0
6390:     -------------------------------
6391:     Proc2  26 27  |  0  0 28  | 29
6392:             0  0  | 31 32 33  |  0
6393: .ve


6396:     Concepts: matrices^submatrices

6398: .seealso: MatGetSubMatrices()
6399: @*/
6400: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
6401: {
6403:   PetscMPIInt    size;
6404:   Mat            *local;
6405:   IS             iscoltmp;

6414:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6415:   MatPreallocated(mat);
6416:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

6418:   if (!iscol) {
6419:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
6420:   } else {
6421:     iscoltmp = iscol;
6422:   }

6424:   /* if original matrix is on just one processor then use submatrix generated */
6425:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6426:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6427:     if (!iscol) {ISDestroy(iscoltmp);}
6428:     return(0);
6429:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
6430:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6431:     *newmat = *local;
6432:     PetscFree(local);
6433:     if (!iscol) {ISDestroy(iscoltmp);}
6434:     return(0);
6435:   } else if (!mat->ops->getsubmatrix) {
6436:     /* Create a new matrix type that implements the operation using the full matrix */
6437:     switch (cll) {
6438:       case MAT_INITIAL_MATRIX:
6439:         MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
6440:         break;
6441:       case MAT_REUSE_MATRIX:
6442:         MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
6443:         break;
6444:       default: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
6445:     }
6446:     if (!iscol) {ISDestroy(iscoltmp);}
6447:     return(0);
6448:   }

6450:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6451:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
6452:   if (!iscol) {ISDestroy(iscoltmp);}
6453:   PetscObjectStateIncrease((PetscObject)*newmat);
6454:   return(0);
6455: }

6459: /*@
6460:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6461:    used during the assembly process to store values that belong to 
6462:    other processors.

6464:    Not Collective

6466:    Input Parameters:
6467: +  mat   - the matrix
6468: .  size  - the initial size of the stash.
6469: -  bsize - the initial size of the block-stash(if used).

6471:    Options Database Keys:
6472: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6473: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

6475:    Level: intermediate

6477:    Notes: 
6478:      The block-stash is used for values set with MatSetValuesBlocked() while
6479:      the stash is used for values set with MatSetValues()

6481:      Run with the option -info and look for output of the form
6482:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6483:      to determine the appropriate value, MM, to use for size and 
6484:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6485:      to determine the value, BMM to use for bsize

6487:    Concepts: stash^setting matrix size
6488:    Concepts: matrices^stash

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

6492: @*/
6493: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6494: {

6500:   MatStashSetInitialSize_Private(&mat->stash,size);
6501:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
6502:   return(0);
6503: }

6507: /*@
6508:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
6509:      the matrix

6511:    Collective on Mat

6513:    Input Parameters:
6514: +  mat   - the matrix
6515: .  x,y - the vectors
6516: -  w - where the result is stored

6518:    Level: intermediate

6520:    Notes: 
6521:     w may be the same vector as y. 

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

6526:     Concepts: interpolation

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

6530: @*/
6531: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6532: {
6534:   PetscInt       M,N;

6542:   MatPreallocated(A);
6543:   MatGetSize(A,&M,&N);
6544:   if (N > M) {
6545:     MatMultTransposeAdd(A,x,y,w);
6546:   } else {
6547:     MatMultAdd(A,x,y,w);
6548:   }
6549:   return(0);
6550: }

6554: /*@
6555:    MatInterpolate - y = A*x or A'*x depending on the shape of 
6556:      the matrix

6558:    Collective on Mat

6560:    Input Parameters:
6561: +  mat   - the matrix
6562: -  x,y - the vectors

6564:    Level: intermediate

6566:    Notes: 
6567:     This allows one to use either the restriction or interpolation (its transpose)
6568:     matrix to do the interpolation

6570:    Concepts: matrices^interpolation

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

6574: @*/
6575: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
6576: {
6578:   PetscInt       M,N;

6585:   MatPreallocated(A);
6586:   MatGetSize(A,&M,&N);
6587:   if (N > M) {
6588:     MatMultTranspose(A,x,y);
6589:   } else {
6590:     MatMult(A,x,y);
6591:   }
6592:   return(0);
6593: }

6597: /*@
6598:    MatRestrict - y = A*x or A'*x

6600:    Collective on Mat

6602:    Input Parameters:
6603: +  mat   - the matrix
6604: -  x,y - the vectors

6606:    Level: intermediate

6608:    Notes: 
6609:     This allows one to use either the restriction or interpolation (its transpose)
6610:     matrix to do the restriction

6612:    Concepts: matrices^restriction

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

6616: @*/
6617: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
6618: {
6620:   PetscInt       M,N;

6627:   MatPreallocated(A);

6629:   MatGetSize(A,&M,&N);
6630:   if (N > M) {
6631:     MatMult(A,x,y);
6632:   } else {
6633:     MatMultTranspose(A,x,y);
6634:   }
6635:   return(0);
6636: }

6640: /*@
6641:    MatNullSpaceAttach - attaches a null space to a matrix.
6642:         This null space will be removed from the resulting vector whenever
6643:         MatMult() is called

6645:    Collective on Mat

6647:    Input Parameters:
6648: +  mat - the matrix
6649: -  nullsp - the null space object

6651:    Level: developer

6653:    Notes:
6654:       Overwrites any previous null space that may have been attached

6656:    Concepts: null space^attaching to matrix

6658: .seealso: MatCreate(), MatNullSpaceCreate()
6659: @*/
6660: PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6661: {

6668:   MatPreallocated(mat);
6669:   PetscObjectReference((PetscObject)nullsp);
6670:   if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6671:   mat->nullsp = nullsp;
6672:   return(0);
6673: }

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

6680:    Collective on Mat

6682:    Input Parameters:
6683: +  mat - the matrix
6684: .  row - row/column permutation
6685: .  fill - expected fill factor >= 1.0
6686: -  level - level of fill, for ICC(k)

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

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

6696:    Level: developer

6698:    Concepts: matrices^incomplete Cholesky factorization
6699:    Concepts: Cholesky factorization

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

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

6706: @*/
6707: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6708: {

6716:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6717:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6718:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6719:   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6720:   MatPreallocated(mat);
6721:   (*mat->ops->iccfactor)(mat,row,info);
6722:   PetscObjectStateIncrease((PetscObject)mat);
6723:   return(0);
6724: }

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

6731:    Not Collective

6733:    Input Parameters:
6734: +  mat - the matrix
6735: -  v - the values compute with ADIC

6737:    Level: developer

6739:    Notes:
6740:      Must call MatSetColoring() before using this routine. Also this matrix must already
6741:      have its nonzero pattern determined.

6743: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6744:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6745: @*/
6746: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
6747: {


6755:   if (!mat->assembled) {
6756:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6757:   }
6758:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6759:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6760:   (*mat->ops->setvaluesadic)(mat,v);
6761:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6762:   MatView_Private(mat);
6763:   PetscObjectStateIncrease((PetscObject)mat);
6764:   return(0);
6765: }


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

6773:    Not Collective

6775:    Input Parameters:
6776: +  mat - the matrix
6777: -  coloring - the coloring

6779:    Level: developer

6781: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6782:           MatSetValues(), MatSetValuesAdic()
6783: @*/
6784: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
6785: {


6793:   if (!mat->assembled) {
6794:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6795:   }
6796:   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6797:   (*mat->ops->setcoloring)(mat,coloring);
6798:   return(0);
6799: }

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

6806:    Not Collective

6808:    Input Parameters:
6809: +  mat - the matrix
6810: .  nl - leading dimension of v
6811: -  v - the values compute with ADIFOR

6813:    Level: developer

6815:    Notes:
6816:      Must call MatSetColoring() before using this routine. Also this matrix must already
6817:      have its nonzero pattern determined.

6819: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6820:           MatSetValues(), MatSetColoring()
6821: @*/
6822: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6823: {


6831:   if (!mat->assembled) {
6832:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6833:   }
6834:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6835:   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6836:   (*mat->ops->setvaluesadifor)(mat,nl,v);
6837:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6838:   PetscObjectStateIncrease((PetscObject)mat);
6839:   return(0);
6840: }

6844: /*@ 
6845:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
6846:          ghosted ones.

6848:    Not Collective

6850:    Input Parameters:
6851: +  mat - the matrix
6852: -  diag = the diagonal values, including ghost ones

6854:    Level: developer

6856:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6857:       
6858: .seealso: MatDiagonalScale()
6859: @*/
6860: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
6861: {
6863:   PetscMPIInt    size;


6870:   if (!mat->assembled) {
6871:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6872:   }
6873:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6874:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
6875:   if (size == 1) {
6876:     PetscInt n,m;
6877:     VecGetSize(diag,&n);
6878:     MatGetSize(mat,0,&m);
6879:     if (m == n) {
6880:       MatDiagonalScale(mat,0,diag);
6881:     } else {
6882:       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6883:     }
6884:   } else {
6885:     PetscErrorCode (*f)(Mat,Vec);
6886:     PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6887:     if (f) {
6888:       (*f)(mat,diag);
6889:     } else {
6890:       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6891:     }
6892:   }
6893:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6894:   PetscObjectStateIncrease((PetscObject)mat);
6895:   return(0);
6896: }

6900: /*@ 
6901:    MatGetInertia - Gets the inertia from a factored matrix

6903:    Collective on Mat

6905:    Input Parameter:
6906: .  mat - the matrix

6908:    Output Parameters:
6909: +   nneg - number of negative eigenvalues
6910: .   nzero - number of zero eigenvalues
6911: -   npos - number of positive eigenvalues

6913:    Level: advanced

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


6918: @*/
6919: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6920: {

6926:   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6927:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6928:   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6929:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6930:   return(0);
6931: }

6933: /* ----------------------------------------------------------------*/
6936: /*@C
6937:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

6939:    Collective on Mat and Vecs

6941:    Input Parameters:
6942: +  mat - the factored matrix
6943: -  b - the right-hand-side vectors

6945:    Output Parameter:
6946: .  x - the result vectors

6948:    Notes:
6949:    The vectors b and x cannot be the same.  I.e., one cannot
6950:    call MatSolves(A,x,x).

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

6957:    Level: developer

6959:    Concepts: matrices^triangular solves

6961: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6962: @*/
6963: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
6964: {

6970:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6971:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6972:   if (!mat->rmap->N && !mat->cmap->N) return(0);

6974:   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6975:   MatPreallocated(mat);
6976:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6977:   (*mat->ops->solves)(mat,b,x);
6978:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6979:   return(0);
6980: }

6984: /*@
6985:    MatIsSymmetric - Test whether a matrix is symmetric

6987:    Collective on Mat

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

6993:    Output Parameters:
6994: .  flg - the result

6996:    Level: intermediate

6998:    Concepts: matrix^symmetry

7000: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7001: @*/
7002: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
7003: {


7010:   if (!A->symmetric_set) {
7011:     if (!A->ops->issymmetric) {
7012:       const MatType mattype;
7013:       MatGetType(A,&mattype);
7014:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7015:     }
7016:     (*A->ops->issymmetric)(A,tol,flg);
7017:     if (!tol) {
7018:       A->symmetric_set = PETSC_TRUE;
7019:       A->symmetric = *flg;
7020:       if (A->symmetric) {
7021:         A->structurally_symmetric_set = PETSC_TRUE;
7022:         A->structurally_symmetric     = PETSC_TRUE;
7023:       }
7024:     }
7025:   } else if (A->symmetric) {
7026:     *flg = PETSC_TRUE;
7027:   } else if (!tol) {
7028:     *flg = PETSC_FALSE;
7029:   } else {
7030:     if (!A->ops->issymmetric) {
7031:       const MatType mattype;
7032:       MatGetType(A,&mattype);
7033:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7034:     }
7035:     (*A->ops->issymmetric)(A,tol,flg);
7036:   }
7037:   return(0);
7038: }

7042: /*@
7043:    MatIsHermitian - Test whether a matrix is Hermitian

7045:    Collective on Mat

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

7051:    Output Parameters:
7052: .  flg - the result

7054:    Level: intermediate

7056:    Concepts: matrix^symmetry

7058: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7059: @*/
7060: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
7061: {


7068:   if (!A->hermitian_set) {
7069:     if (!A->ops->ishermitian) {
7070:       const MatType mattype;
7071:       MatGetType(A,&mattype);
7072:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7073:     }
7074:     (*A->ops->ishermitian)(A,tol,flg);
7075:     if (!tol) {
7076:       A->hermitian_set = PETSC_TRUE;
7077:       A->hermitian = *flg;
7078:       if (A->hermitian) {
7079:         A->structurally_symmetric_set = PETSC_TRUE;
7080:         A->structurally_symmetric     = PETSC_TRUE;
7081:       }
7082:     }
7083:   } else if (A->hermitian) {
7084:     *flg = PETSC_TRUE;
7085:   } else if (!tol) {
7086:     *flg = PETSC_FALSE;
7087:   } else {
7088:     if (!A->ops->ishermitian) {
7089:       const MatType mattype;
7090:       MatGetType(A,&mattype);
7091:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7092:     }
7093:     (*A->ops->ishermitian)(A,tol,flg);
7094:   }
7095:   return(0);
7096: }

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

7103:    Collective on Mat

7105:    Input Parameter:
7106: .  A - the matrix to check

7108:    Output Parameters:
7109: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7110: -  flg - the result

7112:    Level: advanced

7114:    Concepts: matrix^symmetry

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

7119: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7120: @*/
7121: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7122: {
7127:   if (A->symmetric_set) {
7128:     *set = PETSC_TRUE;
7129:     *flg = A->symmetric;
7130:   } else {
7131:     *set = PETSC_FALSE;
7132:   }
7133:   return(0);
7134: }

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

7141:    Collective on Mat

7143:    Input Parameter:
7144: .  A - the matrix to check

7146:    Output Parameters:
7147: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7148: -  flg - the result

7150:    Level: advanced

7152:    Concepts: matrix^symmetry

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

7157: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7158: @*/
7159: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7160: {
7165:   if (A->hermitian_set) {
7166:     *set = PETSC_TRUE;
7167:     *flg = A->hermitian;
7168:   } else {
7169:     *set = PETSC_FALSE;
7170:   }
7171:   return(0);
7172: }

7176: /*@
7177:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

7179:    Collective on Mat

7181:    Input Parameter:
7182: .  A - the matrix to test

7184:    Output Parameters:
7185: .  flg - the result

7187:    Level: intermediate

7189:    Concepts: matrix^symmetry

7191: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7192: @*/
7193: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7194: {

7200:   if (!A->structurally_symmetric_set) {
7201:     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7202:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7203:     A->structurally_symmetric_set = PETSC_TRUE;
7204:   }
7205:   *flg = A->structurally_symmetric;
7206:   return(0);
7207: }

7212: /*@ 
7213:    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7214:        to be communicated to other processors during the MatAssemblyBegin/End() process

7216:     Not collective

7218:    Input Parameter:
7219: .   vec - the vector

7221:    Output Parameters:
7222: +   nstash   - the size of the stash
7223: .   reallocs - the number of additional mallocs incurred.
7224: .   bnstash   - the size of the block stash
7225: -   breallocs - the number of additional mallocs incurred.in the block stash
7226:  
7227:    Level: advanced

7229: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7230:   
7231: @*/
7232: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7233: {
7236:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7237:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7238:   return(0);
7239: }

7243: /*@C
7244:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
7245:      parallel layout
7246:    
7247:    Collective on Mat

7249:    Input Parameter:
7250: .  mat - the matrix

7252:    Output Parameter:
7253: +   right - (optional) vector that the matrix can be multiplied against
7254: -   left - (optional) vector that the matrix vector product can be stored in

7256:   Level: advanced

7258: .seealso: MatCreate()
7259: @*/
7260: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7261: {

7267:   MatPreallocated(mat);
7268:   if (mat->ops->getvecs) {
7269:     (*mat->ops->getvecs)(mat,right,left);
7270:   } else {
7271:     PetscMPIInt size;
7272:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
7273:     if (right) {
7274:       VecCreate(((PetscObject)mat)->comm,right);
7275:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7276:       VecSetBlockSize(*right,mat->rmap->bs);
7277:       if (size > 1) {
7278:         /* New vectors uses Mat cmap and does not create a new one */
7279:         PetscLayoutDestroy((*right)->map);
7280:         (*right)->map = mat->cmap;
7281:         mat->cmap->refcnt++;

7283:         VecSetType(*right,VECMPI);
7284:       } else {VecSetType(*right,VECSEQ);}
7285:     }
7286:     if (left) {
7287:       VecCreate(((PetscObject)mat)->comm,left);
7288:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7289:       VecSetBlockSize(*left,mat->rmap->bs);
7290:       if (size > 1) {
7291:         /* New vectors uses Mat rmap and does not create a new one */
7292:         PetscLayoutDestroy((*left)->map);
7293:         (*left)->map = mat->rmap;
7294:         mat->rmap->refcnt++;

7296:         VecSetType(*left,VECMPI);
7297:       } else {VecSetType(*left,VECSEQ);}
7298:     }
7299:   }
7300:   if (mat->mapping) {
7301:     if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7302:     if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7303:   }
7304:   if (mat->bmapping) {
7305:     if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7306:     if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7307:   }
7308:   return(0);
7309: }

7313: /*@C
7314:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7315:      with default values.

7317:    Not Collective

7319:    Input Parameters:
7320: .    info - the MatFactorInfo data structure


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

7326:    Level: developer

7328: .seealso: MatFactorInfo

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

7333: @*/

7335: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7336: {

7340:   PetscMemzero(info,sizeof(MatFactorInfo));
7341:   return(0);
7342: }

7346: /*@
7347:    MatPtAP - Creates the matrix projection C = P^T * A * P

7349:    Collective on Mat

7351:    Input Parameters:
7352: +  A - the matrix
7353: .  P - the projection matrix
7354: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7355: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

7357:    Output Parameters:
7358: .  C - the product matrix

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

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

7366:    Level: intermediate

7368: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7369: @*/
7370: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7371: {

7377:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7378:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7381:   MatPreallocated(P);
7382:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7383:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7385:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7386:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7387:   MatPreallocated(A);

7389:   if (!A->ops->ptap) {
7390:     const MatType mattype;
7391:     MatGetType(A,&mattype);
7392:     SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7393:   }
7394:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7395:   (*A->ops->ptap)(A,P,scall,fill,C);
7396:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);

7398:   return(0);
7399: }

7403: /*@
7404:    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P

7406:    Collective on Mat

7408:    Input Parameters:
7409: +  A - the matrix
7410: -  P - the projection matrix

7412:    Output Parameters:
7413: .  C - the product matrix

7415:    Notes:
7416:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7417:    the user using MatDeatroy().

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

7422:    Level: intermediate

7424: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7425: @*/
7426: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
7427: {

7433:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7434:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7437:   MatPreallocated(P);
7438:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7439:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7442:   MatPreallocated(C);
7443:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7444:   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7445:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7446:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
7447:   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7448:   MatPreallocated(A);

7450:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7451:   (*A->ops->ptapnumeric)(A,P,C);
7452:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7453:   return(0);
7454: }

7458: /*@
7459:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P

7461:    Collective on Mat

7463:    Input Parameters:
7464: +  A - the matrix
7465: -  P - the projection matrix

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

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

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

7477:    Level: intermediate

7479: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7480: @*/
7481: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7482: {

7488:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7489:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7490:   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7493:   MatPreallocated(P);
7494:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7495:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7498:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7499:   if (A->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N);
7500:   MatPreallocated(A);
7501:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7502:   (*A->ops->ptapsymbolic)(A,P,fill,C);
7503:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

7505:   MatSetBlockSize(*C,A->rmap->bs);

7507:   return(0);
7508: }

7512: /*@
7513:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

7515:    Collective on Mat

7517:    Input Parameters:
7518: +  A - the left matrix
7519: .  B - the right matrix
7520: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7521: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7522:           if the result is a dense matrix this is irrelevent

7524:    Output Parameters:
7525: .  C - the product matrix

7527:    Notes:
7528:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

7540:    Level: intermediate

7542: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7543: @*/
7544: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7545: {
7547:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7548:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7549:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

7554:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7555:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7558:   MatPreallocated(B);
7559:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7560:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7562:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7563:   if (scall == MAT_REUSE_MATRIX){
7566:   }
7567:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7568:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7569:   MatPreallocated(A);

7571:   fA = A->ops->matmult;
7572:   fB = B->ops->matmult;
7573:   if (fB == fA) {
7574:     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7575:     mult = fB;
7576:   } else {
7577:     /* dispatch based on the type of A and B */
7578:     char  multname[256];
7579:     PetscStrcpy(multname,"MatMatMult_");
7580:     PetscStrcat(multname,((PetscObject)A)->type_name);
7581:     PetscStrcat(multname,"_");
7582:     PetscStrcat(multname,((PetscObject)B)->type_name);
7583:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7584:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7585:     if (!mult) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7586:   }
7587:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7588:   (*mult)(A,B,scall,fill,C);
7589:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7590:   return(0);
7591: }

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

7599:    Collective on Mat

7601:    Input Parameters:
7602: +  A - the left matrix
7603: .  B - the right matrix
7604: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7605:       if C is a dense matrix this is irrelevent
7606:  
7607:    Output Parameters:
7608: .  C - the product matrix

7610:    Notes:
7611:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

7616:    This routine is currently implemented for 
7617:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7618:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7619:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7621:    Level: intermediate

7623: .seealso: MatMatMult(), MatMatMultNumeric()
7624: @*/
7625: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7626: {
7628:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7629:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7630:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

7635:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7636:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7640:   MatPreallocated(B);
7641:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7642:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7645:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7646:   if (fill == PETSC_DEFAULT) fill = 2.0;
7647:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7648:   MatPreallocated(A);
7649: 
7650:   Asymbolic = A->ops->matmultsymbolic;
7651:   Bsymbolic = B->ops->matmultsymbolic;
7652:   if (Asymbolic == Bsymbolic){
7653:     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7654:     symbolic = Bsymbolic;
7655:   } else { /* dispatch based on the type of A and B */
7656:     char  symbolicname[256];
7657:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7658:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7659:     PetscStrcat(symbolicname,"_");
7660:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7661:     PetscStrcat(symbolicname,"_C");
7662:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7663:     if (!symbolic) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7664:   }
7665:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7666:   (*symbolic)(A,B,fill,C);
7667:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7668:   return(0);
7669: }

7673: /*@
7674:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7675:    Call this routine after first calling MatMatMultSymbolic().

7677:    Collective on Mat

7679:    Input Parameters:
7680: +  A - the left matrix
7681: -  B - the right matrix

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

7686:    Notes:
7687:    C must have been created with MatMatMultSymbolic().

7689:    This routine is currently implemented for 
7690:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7691:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7692:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7694:    Level: intermediate

7696: .seealso: MatMatMult(), MatMatMultSymbolic()
7697: @*/
7698: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
7699: {
7701:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7702:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7703:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

7708:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7709:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7713:   MatPreallocated(B);
7714:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7715:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7719:   MatPreallocated(C);
7720:   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7721:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7723:   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7724:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7725:   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7726:   MatPreallocated(A);

7728:   Anumeric = A->ops->matmultnumeric;
7729:   Bnumeric = B->ops->matmultnumeric;
7730:   if (Anumeric == Bnumeric){
7731:     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7732:     numeric = Bnumeric;
7733:   } else {
7734:     char  numericname[256];
7735:     PetscStrcpy(numericname,"MatMatMultNumeric_");
7736:     PetscStrcat(numericname,((PetscObject)A)->type_name);
7737:     PetscStrcat(numericname,"_");
7738:     PetscStrcat(numericname,((PetscObject)B)->type_name);
7739:     PetscStrcat(numericname,"_C");
7740:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7741:     if (!numeric)
7742:       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7743:   }
7744:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7745:   (*numeric)(A,B,C);
7746:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7747:   return(0);
7748: }

7752: /*@
7753:    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.

7755:    Collective on Mat

7757:    Input Parameters:
7758: +  A - the left matrix
7759: .  B - the right matrix
7760: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7761: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

7763:    Output Parameters:
7764: .  C - the product matrix

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

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

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

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

7777:    Level: intermediate

7779: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7780: @*/
7781: PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7782: {
7784:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7785:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

7790:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7791:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7794:   MatPreallocated(B);
7795:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7796:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7798:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7799:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7800:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7801:   MatPreallocated(A);

7803:   fA = A->ops->matmulttranspose;
7804:   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7805:   fB = B->ops->matmulttranspose;
7806:   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7807:   if (fB!=fA) SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultTranspose requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);

7809:   PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7810:   (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7811:   PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7812: 
7813:   return(0);
7814: }

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

7821:    Collective on Mat

7823:    Input Parameters:
7824: +  mat - the matrix
7825: .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7826: .  subcomm - MPI communicator split from the communicator where mat resides in
7827: .  mlocal_red - number of local rows of the redundant matrix
7828: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7830:    Output Parameter:
7831: .  matredundant - redundant matrix

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

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

7840:    Only MPIAIJ matrix is supported. 
7841:    
7842:    Level: advanced

7844:    Concepts: subcommunicator
7845:    Concepts: duplicate matrix

7847: .seealso: MatDestroy()
7848: @*/
7849: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7850: {

7855:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7858:   }
7859:   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7860:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7861:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7862:   MatPreallocated(mat);

7864:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7865:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7866:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7867:   return(0);
7868: }