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:    PetscInt       ncols, nrows;
100:    Vec            diag;

103:    MatGetSize(mat, &nrows, &ncols);
104:    VecCreateSeq(PETSC_COMM_WORLD, ncols, &diag);
105:    MatGetDiagonal(mat,diag);
106:    VecSum(diag, trace);
107:    VecDestroy(diag);
108:    return(0);
109: }

113: /*@
114:    MatRealPart - Zeros out the imaginary part of the matrix

116:    Collective on Mat

118:    Input Parameters:
119: .  mat - the matrix

121:    Level: advanced


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

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

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

146:    Collective on Mat

148:    Input Parameter:
149: .  mat - the matrix

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

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

157:    Level: advanced

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

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


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

184:    Collective on Mat

186:    Input Parameters:
187: .  mat - the matrix

189:    Level: advanced


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

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

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

214:    Collective on Mat

216:    Input Parameter:
217: .  mat - the matrix

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

223:    Level: advanced


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

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

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

249:    Not Collective

251:    Input Parameters:
252: +  mat - the matrix
253: -  row - the row to get

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

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

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

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

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

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

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


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

299:    Level: advanced

301:    Concepts: matrices^row access

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

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

326: /*@
327:    MatConjugate - replaces the matrix values with their complex conjugates

329:    Collective on Mat

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

334:    Level: advanced

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

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

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

355:    Not Collective

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

363:    Notes: 
364:    This routine should be called after you have finished examining the entries.

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

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

381:    Level: advanced

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

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

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

404:    Not Collective

406:    Input Parameters:
407: +  mat - the matrix

409:    Notes:
410:    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.

412:    Level: advanced

414:    Concepts: matrices^row access

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

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

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

438:    Not Collective

440:    Input Parameters:
441: +  mat - the matrix

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


447:    Level: advanced

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

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

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

469:    Collective on Mat

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

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

479:    Level: advanced

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

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

491:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
492:   return(0);
493: }

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

501:    Collective on Mat

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

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

511:    Level: advanced

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

515: .seealso: MatGetOptionsPrefix()
516: @*/
517: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
518: {
520: 
523:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
524:   return(0);
525: }

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

533:    Not Collective

535:    Input Parameter:
536: .  A - the Mat context

538:    Output Parameter:
539: .  prefix - pointer to the prefix string used

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

544:    Level: advanced

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

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

556:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
557:   return(0);
558: }

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

565:    Collective on Mat

567:    Input Parameters:
568: .  A - the Mat context

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

574:    Level: advanced

576: .keywords: Mat, setup

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

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

601: /*@C
602:    MatView - Visualizes a matrix object.

604:    Collective on Mat

606:    Input Parameters:
607: +  mat - the matrix
608: -  viewer - visualization context

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

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

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

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

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

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

665:    Concepts: matrices^viewing
666:    Concepts: matrices^plotting
667:    Concepts: matrices^printing

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

683:   if (!viewer) {
684:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
685:   }
688:   if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
689:   MatPreallocated(mat);

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

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

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


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

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

755:    Level: Developer            

757:    Concepts: matrices^scaling

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

768:   MatPreallocated(mat);

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

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

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


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

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

799:    Level: Developer            

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

810:   MatPreallocated(mat);
813:   if (mat->ops->unscalesystem) {
814:     (*mat->ops->unscalesystem)(mat,b,x);
815:   }
816:   return(0);
817: }

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

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

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

837:    Level: Developer            

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

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

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

862:    Input Parameter:
863: .  A - the matrix

865:    Level: beginner

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

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

896: /*@
897:    MatValid - Checks whether a matrix object is valid.

899:    Collective on Mat

901:    Input Parameter:
902: .  m - the matrix to check 

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

908:    Level: developer

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

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

929:    Not Collective

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

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

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

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

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

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

959:    Level: beginner

961:    Concepts: matrices^putting entries in

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

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

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


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

1006:    Not Collective

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

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

1016:    All the nonzeros in the row must be provided

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

1020:    The row must belong to this process

1022:    Level: intermediate

1024:    Concepts: matrices^putting entries in

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

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

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

1047:    Not Collective

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

1054:    Notes:
1055:    The values, v, are column-oriented for the block version.

1057:    All the nonzeros in the row must be provided

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

1061:    The row must belong to this process

1063:    Level: advanced

1065:    Concepts: matrices^putting entries in

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

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

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

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

1101:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

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

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

1161:    Level: beginner

1163:    Concepts: matrices^putting entries in

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

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

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

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

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

1215:    Not Collective

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

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

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

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

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

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

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

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

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

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

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

1268:    Level: beginner

1270:    Concepts: matrices^putting entries in

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

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

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

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

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

1323:    Not Collective

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


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

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

1341:    Concepts: matrices^putting entries in

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


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

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

1371:    Not Collective

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

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

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

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

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

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

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

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

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

1428:    Level: intermediate

1430:    Concepts: matrices^putting entries in blocked

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

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

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

1491: /*@ 
1492:    MatGetValues - Gets a block of values from a matrix.

1494:    Not Collective; currently only returns a local block

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

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

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

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

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

1518:    Level: advanced

1520:    Concepts: matrices^accessing values

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

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

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

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

1552:    Not Collective

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

1559:    Level: intermediate

1561:    Concepts: matrices^local to global mapping
1562:    Concepts: local to global mapping^for matrices

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

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

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

1595:    Not Collective

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

1602:    Level: intermediate

1604:    Concepts: matrices^local to global mapping blocked
1605:    Concepts: local to global mapping^for matrices, blocked

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

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

1632:    Not Collective

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

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

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

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

1654:    Level: intermediate

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

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

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

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

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

1710:    Not Collective

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

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

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

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

1734:    Level: intermediate

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

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

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

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

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

1810:    Collective on Mat and Vec

1812:    Input Parameters:
1813: +  mat - the matrix
1814: -  x   - the vector to be multiplied

1816:    Output Parameters:
1817: .  y - the result

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

1823:    Level: developer

1825:    Concepts: matrix-vector product

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


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

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

1850: /* --------------------------------------------------------*/
1853: /*@
1854:    MatMult - Computes the matrix-vector product, y = Ax.

1856:    Collective on Mat and Vec

1858:    Input Parameters:
1859: +  mat - the matrix
1860: -  x   - the vector to be multiplied

1862:    Output Parameters:
1863: .  y - the result

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

1869:    Level: beginner

1871:    Concepts: matrix-vector product

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


1885:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1886:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1887:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1888: #ifndef PETSC_HAVE_CONSTRAINTS
1889:   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);
1890:   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);
1891:   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);
1892: #endif
1893:   MatPreallocated(mat);

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

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

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

1913: /*@
1914:    MatMultTranspose - Computes matrix transpose times a vector.

1916:    Collective on Mat and Vec

1918:    Input Parameters:
1919: +  mat - the matrix
1920: -  x   - the vector to be multilplied

1922:    Output Parameters:
1923: .  y - the result

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

1929:    Level: beginner

1931:    Concepts: matrix vector product^transpose

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


1945:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1946:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1947:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1948: #ifndef PETSC_HAVE_CONSTRAINTS
1949:   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);
1950:   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);
1951: #endif
1952:   MatPreallocated(mat);

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

1964: /*@
1965:    MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.

1967:    Collective on Mat and Vec

1969:    Input Parameters:
1970: +  mat - the matrix
1971: -  x   - the vector to be multilplied

1973:    Output Parameters:
1974: .  y - the result

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

1980:    Level: beginner

1982:    Concepts: matrix vector product^transpose

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


1996:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1997:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1998:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1999: #ifndef PETSC_HAVE_CONSTRAINTS
2000:   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);
2001:   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);
2002: #endif
2003:   MatPreallocated(mat);

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

2015: /*@
2016:     MatMultAdd -  Computes v3 = v2 + A * v1.

2018:     Collective on Mat and Vec

2020:     Input Parameters:
2021: +   mat - the matrix
2022: -   v1, v2 - the vectors

2024:     Output Parameters:
2025: .   v3 - the result

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

2031:     Level: beginner

2033:     Concepts: matrix vector product^addition

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


2048:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2049:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2050:   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);
2051:   /* 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);
2052:      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); */
2053:   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);
2054:   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);
2055:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2056:   MatPreallocated(mat);

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

2067: /*@
2068:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

2070:    Collective on Mat and Vec

2072:    Input Parameters:
2073: +  mat - the matrix
2074: -  v1, v2 - the vectors

2076:    Output Parameters:
2077: .  v3 - the result

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

2083:    Level: beginner

2085:    Concepts: matrix vector product^transpose and addition

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


2100:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2101:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2102:   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2103:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2104:   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);
2105:   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);
2106:   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);
2107:   MatPreallocated(mat);

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

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

2121:    Collective on Mat and Vec

2123:    Input Parameters:
2124: +  mat - the matrix
2125: -  v1, v2 - the vectors

2127:    Output Parameters:
2128: .  v3 - the result

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

2134:    Level: beginner

2136:    Concepts: matrix vector product^transpose and addition

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


2151:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2152:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2153:   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2154:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2155:   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);
2156:   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);
2157:   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);
2158:   MatPreallocated(mat);

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

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

2173:    Collective on Mat and Vec

2175:    Input Parameters:
2176: +  mat - the matrix
2177: -  x   - the vector to be multilplied

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

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

2186:    Level: beginner

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

2199:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2200:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2201:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2202:   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);
2203:   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);
2204:   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);

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

2211:   return(0);
2212: }

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

2220:    Collective on Mat and Vec

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

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

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

2233:    Level: beginner

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

2246:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2247:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2248:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2249:   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);
2250:   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);

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

2257:   return(0);
2258: }
2259: /* ------------------------------------------------------------*/
2262: /*@C
2263:    MatGetInfo - Returns information about matrix storage (number of
2264:    nonzeros, memory, etc.).

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

2269:    Input Parameters:
2270: .  mat - the matrix

2272:    Output Parameters:
2273: +  flag - flag indicating the type of parameters to be returned
2274:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2275:    MAT_GLOBAL_SUM - sum over all processors)
2276: -  info - matrix information context

2278:    Notes:
2279:    The MatInfo context contains a variety of matrix data, including
2280:    number of nonzeros allocated and used, number of mallocs during
2281:    matrix assembly, etc.  Additional information for factored matrices
2282:    is provided (such as the fill ratio, number of mallocs during
2283:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2284:    when using the runtime options 
2285: $       -info -mat_view_info

2287:    Example for C/C++ Users:
2288:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2289:    data within the MatInfo context.  For example, 
2290: .vb
2291:       MatInfo info;
2292:       Mat     A;
2293:       double  mal, nz_a, nz_u;

2295:       MatGetInfo(A,MAT_LOCAL,&info);
2296:       mal  = info.mallocs;
2297:       nz_a = info.nz_allocated;
2298: .ve

2300:    Example for Fortran Users:
2301:    Fortran users should declare info as a double precision
2302:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2303:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2304:    a complete list of parameter names.
2305: .vb
2306:       double  precision info(MAT_INFO_SIZE)
2307:       double  precision mal, nz_a
2308:       Mat     A
2309:       integer ierr

2311:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2312:       mal = info(MAT_INFO_MALLOCS)
2313:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2314: .ve

2316:     Level: intermediate

2318:     Concepts: matrices^getting information on
2319:     
2320:     Developer Note: fortran interface is not autogenerated as the f90
2321:     interface defintion cannot be generated correctly [due to MatInfo]
2322:  
2323: @*/
2324: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2325: {

2332:   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2333:   MatPreallocated(mat);
2334:   (*mat->ops->getinfo)(mat,flag,info);
2335:   return(0);
2336: }

2338: /* ----------------------------------------------------------*/

2342: /*@C
2343:    MatLUFactor - Performs in-place LU factorization of matrix.

2345:    Collective on Mat

2347:    Input Parameters:
2348: +  mat - the matrix
2349: .  row - row permutation
2350: .  col - column permutation
2351: -  info - options for factorization, includes 
2352: $          fill - expected fill as ratio of original fill.
2353: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2354: $                   Run with the option -info to determine an optimal value to use

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

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

2364:    Level: developer

2366:    Concepts: matrices^LU factorization

2368: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2369:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo

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

2374: @*/
2375: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2376: {

2385:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2386:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2387:   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2388:   MatPreallocated(mat);

2390:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2391:   (*mat->ops->lufactor)(mat,row,col,info);
2392:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2393:   PetscObjectStateIncrease((PetscObject)mat);
2394:   return(0);
2395: }

2399: /*@C
2400:    MatILUFactor - Performs in-place ILU factorization of matrix.

2402:    Collective on Mat

2404:    Input Parameters:
2405: +  mat - the matrix
2406: .  row - row permutation
2407: .  col - column permutation
2408: -  info - structure containing 
2409: $      levels - number of levels of fill.
2410: $      expected fill - as ratio of original fill.
2411: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2412:                 missing diagonal entries)

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

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

2422:    Level: developer

2424:    Concepts: matrices^ILU factorization

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

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

2431: @*/
2432: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2433: {

2442:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2443:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2444:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2445:   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2446:   MatPreallocated(mat);

2448:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2449:   (*mat->ops->ilufactor)(mat,row,col,info);
2450:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2451:   PetscObjectStateIncrease((PetscObject)mat);
2452:   return(0);
2453: }

2457: /*@C
2458:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2459:    Call this routine before calling MatLUFactorNumeric().

2461:    Collective on Mat

2463:    Input Parameters:
2464: +  fact - the factor matrix obtained with MatGetFactor()
2465: .  mat - the matrix
2466: .  row, col - row and column permutations
2467: -  info - options for factorization, includes 
2468: $          fill - expected fill as ratio of original fill.
2469: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2470: $                   Run with the option -info to determine an optimal value to use


2473:    Notes:
2474:    See the users manual for additional information about
2475:    choosing the fill factor for better efficiency.

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

2481:    Level: developer

2483:    Concepts: matrices^LU symbolic factorization

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

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

2490: @*/
2491: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2492: {

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

2507:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2508:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2509:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2510:   PetscObjectStateIncrease((PetscObject)fact);
2511:   return(0);
2512: }

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

2520:    Collective on Mat

2522:    Input Parameters:
2523: +  fact - the factor matrix obtained with MatGetFactor()
2524: .  mat - the matrix
2525: -  info - options for factorization

2527:    Notes:
2528:    See MatLUFactor() for in-place factorization.  See 
2529:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

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

2535:    Level: developer

2537:    Concepts: matrices^LU numeric factorization

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

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

2544: @*/
2545: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2546: {

2554:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2555:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2556:     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);
2557:   }
2558:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2559:   MatPreallocated(mat);
2560:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2561:   (fact->ops->lufactornumeric)(fact,mat,info);
2562:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

2564:   MatView_Private(fact);
2565:   PetscObjectStateIncrease((PetscObject)fact);
2566:   return(0);
2567: }

2571: /*@C
2572:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2573:    symmetric matrix. 

2575:    Collective on Mat

2577:    Input Parameters:
2578: +  mat - the matrix
2579: .  perm - row and column permutations
2580: -  f - expected fill as ratio of original fill

2582:    Notes:
2583:    See MatLUFactor() for the nonsymmetric case.  See also
2584:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2590:    Level: developer

2592:    Concepts: matrices^Cholesky factorization

2594: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2595:           MatGetOrdering()

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

2600: @*/
2601: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2602: {

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

2616:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2617:   (*mat->ops->choleskyfactor)(mat,perm,info);
2618:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2619:   PetscObjectStateIncrease((PetscObject)mat);
2620:   return(0);
2621: }

2625: /*@C
2626:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2627:    of a symmetric matrix. 

2629:    Collective on Mat

2631:    Input Parameters:
2632: +  fact - the factor matrix obtained with MatGetFactor()
2633: .  mat - the matrix
2634: .  perm - row and column permutations
2635: -  info - options for factorization, includes 
2636: $          fill - expected fill as ratio of original fill.
2637: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2638: $                   Run with the option -info to determine an optimal value to use

2640:    Notes:
2641:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2642:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2648:    Level: developer

2650:    Concepts: matrices^Cholesky symbolic factorization

2652: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2653:           MatGetOrdering()

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

2658: @*/
2659: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2660: {

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

2675:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2676:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2677:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2678:   PetscObjectStateIncrease((PetscObject)fact);
2679:   return(0);
2680: }

2684: /*@C
2685:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2686:    of a symmetric matrix. Call this routine after first calling
2687:    MatCholeskyFactorSymbolic().

2689:    Collective on Mat

2691:    Input Parameters:
2692: +  fact - the factor matrix obtained with MatGetFactor()
2693: .  mat - the initial matrix
2694: .  info - options for factorization
2695: -  fact - the symbolic factor of mat


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

2703:    Level: developer

2705:    Concepts: matrices^Cholesky numeric factorization

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

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

2712: @*/
2713: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2714: {

2722:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2723:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2724:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2725:     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);
2726:   }
2727:   MatPreallocated(mat);

2729:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2730:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
2731:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

2733:   MatView_Private(fact);
2734:   PetscObjectStateIncrease((PetscObject)fact);
2735:   return(0);
2736: }

2738: /* ----------------------------------------------------------------*/
2741: /*@
2742:    MatSolve - Solves A x = b, given a factored matrix.

2744:    Collective on Mat and Vec

2746:    Input Parameters:
2747: +  mat - the factored matrix
2748: -  b - the right-hand-side vector

2750:    Output Parameter:
2751: .  x - the result vector

2753:    Notes:
2754:    The vectors b and x cannot be the same.  I.e., one cannot
2755:    call MatSolve(A,x,x).

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

2762:    Level: developer

2764:    Concepts: matrices^triangular solves

2766: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2767: @*/
2768: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
2769: {

2779:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2780:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2781:   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);
2782:   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);
2783:   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);
2784:   if (!mat->rmap->N && !mat->cmap->N) return(0);
2785:   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2786:   MatPreallocated(mat);

2788:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2789:   (*mat->ops->solve)(mat,b,x);
2790:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2791:   PetscObjectStateIncrease((PetscObject)x);
2792:   return(0);
2793: }

2797: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
2798: {
2800:   Vec            b,x;
2801:   PetscInt       m,N,i;
2802:   PetscScalar    *bb,*xx;

2805:   MatGetArray(B,&bb);
2806:   MatGetArray(X,&xx);
2807:   MatGetLocalSize(B,&m,PETSC_NULL);  /* number local rows */
2808:   MatGetSize(B,PETSC_NULL,&N);       /* total columns in dense matrix */
2809:   MatGetVecs(A,&x,&b);
2810:   for (i=0; i<N; i++) {
2811:     VecPlaceArray(b,bb + i*m);
2812:     VecPlaceArray(x,xx + i*m);
2813:     MatSolve(A,b,x);
2814:     VecResetArray(x);
2815:     VecResetArray(b);
2816:   }
2817:   VecDestroy(b);
2818:   VecDestroy(x);
2819:   MatRestoreArray(B,&bb);
2820:   MatRestoreArray(X,&xx);
2821:   return(0);
2822: }

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

2829:    Collective on Mat 

2831:    Input Parameters:
2832: +  mat - the factored matrix
2833: -  B - the right-hand-side matrix  (dense matrix)

2835:    Output Parameter:
2836: .  X - the result matrix (dense matrix)

2838:    Notes:
2839:    The matrices b and x cannot be the same.  I.e., one cannot
2840:    call MatMatSolve(A,x,x).

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

2848:    Level: developer

2850:    Concepts: matrices^triangular solves

2852: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2853: @*/
2854: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
2855: {

2865:   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2866:   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2867:   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);
2868:   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);
2869:   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);
2870:   if (!A->rmap->N && !A->cmap->N) return(0);
2871:   MatPreallocated(A);

2873:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
2874:   if (!A->ops->matsolve) {
2875:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
2876:     MatMatSolve_Basic(A,B,X);
2877:   } else {
2878:     (*A->ops->matsolve)(A,B,X);
2879:   }
2880:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
2881:   PetscObjectStateIncrease((PetscObject)X);
2882:   return(0);
2883: }


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

2892:    Collective on Mat and Vec

2894:    Input Parameters:
2895: +  mat - the factored matrix
2896: -  b - the right-hand-side vector

2898:    Output Parameter:
2899: .  x - the result vector

2901:    Notes:
2902:    MatSolve() should be used for most applications, as it performs
2903:    a forward solve followed by a backward solve.

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

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

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

2918:    Level: developer

2920:    Concepts: matrices^forward solves

2922: .seealso: MatSolve(), MatBackwardSolve()
2923: @*/
2924: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
2925: {

2935:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2936:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2937:   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2938:   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);
2939:   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);
2940:   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);
2941:   MatPreallocated(mat);
2942:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2943:   (*mat->ops->forwardsolve)(mat,b,x);
2944:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2945:   PetscObjectStateIncrease((PetscObject)x);
2946:   return(0);
2947: }

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

2955:    Collective on Mat and Vec

2957:    Input Parameters:
2958: +  mat - the factored matrix
2959: -  b - the right-hand-side vector

2961:    Output Parameter:
2962: .  x - the result vector

2964:    Notes:
2965:    MatSolve() should be used for most applications, as it performs
2966:    a forward solve followed by a backward solve.

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

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

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

2981:    Level: developer

2983:    Concepts: matrices^backward solves

2985: .seealso: MatSolve(), MatForwardSolve()
2986: @*/
2987: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
2988: {

2998:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2999:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3000:   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3001:   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);
3002:   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);
3003:   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);
3004:   MatPreallocated(mat);

3006:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3007:   (*mat->ops->backwardsolve)(mat,b,x);
3008:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3009:   PetscObjectStateIncrease((PetscObject)x);
3010:   return(0);
3011: }

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

3018:    Collective on Mat and Vec

3020:    Input Parameters:
3021: +  mat - the factored matrix
3022: .  b - the right-hand-side vector
3023: -  y - the vector to be added to 

3025:    Output Parameter:
3026: .  x - the result vector

3028:    Notes:
3029:    The vectors b and x cannot be the same.  I.e., one cannot
3030:    call MatSolveAdd(A,x,y,x).

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

3036:    Level: developer

3038:    Concepts: matrices^triangular solves

3040: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3041: @*/
3042: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3043: {
3044:   PetscScalar    one = 1.0;
3045:   Vec            tmp;

3057:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3058:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3059:   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);
3060:   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);
3061:   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);
3062:   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);
3063:   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);
3064:   MatPreallocated(mat);

3066:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3067:   if (mat->ops->solveadd)  {
3068:     (*mat->ops->solveadd)(mat,b,y,x);
3069:   } else {
3070:     /* do the solve then the add manually */
3071:     if (x != y) {
3072:       MatSolve(mat,b,x);
3073:       VecAXPY(x,one,y);
3074:     } else {
3075:       VecDuplicate(x,&tmp);
3076:       PetscLogObjectParent(mat,tmp);
3077:       VecCopy(x,tmp);
3078:       MatSolve(mat,b,x);
3079:       VecAXPY(x,one,tmp);
3080:       VecDestroy(tmp);
3081:     }
3082:   }
3083:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3084:   PetscObjectStateIncrease((PetscObject)x);
3085:   return(0);
3086: }

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

3093:    Collective on Mat and Vec

3095:    Input Parameters:
3096: +  mat - the factored matrix
3097: -  b - the right-hand-side vector

3099:    Output Parameter:
3100: .  x - the result vector

3102:    Notes:
3103:    The vectors b and x cannot be the same.  I.e., one cannot
3104:    call MatSolveTranspose(A,x,x).

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

3110:    Level: developer

3112:    Concepts: matrices^triangular solves

3114: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3115: @*/
3116: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
3117: {

3127:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3128:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3129:   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3130:   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);
3131:   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);
3132:   MatPreallocated(mat);
3133:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3134:   (*mat->ops->solvetranspose)(mat,b,x);
3135:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3136:   PetscObjectStateIncrease((PetscObject)x);
3137:   return(0);
3138: }

3142: /*@
3143:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
3144:                       factored matrix. 

3146:    Collective on Mat and Vec

3148:    Input Parameters:
3149: +  mat - the factored matrix
3150: .  b - the right-hand-side vector
3151: -  y - the vector to be added to 

3153:    Output Parameter:
3154: .  x - the result vector

3156:    Notes:
3157:    The vectors b and x cannot be the same.  I.e., one cannot
3158:    call MatSolveTransposeAdd(A,x,y,x).

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

3164:    Level: developer

3166:    Concepts: matrices^triangular solves

3168: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3169: @*/
3170: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3171: {
3172:   PetscScalar    one = 1.0;
3174:   Vec            tmp;

3185:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3186:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3187:   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);
3188:   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);
3189:   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);
3190:   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);
3191:   MatPreallocated(mat);

3193:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3194:   if (mat->ops->solvetransposeadd) {
3195:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3196:   } else {
3197:     /* do the solve then the add manually */
3198:     if (x != y) {
3199:       MatSolveTranspose(mat,b,x);
3200:       VecAXPY(x,one,y);
3201:     } else {
3202:       VecDuplicate(x,&tmp);
3203:       PetscLogObjectParent(mat,tmp);
3204:       VecCopy(x,tmp);
3205:       MatSolveTranspose(mat,b,x);
3206:       VecAXPY(x,one,tmp);
3207:       VecDestroy(tmp);
3208:     }
3209:   }
3210:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3211:   PetscObjectStateIncrease((PetscObject)x);
3212:   return(0);
3213: }
3214: /* ----------------------------------------------------------------*/

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

3221:    Collective on Mat and Vec

3223:    Input Parameters:
3224: +  mat - the matrix
3225: .  b - the right hand side
3226: .  omega - the relaxation factor
3227: .  flag - flag indicating the type of SOR (see below)
3228: .  shift -  diagonal shift
3229: .  its - the number of iterations
3230: -  lits - the number of local iterations 

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

3235:    SOR Flags:
3236: .     SOR_FORWARD_SWEEP - forward SOR
3237: .     SOR_BACKWARD_SWEEP - backward SOR
3238: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3239: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
3240: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
3241: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3242: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
3243:          upper/lower triangular part of matrix to
3244:          vector (with omega)
3245: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3247:    Notes:
3248:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3249:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3250:    on each processor. 

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

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

3257:    Notes for Advanced Users:
3258:    The flags are implemented as bitwise inclusive or operations.
3259:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3260:    to specify a zero initial guess for SSOR.

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


3267:    Level: developer

3269:    Concepts: matrices^relaxation
3270:    Concepts: matrices^SOR
3271:    Concepts: matrices^Gauss-Seidel

3273: @*/
3274: PetscErrorCode  MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3275: {

3285:   if (!mat->ops->sor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3286:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3287:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3288:   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);
3289:   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);
3290:   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);
3291:   if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3292:   if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);

3294:   MatPreallocated(mat);
3295:   PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3296:   ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3297:   PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3298:   PetscObjectStateIncrease((PetscObject)x);
3299:   return(0);
3300: }

3304: /*
3305:       Default matrix copy routine.
3306: */
3307: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3308: {
3309:   PetscErrorCode    ierr;
3310:   PetscInt          i,rstart = 0,rend = 0,nz;
3311:   const PetscInt    *cwork;
3312:   const PetscScalar *vwork;

3315:   if (B->assembled) {
3316:     MatZeroEntries(B);
3317:   }
3318:   MatGetOwnershipRange(A,&rstart,&rend);
3319:   for (i=rstart; i<rend; i++) {
3320:     MatGetRow(A,i,&nz,&cwork,&vwork);
3321:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3322:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3323:   }
3324:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3325:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3326:   PetscObjectStateIncrease((PetscObject)B);
3327:   return(0);
3328: }

3332: /*@
3333:    MatCopy - Copys a matrix to another matrix.

3335:    Collective on Mat

3337:    Input Parameters:
3338: +  A - the matrix
3339: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3341:    Output Parameter:
3342: .  B - where the copy is put

3344:    Notes:
3345:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
3346:    same nonzero pattern or the routine will crash.

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

3352:    Level: intermediate
3353:    
3354:    Concepts: matrices^copying

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

3358: @*/
3359: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3360: {
3362:   PetscInt       i;

3370:   MatPreallocated(B);
3371:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3372:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3373:   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);
3374:   MatPreallocated(A);

3376:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3377:   if (A->ops->copy) {
3378:     (*A->ops->copy)(A,B,str);
3379:   } else { /* generic conversion */
3380:     MatCopy_Basic(A,B,str);
3381:   }
3382:   if (A->mapping) {
3383:     if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
3384:     MatSetLocalToGlobalMapping(B,A->mapping);
3385:   }
3386:   if (A->bmapping) {
3387:     if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
3388:     MatSetLocalToGlobalMappingBlock(B,A->mapping);
3389:   }

3391:   B->stencil.dim = A->stencil.dim;
3392:   B->stencil.noc = A->stencil.noc;
3393:   for (i=0; i<=A->stencil.dim; i++) {
3394:     B->stencil.dims[i]   = A->stencil.dims[i];
3395:     B->stencil.starts[i] = A->stencil.starts[i];
3396:   }

3398:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3399:   PetscObjectStateIncrease((PetscObject)B);
3400:   return(0);
3401: }

3405: /*@C  
3406:    MatConvert - Converts a matrix to another matrix, either of the same
3407:    or different type.

3409:    Collective on Mat

3411:    Input Parameters:
3412: +  mat - the matrix
3413: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3414:    same type as the original matrix.
3415: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3416:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3417:    MAT_INITIAL_MATRIX.

3419:    Output Parameter:
3420: .  M - pointer to place new matrix

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

3427:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3428:    the MPI communicator of the generated matrix is always the same as the communicator
3429:    of the input matrix.

3431:    Level: intermediate

3433:    Concepts: matrices^converting between storage formats

3435: .seealso: MatCopy(), MatDuplicate()
3436: @*/
3437: PetscErrorCode  MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3438: {
3439:   PetscErrorCode         ierr;
3440:   PetscTruth             sametype,issame,flg;
3441:   char                   convname[256],mtype[256];
3442:   Mat                    B;

3448:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3449:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3450:   MatPreallocated(mat);

3452:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3453:   if (flg) {
3454:     newtype = mtype;
3455:   }
3456:   PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3457:   PetscStrcmp(newtype,"same",&issame);
3458:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3459:     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3460:   }

3462:   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3463: 
3464:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3465:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3466:   } else {
3467:     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3468:     const char     *prefix[3] = {"seq","mpi",""};
3469:     PetscInt       i;
3470:     /* 
3471:        Order of precedence:
3472:        1) See if a specialized converter is known to the current matrix.
3473:        2) See if a specialized converter is known to the desired matrix class.
3474:        3) See if a good general converter is registered for the desired class
3475:           (as of 6/27/03 only MATMPIADJ falls into this category).
3476:        4) See if a good general converter is known for the current matrix.
3477:        5) Use a really basic converter.
3478:     */
3479: 
3480:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3481:     for (i=0; i<3; i++) {
3482:       PetscStrcpy(convname,"MatConvert_");
3483:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3484:       PetscStrcat(convname,"_");
3485:       PetscStrcat(convname,prefix[i]);
3486:       PetscStrcat(convname,newtype);
3487:       PetscStrcat(convname,"_C");
3488:       PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3489:       if (conv) goto foundconv;
3490:     }

3492:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3493:     MatCreate(((PetscObject)mat)->comm,&B);
3494:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3495:     MatSetType(B,newtype);
3496:     for (i=0; i<3; i++) {
3497:       PetscStrcpy(convname,"MatConvert_");
3498:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3499:       PetscStrcat(convname,"_");
3500:       PetscStrcat(convname,prefix[i]);
3501:       PetscStrcat(convname,newtype);
3502:       PetscStrcat(convname,"_C");
3503:       PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3504:       if (conv) {
3505:         MatDestroy(B);
3506:         goto foundconv;
3507:       }
3508:     }

3510:     /* 3) See if a good general converter is registered for the desired class */
3511:     conv = B->ops->convertfrom;
3512:     MatDestroy(B);
3513:     if (conv) goto foundconv;

3515:     /* 4) See if a good general converter is known for the current matrix */
3516:     if (mat->ops->convert) {
3517:       conv = mat->ops->convert;
3518:     }
3519:     if (conv) goto foundconv;

3521:     /* 5) Use a really basic converter. */
3522:     conv = MatConvert_Basic;

3524:     foundconv:
3525:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3526:     (*conv)(mat,newtype,reuse,M);
3527:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3528:   }
3529:   PetscObjectStateIncrease((PetscObject)*M);
3530:   return(0);
3531: }

3535: /*@C  
3536:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3538:    Not Collective

3540:    Input Parameter:
3541: .  mat - the matrix, must be a factored matrix

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

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

3550:    Level: intermediate

3552: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3553: @*/
3554: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3555: {
3556:   PetscErrorCode         ierr;
3557:   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);

3562:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3563:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3564:   if (!conv) {
3565:     *type = MAT_SOLVER_PETSC;
3566:   } else {
3567:     (*conv)(mat,type);
3568:   }
3569:   return(0);
3570: }

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

3577:    Collective on Mat

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

3584:    Output Parameters:
3585: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

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

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

3593:    Level: intermediate

3595: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3596: @*/
3597: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3598: {
3599:   PetscErrorCode         ierr;
3600:   char                   convname[256];
3601:   PetscErrorCode         (*conv)(Mat,MatFactorType,Mat*);


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

3610:   PetscStrcpy(convname,"MatGetFactor_");
3611:   PetscStrcat(convname,type);
3612:   PetscStrcat(convname,"_C");
3613:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3614:   if (!conv) {
3615:     PetscTruth flag;
3616:     PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);
3617:     if (flag) {
3618:       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3619:     } else {
3620:       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);
3621:     }
3622:   }
3623:   (*conv)(mat,ftype,f);
3624:   return(0);
3625: }

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

3632:    Collective on Mat

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

3639:    Output Parameter:
3640: .    flg - PETSC_TRUE if the factorization is available

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

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

3648:    Level: intermediate

3650: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3651: @*/
3652: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3653: {
3654:   PetscErrorCode         ierr;
3655:   char                   convname[256];
3656:   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscTruth*);


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

3665:   PetscStrcpy(convname,"MatGetFactorAvailable_");
3666:   PetscStrcat(convname,type);
3667:   PetscStrcat(convname,"_C");
3668:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3669:   if (!conv) {
3670:     *flg = PETSC_FALSE;
3671:   } else {
3672:     (*conv)(mat,ftype,flg);
3673:   }
3674:   return(0);
3675: }


3680: /*@
3681:    MatDuplicate - Duplicates a matrix including the non-zero structure.

3683:    Collective on Mat

3685:    Input Parameters:
3686: +  mat - the matrix
3687: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
3688:         MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.

3690:    Output Parameter:
3691: .  M - pointer to place new matrix

3693:    Level: intermediate

3695:    Concepts: matrices^duplicating

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

3699: .seealso: MatCopy(), MatConvert()
3700: @*/
3701: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3702: {
3704:   Mat            B;
3705:   PetscInt       i;

3711:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3712:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3713:   MatPreallocated(mat);

3715:   *M  = 0;
3716:   if (!mat->ops->duplicate) {
3717:     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3718:   }
3719:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3720:   (*mat->ops->duplicate)(mat,op,M);
3721:   B = *M;
3722:   if (mat->mapping) {
3723:     MatSetLocalToGlobalMapping(B,mat->mapping);
3724:   }
3725:   if (mat->bmapping) {
3726:     MatSetLocalToGlobalMappingBlock(B,mat->bmapping);
3727:   }
3728:   PetscLayoutCopy(mat->rmap,&B->rmap);
3729:   PetscLayoutCopy(mat->cmap,&B->cmap);
3730: 
3731:   B->stencil.dim = mat->stencil.dim;
3732:   B->stencil.noc = mat->stencil.noc;
3733:   for (i=0; i<=mat->stencil.dim; i++) {
3734:     B->stencil.dims[i]   = mat->stencil.dims[i];
3735:     B->stencil.starts[i] = mat->stencil.starts[i];
3736:   }

3738:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3739:   PetscObjectStateIncrease((PetscObject)B);
3740:   return(0);
3741: }

3745: /*@ 
3746:    MatGetDiagonal - Gets the diagonal of a matrix.

3748:    Collective on Mat and Vec

3750:    Input Parameters:
3751: +  mat - the matrix
3752: -  v - the vector for storing the diagonal

3754:    Output Parameter:
3755: .  v - the diagonal of the matrix

3757:    Level: intermediate

3759:    Concepts: matrices^accessing diagonals

3761: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3762: @*/
3763: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
3764: {

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

3775:   (*mat->ops->getdiagonal)(mat,v);
3776:   PetscObjectStateIncrease((PetscObject)v);
3777:   return(0);
3778: }

3782: /*@ 
3783:    MatGetRowMin - Gets the minimum value (of the real part) of each
3784:         row of the matrix

3786:    Collective on Mat and Vec

3788:    Input Parameters:
3789: .  mat - the matrix

3791:    Output Parameter:
3792: +  v - the vector for storing the maximums
3793: -  idx - the indices of the column found for each row (optional)

3795:    Level: intermediate

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

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

3802:    Concepts: matrices^getting row maximums

3804: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3805:           MatGetRowMax()
3806: @*/
3807: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3808: {

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

3819:   (*mat->ops->getrowmin)(mat,v,idx);
3820:   PetscObjectStateIncrease((PetscObject)v);
3821:   return(0);
3822: }

3826: /*@ 
3827:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3828:         row of the matrix

3830:    Collective on Mat and Vec

3832:    Input Parameters:
3833: .  mat - the matrix

3835:    Output Parameter:
3836: +  v - the vector for storing the minimums
3837: -  idx - the indices of the column found for each row (optional)

3839:    Level: intermediate

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

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

3846:    Concepts: matrices^getting row maximums

3848: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3849: @*/
3850: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3851: {

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

3863:   (*mat->ops->getrowminabs)(mat,v,idx);
3864:   PetscObjectStateIncrease((PetscObject)v);
3865:   return(0);
3866: }

3870: /*@ 
3871:    MatGetRowMax - Gets the maximum value (of the real part) of each
3872:         row of the matrix

3874:    Collective on Mat and Vec

3876:    Input Parameters:
3877: .  mat - the matrix

3879:    Output Parameter:
3880: +  v - the vector for storing the maximums
3881: -  idx - the indices of the column found for each row (optional)

3883:    Level: intermediate

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

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

3890:    Concepts: matrices^getting row maximums

3892: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3893: @*/
3894: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3895: {

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

3906:   (*mat->ops->getrowmax)(mat,v,idx);
3907:   PetscObjectStateIncrease((PetscObject)v);
3908:   return(0);
3909: }

3913: /*@ 
3914:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3915:         row of the matrix

3917:    Collective on Mat and Vec

3919:    Input Parameters:
3920: .  mat - the matrix

3922:    Output Parameter:
3923: +  v - the vector for storing the maximums
3924: -  idx - the indices of the column found for each row (optional)

3926:    Level: intermediate

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

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

3933:    Concepts: matrices^getting row maximums

3935: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3936: @*/
3937: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3938: {

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

3950:   (*mat->ops->getrowmaxabs)(mat,v,idx);
3951:   PetscObjectStateIncrease((PetscObject)v);
3952:   return(0);
3953: }

3957: /*@ 
3958:    MatGetRowSum - Gets the sum of each row of the matrix

3960:    Collective on Mat and Vec

3962:    Input Parameters:
3963: .  mat - the matrix

3965:    Output Parameter:
3966: .  v - the vector for storing the sum of rows

3968:    Level: intermediate

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

3972:    Concepts: matrices^getting row sums

3974: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3975: @*/
3976: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
3977: {
3978:   PetscInt       start = 0, end = 0, row;
3979:   PetscScalar   *array;

3986:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3987:   MatPreallocated(mat);
3988:   MatGetOwnershipRange(mat, &start, &end);
3989:   VecGetArray(v, &array);
3990:   for(row = start; row < end; ++row) {
3991:     PetscInt           ncols, col;
3992:     const PetscInt    *cols;
3993:     const PetscScalar *vals;

3995:     array[row - start] = 0.0;
3996:     MatGetRow(mat, row, &ncols, &cols, &vals);
3997:     for(col = 0; col < ncols; col++) {
3998:       array[row - start] += vals[col];
3999:     }
4000:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
4001:   }
4002:   VecRestoreArray(v, &array);
4003:   PetscObjectStateIncrease((PetscObject) v);
4004:   return(0);
4005: }

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

4012:    Collective on Mat

4014:    Input Parameter:
4015: +  mat - the matrix to transpose
4016: -  reuse - store the transpose matrix in the provided B

4018:    Output Parameters:
4019: .  B - the transpose 

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

4024:    Level: intermediate

4026:    Concepts: matrices^transposing

4028: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4029: @*/
4030: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4031: {

4037:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4038:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4039:   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4040:   MatPreallocated(mat);

4042:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4043:   (*mat->ops->transpose)(mat,reuse,B);
4044:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4045:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4046:   return(0);
4047: }

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

4055:    Collective on Mat

4057:    Input Parameter:
4058: +  A - the matrix to test
4059: -  B - the matrix to test against, this can equal the first parameter

4061:    Output Parameters:
4062: .  flg - the result

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

4069:    Level: intermediate

4071:    Concepts: matrices^transposing, matrix^symmetry

4073: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4074: @*/
4075: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4076: {
4077:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

4083:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
4084:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
4085:   if (f && g) {
4086:     if (f==g) {
4087:       (*f)(A,B,tol,flg);
4088:     } else {
4089:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4090:     }
4091:   }
4092:   return(0);
4093: }

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

4100:    Collective on Mat

4102:    Input Parameter:
4103: +  mat - the matrix to transpose and complex conjugate
4104: -  reuse - store the transpose matrix in the provided B

4106:    Output Parameters:
4107: .  B - the Hermitian

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

4112:    Level: intermediate

4114:    Concepts: matrices^transposing, complex conjugatex

4116: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4117: @*/
4118: PetscErrorCode  MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4119: {

4123:   MatTranspose(mat,reuse,B);
4124: #if defined(PETSC_USE_COMPLEX)
4125:   MatConjugate(*B);
4126: #endif
4127:   return(0);
4128: }

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

4135:    Collective on Mat

4137:    Input Parameter:
4138: +  A - the matrix to test
4139: -  B - the matrix to test against, this can equal the first parameter

4141:    Output Parameters:
4142: .  flg - the result

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

4149:    Level: intermediate

4151:    Concepts: matrices^transposing, matrix^symmetry

4153: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4154: @*/
4155: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4156: {
4157:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

4163:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4164:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4165:   if (f && g) {
4166:     if (f==g) {
4167:       (*f)(A,B,tol,flg);
4168:     } else {
4169:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4170:     }
4171:   }
4172:   return(0);
4173: }

4177: /*@
4178:    MatPermute - Creates a new matrix with rows and columns permuted from the 
4179:    original.

4181:    Collective on Mat

4183:    Input Parameters:
4184: +  mat - the matrix to permute
4185: .  row - row permutation, each processor supplies only the permutation for its rows
4186: -  col - column permutation, each processor needs the entire column permutation, that is
4187:          this is the same size as the total number of columns in the matrix. It can often
4188:          be obtained with ISAllGather() on the row permutation

4190:    Output Parameters:
4191: .  B - the permuted matrix

4193:    Level: advanced

4195:    Concepts: matrices^permuting

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

4199: @*/
4200: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4201: {

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

4215:   (*mat->ops->permute)(mat,row,col,B);
4216:   PetscObjectStateIncrease((PetscObject)*B);
4217:   return(0);
4218: }

4222: /*@
4223:   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the 
4224:   original and sparsified to the prescribed tolerance.

4226:   Collective on Mat

4228:   Input Parameters:
4229: + A    - The matrix to permute
4230: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4231: . frac - The half-bandwidth as a fraction of the total size, or 0.0
4232: . tol  - The drop tolerance
4233: . rowp - The row permutation
4234: - colp - The column permutation

4236:   Output Parameter:
4237: . B    - The permuted, sparsified matrix

4239:   Level: advanced

4241:   Note:
4242:   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4243:   restrict the half-bandwidth of the resulting matrix to 5% of the
4244:   total matrix size.

4246: .keywords: matrix, permute, sparsify

4248: .seealso: MatGetOrdering(), MatPermute()
4249: @*/
4250: PetscErrorCode  MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4251: {
4252:   IS                irowp, icolp;
4253:   const PetscInt    *rows, *cols;
4254:   PetscInt          M, N, locRowStart = 0, locRowEnd = 0;
4255:   PetscInt          nz, newNz;
4256:   const PetscInt    *cwork;
4257:   PetscInt          *cnew;
4258:   const PetscScalar *vwork;
4259:   PetscScalar       *vnew;
4260:   PetscInt          bw, issize;
4261:   PetscInt          row, locRow, newRow, col, newCol;
4262:   PetscErrorCode    ierr;

4269:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4270:   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4271:   if (!A->ops->permutesparsify) {
4272:     MatGetSize(A, &M, &N);
4273:     MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
4274:     ISGetSize(rowp, &issize);
4275:     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4276:     ISGetSize(colp, &issize);
4277:     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4278:     ISInvertPermutation(rowp, 0, &irowp);
4279:     ISGetIndices(irowp, &rows);
4280:     ISInvertPermutation(colp, 0, &icolp);
4281:     ISGetIndices(icolp, &cols);
4282:     PetscMalloc(N*sizeof(PetscInt),&cnew);
4283:     PetscMalloc(N*sizeof(PetscScalar),&vnew);

4285:     /* Setup bandwidth to include */
4286:     if (band == PETSC_DECIDE) {
4287:       if (frac <= 0.0)
4288:         bw = (PetscInt) (M * 0.05);
4289:       else
4290:         bw = (PetscInt) (M * frac);
4291:     } else {
4292:       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4293:       bw = band;
4294:     }

4296:     /* Put values into new matrix */
4297:     MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
4298:     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4299:       MatGetRow(A, row, &nz, &cwork, &vwork);
4300:       newRow   = rows[locRow]+locRowStart;
4301:       for(col = 0, newNz = 0; col < nz; col++) {
4302:         newCol = cols[cwork[col]];
4303:         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4304:           cnew[newNz] = newCol;
4305:           vnew[newNz] = vwork[col];
4306:           newNz++;
4307:         }
4308:       }
4309:       MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
4310:       MatRestoreRow(A, row, &nz, &cwork, &vwork);
4311:     }
4312:     PetscFree(cnew);
4313:     PetscFree(vnew);
4314:     MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
4315:     MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
4316:     ISRestoreIndices(irowp, &rows);
4317:     ISRestoreIndices(icolp, &cols);
4318:     ISDestroy(irowp);
4319:     ISDestroy(icolp);
4320:   } else {
4321:     (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
4322:   }
4323:   PetscObjectStateIncrease((PetscObject)*B);
4324:   return(0);
4325: }

4329: /*@
4330:    MatEqual - Compares two matrices.

4332:    Collective on Mat

4334:    Input Parameters:
4335: +  A - the first matrix
4336: -  B - the second matrix

4338:    Output Parameter:
4339: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4341:    Level: intermediate

4343:    Concepts: matrices^equality between
4344: @*/
4345: PetscErrorCode  MatEqual(Mat A,Mat B,PetscTruth *flg)
4346: {

4356:   MatPreallocated(B);
4357:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4358:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4359:   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);
4360:   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4361:   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4362:   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);
4363:   MatPreallocated(A);

4365:   (*A->ops->equal)(A,B,flg);
4366:   return(0);
4367: }

4371: /*@
4372:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4373:    matrices that are stored as vectors.  Either of the two scaling
4374:    matrices can be PETSC_NULL.

4376:    Collective on Mat

4378:    Input Parameters:
4379: +  mat - the matrix to be scaled
4380: .  l - the left scaling vector (or PETSC_NULL)
4381: -  r - the right scaling vector (or PETSC_NULL)

4383:    Notes:
4384:    MatDiagonalScale() computes A = LAR, where
4385:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)

4387:    Level: intermediate

4389:    Concepts: matrices^diagonal scaling
4390:    Concepts: diagonal scaling of matrices

4392: .seealso: MatScale()
4393: @*/
4394: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4395: {

4401:   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4404:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4405:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4406:   MatPreallocated(mat);

4408:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4409:   (*mat->ops->diagonalscale)(mat,l,r);
4410:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4411:   PetscObjectStateIncrease((PetscObject)mat);
4412:   return(0);
4413: }

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

4420:     Collective on Mat

4422:     Input Parameters:
4423: +   mat - the matrix to be scaled
4424: -   a  - the scaling value

4426:     Output Parameter:
4427: .   mat - the scaled matrix

4429:     Level: intermediate

4431:     Concepts: matrices^scaling all entries

4433: .seealso: MatDiagonalScale()
4434: @*/
4435: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4436: {

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

4447:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4448:   if (a != 1.0) {
4449:     (*mat->ops->scale)(mat,a);
4450:     PetscObjectStateIncrease((PetscObject)mat);
4451:   }
4452:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4453:   return(0);
4454: }

4458: /*@ 
4459:    MatNorm - Calculates various norms of a matrix.

4461:    Collective on Mat

4463:    Input Parameters:
4464: +  mat - the matrix
4465: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4467:    Output Parameters:
4468: .  nrm - the resulting norm 

4470:    Level: intermediate

4472:    Concepts: matrices^norm
4473:    Concepts: norm^of matrix
4474: @*/
4475: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4476: {


4484:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4485:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4486:   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4487:   MatPreallocated(mat);

4489:   (*mat->ops->norm)(mat,type,nrm);
4490:   return(0);
4491: }

4493: /* 
4494:      This variable is used to prevent counting of MatAssemblyBegin() that
4495:    are called from within a MatAssemblyEnd().
4496: */
4497: static PetscInt MatAssemblyEnd_InUse = 0;
4500: /*@
4501:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4502:    be called after completing all calls to MatSetValues().

4504:    Collective on Mat

4506:    Input Parameters:
4507: +  mat - the matrix 
4508: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4509:  
4510:    Notes: 
4511:    MatSetValues() generally caches the values.  The matrix is ready to
4512:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4513:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4514:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4515:    using the matrix.

4517:    Level: beginner

4519:    Concepts: matrices^assembling

4521: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4522: @*/
4523: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4524: {

4530:   MatPreallocated(mat);
4531:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4532:   if (mat->assembled) {
4533:     mat->was_assembled = PETSC_TRUE;
4534:     mat->assembled     = PETSC_FALSE;
4535:   }
4536:   if (!MatAssemblyEnd_InUse) {
4537:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4538:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4539:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4540:   } else {
4541:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4542:   }
4543:   return(0);
4544: }

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

4552:    Collective on Mat

4554:    Input Parameter:
4555: .  mat - the matrix 

4557:    Output Parameter:
4558: .  assembled - PETSC_TRUE or PETSC_FALSE

4560:    Level: advanced

4562:    Concepts: matrices^assembled?

4564: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4565: @*/
4566: PetscErrorCode  MatAssembled(Mat mat,PetscTruth *assembled)
4567: {
4572:   *assembled = mat->assembled;
4573:   return(0);
4574: }

4578: /*
4579:     Processes command line options to determine if/how a matrix
4580:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4581: */
4582: PetscErrorCode MatView_Private(Mat mat)
4583: {
4584:   PetscErrorCode    ierr;
4585:   PetscTruth        flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE;
4586:   static PetscTruth incall = PETSC_FALSE;
4587: #if defined(PETSC_USE_SOCKET_VIEWER)
4588:   PetscTruth        flg5 = PETSC_FALSE;
4589: #endif

4592:   if (incall) return(0);
4593:   incall = PETSC_TRUE;
4594:   PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");
4595:     PetscOptionsTruth("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);
4596:     PetscOptionsTruth("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);
4597:     PetscOptionsTruth("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);
4598:     PetscOptionsTruth("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);
4599: #if defined(PETSC_USE_SOCKET_VIEWER)
4600:     PetscOptionsTruth("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);
4601: #endif
4602:     PetscOptionsTruth("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);
4603:     PetscOptionsTruth("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);
4604:   PetscOptionsEnd();

4606:   if (flg1) {
4607:     PetscViewer viewer;

4609:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4610:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4611:     MatView(mat,viewer);
4612:     PetscViewerPopFormat(viewer);
4613:   }
4614:   if (flg2) {
4615:     PetscViewer viewer;

4617:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4618:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4619:     MatView(mat,viewer);
4620:     PetscViewerPopFormat(viewer);
4621:   }
4622:   if (flg3) {
4623:     PetscViewer viewer;

4625:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4626:     MatView(mat,viewer);
4627:   }
4628:   if (flg4) {
4629:     PetscViewer viewer;

4631:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4632:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4633:     MatView(mat,viewer);
4634:     PetscViewerPopFormat(viewer);
4635:   }
4636: #if defined(PETSC_USE_SOCKET_VIEWER)
4637:   if (flg5) {
4638:     MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4639:     PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4640:   }
4641: #endif
4642:   if (flg6) {
4643:     MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4644:     PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4645:   }
4646:   if (flg7) {
4647:     PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);
4648:     if (flg8) {
4649:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4650:     }
4651:     MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4652:     PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4653:     if (flg8) {
4654:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4655:     }
4656:   }
4657:   incall = PETSC_FALSE;
4658:   return(0);
4659: }

4663: /*@
4664:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4665:    be called after MatAssemblyBegin().

4667:    Collective on Mat

4669:    Input Parameters:
4670: +  mat - the matrix 
4671: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4673:    Options Database Keys:
4674: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4675: .  -mat_view_info_detailed - Prints more detailed info
4676: .  -mat_view - Prints matrix in ASCII format
4677: .  -mat_view_matlab - Prints matrix in Matlab format
4678: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4679: .  -display <name> - Sets display name (default is host)
4680: .  -draw_pause <sec> - Sets number of seconds to pause after display
4681: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4682: .  -viewer_socket_machine <machine>
4683: .  -viewer_socket_port <port>
4684: .  -mat_view_binary - save matrix to file in binary format
4685: -  -viewer_binary_filename <name>

4687:    Notes: 
4688:    MatSetValues() generally caches the values.  The matrix is ready to
4689:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4690:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4691:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4692:    using the matrix.

4694:    Level: beginner

4696: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4697: @*/
4698: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4699: {
4700:   PetscErrorCode  ierr;
4701:   static PetscInt inassm = 0;
4702:   PetscTruth      flg = PETSC_FALSE;


4708:   inassm++;
4709:   MatAssemblyEnd_InUse++;
4710:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4711:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4712:     if (mat->ops->assemblyend) {
4713:       (*mat->ops->assemblyend)(mat,type);
4714:     }
4715:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4716:   } else {
4717:     if (mat->ops->assemblyend) {
4718:       (*mat->ops->assemblyend)(mat,type);
4719:     }
4720:   }

4722:   /* Flush assembly is not a true assembly */
4723:   if (type != MAT_FLUSH_ASSEMBLY) {
4724:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4725:   }
4726:   mat->insertmode = NOT_SET_VALUES;
4727:   MatAssemblyEnd_InUse--;
4728:   PetscObjectStateIncrease((PetscObject)mat);
4729:   if (!mat->symmetric_eternal) {
4730:     mat->symmetric_set              = PETSC_FALSE;
4731:     mat->hermitian_set              = PETSC_FALSE;
4732:     mat->structurally_symmetric_set = PETSC_FALSE;
4733:   }
4734:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4735:     MatView_Private(mat);
4736:     PetscOptionsGetTruth(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg,PETSC_NULL);
4737:     if (flg) {
4738:       PetscReal tol = 0.0;
4739:       PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4740:       MatIsSymmetric(mat,tol,&flg);
4741:       if (flg) {
4742:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4743:       } else {
4744:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4745:       }
4746:     }
4747:   }
4748:   inassm--;
4749:   return(0);
4750: }

4754: /*@
4755:    MatSetOption - Sets a parameter option for a matrix. Some options
4756:    may be specific to certain storage formats.  Some options
4757:    determine how values will be inserted (or added). Sorted, 
4758:    row-oriented input will generally assemble the fastest. The default
4759:    is row-oriented, nonsorted input. 

4761:    Collective on Mat

4763:    Input Parameters:
4764: +  mat - the matrix 
4765: .  option - the option, one of those listed below (and possibly others),
4766: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

4768:   Options Describing Matrix Structure:
4769: +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4770: .    MAT_HERMITIAN - transpose is the complex conjugation
4771: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4772: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4773:                             you set to be kept with all future use of the matrix
4774:                             including after MatAssemblyBegin/End() which could
4775:                             potentially change the symmetry structure, i.e. you 
4776:                             KNOW the matrix will ALWAYS have the property you set.


4779:    Options For Use with MatSetValues():
4780:    Insert a logically dense subblock, which can be
4781: .    MAT_ROW_ORIENTED - row-oriented (default)

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

4787:    When (re)assembling a matrix, we can restrict the input for
4788:    efficiency/debugging purposes.  These options include
4789: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4790:         allowed if they generate a new nonzero
4791: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4792: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4793: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4794: -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly

4796:    Notes:
4797:    Some options are relevant only for particular matrix types and
4798:    are thus ignored by others.  Other options are not supported by
4799:    certain matrix types and will generate an error message if set.

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

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

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

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

4824:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
4825:    other processors should be dropped, rather than stashed.
4826:    This is useful if you know that the "owning" processor is also 
4827:    always generating the correct matrix entries, so that PETSc need
4828:    not transfer duplicate entries generated on another processor.
4829:    
4830:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4831:    searches during matrix assembly. When this flag is set, the hash table
4832:    is created during the first Matrix Assembly. This hash table is
4833:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4834:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 
4835:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4836:    supported by MATMPIBAIJ format only.

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

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

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

4847:    Level: intermediate

4849:    Concepts: matrices^setting options

4851: @*/
4852: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4853: {

4859:   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4860:   MatPreallocated(mat);
4861:   switch (op) {
4862:   case MAT_SYMMETRIC:
4863:     mat->symmetric                  = flg;
4864:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4865:     mat->symmetric_set              = PETSC_TRUE;
4866:     mat->structurally_symmetric_set = flg;
4867:     break;
4868:   case MAT_HERMITIAN:
4869:     mat->hermitian                  = flg;
4870:     if (flg) mat->structurally_symmetric = PETSC_TRUE;
4871:     mat->hermitian_set              = PETSC_TRUE;
4872:     mat->structurally_symmetric_set = flg;
4873:     break;
4874:   case MAT_STRUCTURALLY_SYMMETRIC:
4875:     mat->structurally_symmetric     = flg;
4876:     mat->structurally_symmetric_set = PETSC_TRUE;
4877:     break;
4878:   case MAT_SYMMETRY_ETERNAL:
4879:     mat->symmetric_eternal          = flg;
4880:     break;
4881:   default:
4882:     break;
4883:   }
4884:   if (mat->ops->setoption) {
4885:     (*mat->ops->setoption)(mat,op,flg);
4886:   }
4887:   return(0);
4888: }

4892: /*@
4893:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4894:    this routine retains the old nonzero structure.

4896:    Collective on Mat

4898:    Input Parameters:
4899: .  mat - the matrix 

4901:    Level: intermediate

4903:    Concepts: matrices^zeroing

4905: .seealso: MatZeroRows()
4906: @*/
4907: PetscErrorCode  MatZeroEntries(Mat mat)
4908: {

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

4919:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
4920:   (*mat->ops->zeroentries)(mat);
4921:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
4922:   PetscObjectStateIncrease((PetscObject)mat);
4923:   return(0);
4924: }

4928: /*@C
4929:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4930:    of a set of rows of a matrix.

4932:    Collective on Mat

4934:    Input Parameters:
4935: +  mat - the matrix
4936: .  numRows - the number of rows to remove
4937: .  rows - the global row indices
4938: -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)

4940:    Notes:
4941:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4942:    but does not release memory.  For the dense and block diagonal
4943:    formats this does not alter the nonzero structure.

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

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

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

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

4961:    Level: intermediate

4963:    Concepts: matrices^zeroing rows

4965: .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4966: @*/
4967: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4968: {

4975:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4976:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4977:   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4978:   MatPreallocated(mat);

4980:   (*mat->ops->zerorows)(mat,numRows,rows,diag);
4981:   MatView_Private(mat);
4982:   PetscObjectStateIncrease((PetscObject)mat);
4983:   return(0);
4984: }

4988: /*@C
4989:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4990:    of a set of rows of a matrix.

4992:    Collective on Mat

4994:    Input Parameters:
4995: +  mat - the matrix
4996: .  is - index set of rows to remove
4997: -  diag - value put in all diagonals of eliminated rows

4999:    Notes:
5000:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5001:    but does not release memory.  For the dense and block diagonal
5002:    formats this does not alter the nonzero structure.

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

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

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

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

5019:    Level: intermediate

5021:    Concepts: matrices^zeroing rows

5023: .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5024: @*/
5025: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
5026: {
5027:   PetscInt       numRows;
5028:   const PetscInt *rows;

5035:   ISGetLocalSize(is,&numRows);
5036:   ISGetIndices(is,&rows);
5037:   MatZeroRows(mat,numRows,rows,diag);
5038:   ISRestoreIndices(is,&rows);
5039:   return(0);
5040: }

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

5048:    Collective on Mat

5050:    Input Parameters:
5051: +  mat - the matrix
5052: .  numRows - the number of rows to remove
5053: .  rows - the global row indices
5054: -  diag - value put in all diagonals of eliminated rows

5056:    Notes:
5057:    Before calling MatZeroRowsLocal(), the user must first set the
5058:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5060:    For the AIJ matrix formats this removes the old nonzero structure,
5061:    but does not release memory.  For the dense and block diagonal
5062:    formats this does not alter the nonzero structure.

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

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

5072:    Level: intermediate

5074:    Concepts: matrices^zeroing

5076: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5077: @*/
5078: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
5079: {

5086:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5087:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5088:   MatPreallocated(mat);

5090:   if (mat->ops->zerorowslocal) {
5091:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);
5092:   } else {
5093:     IS             is, newis;
5094:     const PetscInt *newRows;

5096:     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5097:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);
5098:     ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
5099:     ISGetIndices(newis,&newRows);
5100:     (*mat->ops->zerorows)(mat,numRows,newRows,diag);
5101:     ISRestoreIndices(newis,&newRows);
5102:     ISDestroy(newis);
5103:     ISDestroy(is);
5104:   }
5105:   PetscObjectStateIncrease((PetscObject)mat);
5106:   return(0);
5107: }

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

5115:    Collective on Mat

5117:    Input Parameters:
5118: +  mat - the matrix
5119: .  is - index set of rows to remove
5120: -  diag - value put in all diagonals of eliminated rows

5122:    Notes:
5123:    Before calling MatZeroRowsLocalIS(), the user must first set the
5124:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5126:    For the AIJ matrix formats this removes the old nonzero structure,
5127:    but does not release memory.  For the dense and block diagonal
5128:    formats this does not alter the nonzero structure.

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

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

5138:    Level: intermediate

5140:    Concepts: matrices^zeroing

5142: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5143: @*/
5144: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5145: {
5147:   PetscInt       numRows;
5148:   const PetscInt *rows;

5154:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5155:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5156:   MatPreallocated(mat);

5158:   ISGetLocalSize(is,&numRows);
5159:   ISGetIndices(is,&rows);
5160:   MatZeroRowsLocal(mat,numRows,rows,diag);
5161:   ISRestoreIndices(is,&rows);
5162:   return(0);
5163: }

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

5170:    Not Collective

5172:    Input Parameter:
5173: .  mat - the matrix

5175:    Output Parameters:
5176: +  m - the number of global rows
5177: -  n - the number of global columns

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

5181:    Level: beginner

5183:    Concepts: matrices^size

5185: .seealso: MatGetLocalSize()
5186: @*/
5187: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5188: {
5191:   if (m) *m = mat->rmap->N;
5192:   if (n) *n = mat->cmap->N;
5193:   return(0);
5194: }

5198: /*@
5199:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5200:    stored locally.  This information may be implementation dependent, so
5201:    use with care.

5203:    Not Collective

5205:    Input Parameters:
5206: .  mat - the matrix

5208:    Output Parameters:
5209: +  m - the number of local rows
5210: -  n - the number of local columns

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

5214:    Level: beginner

5216:    Concepts: matrices^local size

5218: .seealso: MatGetSize()
5219: @*/
5220: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5221: {
5226:   if (m) *m = mat->rmap->n;
5227:   if (n) *n = mat->cmap->n;
5228:   return(0);
5229: }

5233: /*@
5234:    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5235:    this processor.

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

5239:    Input Parameters:
5240: .  mat - the matrix

5242:    Output Parameters:
5243: +  m - the global index of the first local column
5244: -  n - one more than the global index of the last local column

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

5248:    Level: developer

5250:    Concepts: matrices^column ownership

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

5254: @*/
5255: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5256: {

5264:   MatPreallocated(mat);
5265:   if (m) *m = mat->cmap->rstart;
5266:   if (n) *n = mat->cmap->rend;
5267:   return(0);
5268: }

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

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

5280:    Input Parameters:
5281: .  mat - the matrix

5283:    Output Parameters:
5284: +  m - the global index of the first local row
5285: -  n - one more than the global index of the last local row

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

5289:    Level: beginner

5291:    Concepts: matrices^row ownership

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

5295: @*/
5296: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5297: {

5305:   MatPreallocated(mat);
5306:   if (m) *m = mat->rmap->rstart;
5307:   if (n) *n = mat->rmap->rend;
5308:   return(0);
5309: }

5313: /*@C
5314:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5315:    each process

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

5319:    Input Parameters:
5320: .  mat - the matrix

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

5325:    Level: beginner

5327:    Concepts: matrices^row ownership

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

5331: @*/
5332: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5333: {

5339:   MatPreallocated(mat);
5340:   PetscLayoutGetRanges(mat->rmap,ranges);
5341:   return(0);
5342: }

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

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

5351:    Input Parameters:
5352: .  mat - the matrix

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

5357:    Level: beginner

5359:    Concepts: matrices^column ownership

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

5363: @*/
5364: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5365: {

5371:   MatPreallocated(mat);
5372:   PetscLayoutGetRanges(mat->cmap,ranges);
5373:   return(0);
5374: }

5378: /*@C
5379:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5380:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
5381:    to complete the factorization.

5383:    Collective on Mat

5385:    Input Parameters:
5386: +  mat - the matrix
5387: .  row - row permutation
5388: .  column - column permutation
5389: -  info - structure containing 
5390: $      levels - number of levels of fill.
5391: $      expected fill - as ratio of original fill.
5392: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5393:                 missing diagonal entries)

5395:    Output Parameters:
5396: .  fact - new matrix that has been symbolically factored

5398:    Notes:
5399:    See the users manual for additional information about
5400:    choosing the fill factor for better efficiency.

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

5406:    Level: developer

5408:   Concepts: matrices^symbolic LU factorization
5409:   Concepts: matrices^factorization
5410:   Concepts: LU^symbolic factorization

5412: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5413:           MatGetOrdering(), MatFactorInfo

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

5418: @*/
5419: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5420: {

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

5437:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
5438:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
5439:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
5440:   return(0);
5441: }

5445: /*@C
5446:    MatICCFactorSymbolic - Performs symbolic incomplete
5447:    Cholesky factorization for a symmetric matrix.  Use 
5448:    MatCholeskyFactorNumeric() to complete the factorization.

5450:    Collective on Mat

5452:    Input Parameters:
5453: +  mat - the matrix
5454: .  perm - row and column permutation
5455: -  info - structure containing 
5456: $      levels - number of levels of fill.
5457: $      expected fill - as ratio of original fill.

5459:    Output Parameter:
5460: .  fact - the factored matrix

5462:    Notes:
5463:    Most users should employ the KSP interface for linear solvers
5464:    instead of working directly with matrix algebra routines such as this.
5465:    See, e.g., KSPCreate().

5467:    Level: developer

5469:   Concepts: matrices^symbolic incomplete Cholesky factorization
5470:   Concepts: matrices^factorization
5471:   Concepts: Cholsky^symbolic factorization

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

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

5478: @*/
5479: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5480: {

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

5496:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
5497:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
5498:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
5499:   return(0);
5500: }

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

5510:    Not Collective

5512:    Input Parameter:
5513: .  mat - the matrix

5515:    Output Parameter:
5516: .  v - the location of the values


5519:    Fortran Note:
5520:    This routine is used differently from Fortran, e.g.,
5521: .vb
5522:         Mat         mat
5523:         PetscScalar mat_array(1)
5524:         PetscOffset i_mat
5525:         PetscErrorCode ierr
5526:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5532:         [... other code ...]
5533:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5534: .ve

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

5539:    Level: advanced

5541:    Concepts: matrices^access array

5543: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5544: @*/
5545: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
5546: {

5553:   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5554:   MatPreallocated(mat);
5555:   (*mat->ops->getarray)(mat,v);
5556:   CHKMEMQ;
5557:   return(0);
5558: }

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

5565:    Not Collective

5567:    Input Parameter:
5568: +  mat - the matrix
5569: -  v - the location of the values

5571:    Fortran Note:
5572:    This routine is used differently from Fortran, e.g.,
5573: .vb
5574:         Mat         mat
5575:         PetscScalar mat_array(1)
5576:         PetscOffset i_mat
5577:         PetscErrorCode ierr
5578:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5584:         [... other code ...]
5585:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5586: .ve

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

5591:    Level: advanced

5593: .seealso: MatGetArray(), MatRestoreArrayF90()
5594: @*/
5595: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
5596: {

5603: #if defined(PETSC_USE_DEBUG)
5604:   CHKMEMQ;
5605: #endif
5606:   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5607:   (*mat->ops->restorearray)(mat,v);
5608:   PetscObjectStateIncrease((PetscObject)mat);
5609:   return(0);
5610: }

5614: /*@C
5615:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5616:    points to an array of valid matrices, they may be reused to store the new
5617:    submatrices.

5619:    Collective on Mat

5621:    Input Parameters:
5622: +  mat - the matrix
5623: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5624: .  irow, icol - index sets of rows and columns to extract
5625: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

5627:    Output Parameter:
5628: .  submat - the array of submatrices

5630:    Notes:
5631:    MatGetSubMatrices() can extract ONLY sequential submatrices
5632:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5633:    to extract a parallel submatrix.

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

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

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

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

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

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

5657:    Level: advanced

5659:    Concepts: matrices^accessing submatrices
5660:    Concepts: submatrices

5662: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5663: @*/
5664: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5665: {
5667:   PetscInt        i;
5668:   PetscTruth      eq;

5673:   if (n) {
5678:   }
5680:   if (n && scall == MAT_REUSE_MATRIX) {
5683:   }
5684:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5685:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5686:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5687:   MatPreallocated(mat);

5689:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
5690:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
5691:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
5692:   for (i=0; i<n; i++) {
5693:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5694:       ISEqual(irow[i],icol[i],&eq);
5695:       if (eq) {
5696:         if (mat->symmetric){
5697:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
5698:         } else if (mat->hermitian) {
5699:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
5700:         } else if (mat->structurally_symmetric) {
5701:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
5702:         }
5703:       }
5704:     }
5705:   }
5706:   return(0);
5707: }

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

5714:    Collective on Mat

5716:    Input Parameters:
5717: +  n - the number of local matrices
5718: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5719:                        sequence of MatGetSubMatrices())

5721:    Level: advanced

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

5726: .seealso: MatGetSubMatrices()
5727: @*/
5728: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
5729: {
5731:   PetscInt       i;

5734:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5736:   for (i=0; i<n; i++) {
5737:     MatDestroy((*mat)[i]);
5738:   }
5739:   /* memory is allocated even if n = 0 */
5740:   PetscFree(*mat);
5741:   return(0);
5742: }

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

5749:    Collective on Mat

5751:    Input Parameters:
5752: .  mat - the matrix

5754:    Output Parameter:
5755: .  matstruct - the sequential matrix with the nonzero structure of mat

5757:   Level: intermediate

5759: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5760: @*/
5761: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
5762: {

5768: 
5770:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5771:   MatPreallocated(mat);

5773:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
5774:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5775:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5776:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5777:   return(0);
5778: }

5782: /*@C
5783:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

5785:    Collective on Mat

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

5791:    Level: advanced

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

5795: .seealso: MatGetSeqNonzeroStructure()
5796: @*/
5797: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
5798: {

5803:   MatDestroy(*mat);
5804:   return(0);
5805: }

5809: /*@
5810:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5811:    replaces the index sets by larger ones that represent submatrices with
5812:    additional overlap.

5814:    Collective on Mat

5816:    Input Parameters:
5817: +  mat - the matrix
5818: .  n   - the number of index sets
5819: .  is  - the array of index sets (these index sets will changed during the call)
5820: -  ov  - the additional overlap requested

5822:    Level: developer

5824:    Concepts: overlap
5825:    Concepts: ASM^computing overlap

5827: .seealso: MatGetSubMatrices()
5828: @*/
5829: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5830: {

5836:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5837:   if (n) {
5840:   }
5841:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5842:   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5843:   MatPreallocated(mat);

5845:   if (!ov) return(0);
5846:   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5847:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5848:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
5849:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5850:   return(0);
5851: }

5855: /*@
5856:    MatGetBlockSize - Returns the matrix block size; useful especially for the
5857:    block row and block diagonal formats.
5858:    
5859:    Not Collective

5861:    Input Parameter:
5862: .  mat - the matrix

5864:    Output Parameter:
5865: .  bs - block size

5867:    Notes:
5868:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

5870:    Level: intermediate

5872:    Concepts: matrices^block size

5874: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5875: @*/
5876: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
5877: {

5884:   MatPreallocated(mat);
5885:   *bs = mat->rmap->bs;
5886:   return(0);
5887: }

5891: /*@
5892:    MatSetBlockSize - Sets the matrix block size; for many matrix types you 
5893:      cannot use this and MUST set the blocksize when you preallocate the matrix
5894:    
5895:    Collective on Mat

5897:    Input Parameters:
5898: +  mat - the matrix
5899: -  bs - block size

5901:    Notes:
5902:      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
5903:      it is not possible to change BAIJ block sizes after preallocation.

5905:    Level: intermediate

5907:    Concepts: matrices^block size

5909: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5910: @*/
5911: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
5912: {

5918:   MatPreallocated(mat);
5919:   if (bs < 1) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Block size %d, must be positive",bs);
5920:   if (mat->ops->setblocksize) {
5921:     (*mat->ops->setblocksize)(mat,bs);
5922:   } else {
5923:     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5924:   }
5925:   return(0);
5926: }

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

5933:    Collective on Mat

5935:     Input Parameters:
5936: +   mat - the matrix
5937: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5938: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5939:                 symmetrized
5940: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5941:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
5942:                  always used.

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

5951:     Level: developer

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

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

5957:     Fortran Node

5959:            In Fortran use
5960: $           PetscInt ia(1), ja(1)
5961: $           PetscOffset iia, jja
5962: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
5963: $
5964: $          or 
5965: $
5966: $           PetscScalar, pointer :: xx_v(:)
5967: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
5968:   
5969:  
5970:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

5972: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5973: @*/
5974: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5975: {

5985:   MatPreallocated(mat);
5986:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5987:   else {
5988:     *done = PETSC_TRUE;
5989:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
5990:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
5991:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
5992:   }
5993:   return(0);
5994: }

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

6001:     Collective on Mat

6003:     Input Parameters:
6004: +   mat - the matrix
6005: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6006: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6007:                 symmetrized
6008: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6009:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6010:                  always used.

6012:     Output Parameters:
6013: +   n - number of columns in the (possibly compressed) matrix
6014: .   ia - the column pointers
6015: .   ja - the row indices
6016: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6018:     Level: developer

6020: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6021: @*/
6022: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6023: {

6033:   MatPreallocated(mat);
6034:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6035:   else {
6036:     *done = PETSC_TRUE;
6037:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6038:   }
6039:   return(0);
6040: }

6044: /*@C
6045:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6046:     MatGetRowIJ().

6048:     Collective on Mat

6050:     Input Parameters:
6051: +   mat - the matrix
6052: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6053: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6054:                 symmetrized
6055: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6056:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6057:                  always used.

6059:     Output Parameters:
6060: +   n - size of (possibly compressed) matrix
6061: .   ia - the row pointers
6062: .   ja - the column indices
6063: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6065:     Level: developer

6067: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6068: @*/
6069: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6070: {

6079:   MatPreallocated(mat);

6081:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6082:   else {
6083:     *done = PETSC_TRUE;
6084:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6085:   }
6086:   return(0);
6087: }

6091: /*@C
6092:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6093:     MatGetColumnIJ().

6095:     Collective on Mat

6097:     Input Parameters:
6098: +   mat - the matrix
6099: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6100: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6101:                 symmetrized
6102: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6103:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6104:                  always used.

6106:     Output Parameters:
6107: +   n - size of (possibly compressed) matrix
6108: .   ia - the column pointers
6109: .   ja - the row indices
6110: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6112:     Level: developer

6114: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6115: @*/
6116: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6117: {

6126:   MatPreallocated(mat);

6128:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6129:   else {
6130:     *done = PETSC_TRUE;
6131:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6132:   }
6133:   return(0);
6134: }

6138: /*@C
6139:     MatColoringPatch -Used inside matrix coloring routines that 
6140:     use MatGetRowIJ() and/or MatGetColumnIJ().

6142:     Collective on Mat

6144:     Input Parameters:
6145: +   mat - the matrix
6146: .   ncolors - max color value
6147: .   n   - number of entries in colorarray
6148: -   colorarray - array indicating color for each column

6150:     Output Parameters:
6151: .   iscoloring - coloring generated using colorarray information

6153:     Level: developer

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

6157: @*/
6158: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6159: {

6167:   MatPreallocated(mat);

6169:   if (!mat->ops->coloringpatch){
6170:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6171:   } else {
6172:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6173:   }
6174:   return(0);
6175: }


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

6183:    Collective on Mat

6185:    Input Parameter:
6186: .  mat - the factored matrix to be reset

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

6195:    Note that one can specify in-place ILU(0) factorization by calling 
6196: .vb
6197:      PCType(pc,PCILU);
6198:      PCFactorSeUseInPlace(pc);
6199: .ve
6200:    or by using the options -pc_type ilu -pc_factor_in_place

6202:    In-place factorization ILU(0) can also be used as a local
6203:    solver for the blocks within the block Jacobi or additive Schwarz
6204:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion 
6205:    of these preconditioners in the users manual for details on setting
6206:    local solver options.

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

6212:    Level: developer

6214: .seealso: PCFactorSetUseInPlace()

6216:    Concepts: matrices^unfactored

6218: @*/
6219: PetscErrorCode  MatSetUnfactored(Mat mat)
6220: {

6226:   MatPreallocated(mat);
6227:   mat->factor = MAT_FACTOR_NONE;
6228:   if (!mat->ops->setunfactored) return(0);
6229:   (*mat->ops->setunfactored)(mat);
6230:   return(0);
6231: }

6233: /*MC
6234:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

6236:     Synopsis:
6237:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6239:     Not collective

6241:     Input Parameter:
6242: .   x - matrix

6244:     Output Parameters:
6245: +   xx_v - the Fortran90 pointer to the array
6246: -   ierr - error code

6248:     Example of Usage: 
6249: .vb
6250:       PetscScalar, pointer xx_v(:)
6251:       ....
6252:       call MatGetArrayF90(x,xx_v,ierr)
6253:       a = xx_v(3)
6254:       call MatRestoreArrayF90(x,xx_v,ierr)
6255: .ve

6257:     Notes:
6258:     Not yet supported for all F90 compilers

6260:     Level: advanced

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

6264:     Concepts: matrices^accessing array

6266: M*/

6268: /*MC
6269:     MatRestoreArrayF90 - Restores a matrix array that has been
6270:     accessed with MatGetArrayF90().

6272:     Synopsis:
6273:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6275:     Not collective

6277:     Input Parameters:
6278: +   x - matrix
6279: -   xx_v - the Fortran90 pointer to the array

6281:     Output Parameter:
6282: .   ierr - error code

6284:     Example of Usage: 
6285: .vb
6286:        PetscScalar, pointer xx_v(:)
6287:        ....
6288:        call MatGetArrayF90(x,xx_v,ierr)
6289:        a = xx_v(3)
6290:        call MatRestoreArrayF90(x,xx_v,ierr)
6291: .ve
6292:    
6293:     Notes:
6294:     Not yet supported for all F90 compilers

6296:     Level: advanced

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

6300: M*/


6305: /*@
6306:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6307:                       as the original matrix.

6309:     Collective on Mat

6311:     Input Parameters:
6312: +   mat - the original matrix
6313: .   isrow - parallel IS containing the rows this processor should obtain
6314: .   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.
6315: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6317:     Output Parameter:
6318: .   newmat - the new submatrix, of the same type as the old

6320:     Level: advanced

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

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

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

6333:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6334:     the input matrix.

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

6338:    Example usage:
6339:    Consider the following 8x8 matrix with 34 non-zero values, that is
6340:    assembled across 3 processors. Lets assume that proc0 owns 3 rows,
6341:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6342:    as follows:

6344: .vb
6345:             1  2  0  |  0  3  0  |  0  4
6346:     Proc0   0  5  6  |  7  0  0  |  8  0
6347:             9  0 10  | 11  0  0  | 12  0
6348:     -------------------------------------
6349:            13  0 14  | 15 16 17  |  0  0
6350:     Proc1   0 18  0  | 19 20 21  |  0  0
6351:             0  0  0  | 22 23  0  | 24  0
6352:     -------------------------------------
6353:     Proc2  25 26 27  |  0  0 28  | 29  0
6354:            30  0  0  | 31 32 33  |  0 34
6355: .ve

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

6359: .vb
6360:             2  0  |  0  3  0  |  0
6361:     Proc0   5  6  |  7  0  0  |  8
6362:     -------------------------------
6363:     Proc1  18  0  | 19 20 21  |  0
6364:     -------------------------------
6365:     Proc2  26 27  |  0  0 28  | 29
6366:             0  0  | 31 32 33  |  0
6367: .ve


6370:     Concepts: matrices^submatrices

6372: .seealso: MatGetSubMatrices()
6373: @*/
6374: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
6375: {
6377:   PetscMPIInt    size;
6378:   Mat            *local;
6379:   IS             iscoltmp;

6388:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6389:   MatPreallocated(mat);
6390:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

6392:   if (!iscol) {
6393:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
6394:   } else {
6395:     iscoltmp = iscol;
6396:   }

6398:   /* if original matrix is on just one processor then use submatrix generated */
6399:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6400:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6401:     if (!iscol) {ISDestroy(iscoltmp);}
6402:     return(0);
6403:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
6404:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6405:     *newmat = *local;
6406:     PetscFree(local);
6407:     if (!iscol) {ISDestroy(iscoltmp);}
6408:     return(0);
6409:   } else if (!mat->ops->getsubmatrix) {
6410:     /* Create a new matrix type that implements the operation using the full matrix */
6411:     switch (cll) {
6412:       case MAT_INITIAL_MATRIX:
6413:         MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
6414:         break;
6415:       case MAT_REUSE_MATRIX:
6416:         MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
6417:         break;
6418:       default: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
6419:     }
6420:     if (!iscol) {ISDestroy(iscoltmp);}
6421:     return(0);
6422:   }

6424:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6425:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
6426:   if (!iscol) {ISDestroy(iscoltmp);}
6427:   PetscObjectStateIncrease((PetscObject)*newmat);
6428:   return(0);
6429: }

6433: /*@
6434:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6435:    used during the assembly process to store values that belong to 
6436:    other processors.

6438:    Not Collective

6440:    Input Parameters:
6441: +  mat   - the matrix
6442: .  size  - the initial size of the stash.
6443: -  bsize - the initial size of the block-stash(if used).

6445:    Options Database Keys:
6446: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6447: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

6449:    Level: intermediate

6451:    Notes: 
6452:      The block-stash is used for values set with MatSetValuesBlocked() while
6453:      the stash is used for values set with MatSetValues()

6455:      Run with the option -info and look for output of the form
6456:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6457:      to determine the appropriate value, MM, to use for size and 
6458:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6459:      to determine the value, BMM to use for bsize

6461:    Concepts: stash^setting matrix size
6462:    Concepts: matrices^stash

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

6466: @*/
6467: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6468: {

6474:   MatStashSetInitialSize_Private(&mat->stash,size);
6475:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
6476:   return(0);
6477: }

6481: /*@
6482:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
6483:      the matrix

6485:    Collective on Mat

6487:    Input Parameters:
6488: +  mat   - the matrix
6489: .  x,y - the vectors
6490: -  w - where the result is stored

6492:    Level: intermediate

6494:    Notes: 
6495:     w may be the same vector as y. 

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

6500:     Concepts: interpolation

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

6504: @*/
6505: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6506: {
6508:   PetscInt       M,N;

6516:   MatPreallocated(A);
6517:   MatGetSize(A,&M,&N);
6518:   if (N > M) {
6519:     MatMultTransposeAdd(A,x,y,w);
6520:   } else {
6521:     MatMultAdd(A,x,y,w);
6522:   }
6523:   return(0);
6524: }

6528: /*@
6529:    MatInterpolate - y = A*x or A'*x depending on the shape of 
6530:      the matrix

6532:    Collective on Mat

6534:    Input Parameters:
6535: +  mat   - the matrix
6536: -  x,y - the vectors

6538:    Level: intermediate

6540:    Notes: 
6541:     This allows one to use either the restriction or interpolation (its transpose)
6542:     matrix to do the interpolation

6544:    Concepts: matrices^interpolation

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

6548: @*/
6549: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
6550: {
6552:   PetscInt       M,N;

6559:   MatPreallocated(A);
6560:   MatGetSize(A,&M,&N);
6561:   if (N > M) {
6562:     MatMultTranspose(A,x,y);
6563:   } else {
6564:     MatMult(A,x,y);
6565:   }
6566:   return(0);
6567: }

6571: /*@
6572:    MatRestrict - y = A*x or A'*x

6574:    Collective on Mat

6576:    Input Parameters:
6577: +  mat   - the matrix
6578: -  x,y - the vectors

6580:    Level: intermediate

6582:    Notes: 
6583:     This allows one to use either the restriction or interpolation (its transpose)
6584:     matrix to do the restriction

6586:    Concepts: matrices^restriction

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

6590: @*/
6591: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
6592: {
6594:   PetscInt       M,N;

6601:   MatPreallocated(A);

6603:   MatGetSize(A,&M,&N);
6604:   if (N > M) {
6605:     MatMult(A,x,y);
6606:   } else {
6607:     MatMultTranspose(A,x,y);
6608:   }
6609:   return(0);
6610: }

6614: /*@
6615:    MatNullSpaceAttach - attaches a null space to a matrix.
6616:         This null space will be removed from the resulting vector whenever
6617:         MatMult() is called

6619:    Collective on Mat

6621:    Input Parameters:
6622: +  mat - the matrix
6623: -  nullsp - the null space object

6625:    Level: developer

6627:    Notes:
6628:       Overwrites any previous null space that may have been attached

6630:    Concepts: null space^attaching to matrix

6632: .seealso: MatCreate(), MatNullSpaceCreate()
6633: @*/
6634: PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6635: {

6642:   MatPreallocated(mat);
6643:   PetscObjectReference((PetscObject)nullsp);
6644:   if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6645:   mat->nullsp = nullsp;
6646:   return(0);
6647: }

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

6654:    Collective on Mat

6656:    Input Parameters:
6657: +  mat - the matrix
6658: .  row - row/column permutation
6659: .  fill - expected fill factor >= 1.0
6660: -  level - level of fill, for ICC(k)

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

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

6670:    Level: developer

6672:    Concepts: matrices^incomplete Cholesky factorization
6673:    Concepts: Cholesky factorization

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

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

6680: @*/
6681: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6682: {

6690:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6691:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6692:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6693:   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6694:   MatPreallocated(mat);
6695:   (*mat->ops->iccfactor)(mat,row,info);
6696:   PetscObjectStateIncrease((PetscObject)mat);
6697:   return(0);
6698: }

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

6705:    Not Collective

6707:    Input Parameters:
6708: +  mat - the matrix
6709: -  v - the values compute with ADIC

6711:    Level: developer

6713:    Notes:
6714:      Must call MatSetColoring() before using this routine. Also this matrix must already
6715:      have its nonzero pattern determined.

6717: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6718:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6719: @*/
6720: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
6721: {


6729:   if (!mat->assembled) {
6730:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6731:   }
6732:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6733:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6734:   (*mat->ops->setvaluesadic)(mat,v);
6735:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6736:   MatView_Private(mat);
6737:   PetscObjectStateIncrease((PetscObject)mat);
6738:   return(0);
6739: }


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

6747:    Not Collective

6749:    Input Parameters:
6750: +  mat - the matrix
6751: -  coloring - the coloring

6753:    Level: developer

6755: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6756:           MatSetValues(), MatSetValuesAdic()
6757: @*/
6758: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
6759: {


6767:   if (!mat->assembled) {
6768:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6769:   }
6770:   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6771:   (*mat->ops->setcoloring)(mat,coloring);
6772:   return(0);
6773: }

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

6780:    Not Collective

6782:    Input Parameters:
6783: +  mat - the matrix
6784: .  nl - leading dimension of v
6785: -  v - the values compute with ADIFOR

6787:    Level: developer

6789:    Notes:
6790:      Must call MatSetColoring() before using this routine. Also this matrix must already
6791:      have its nonzero pattern determined.

6793: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6794:           MatSetValues(), MatSetColoring()
6795: @*/
6796: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6797: {


6805:   if (!mat->assembled) {
6806:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6807:   }
6808:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6809:   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6810:   (*mat->ops->setvaluesadifor)(mat,nl,v);
6811:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6812:   PetscObjectStateIncrease((PetscObject)mat);
6813:   return(0);
6814: }

6818: /*@ 
6819:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
6820:          ghosted ones.

6822:    Not Collective

6824:    Input Parameters:
6825: +  mat - the matrix
6826: -  diag = the diagonal values, including ghost ones

6828:    Level: developer

6830:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6831:       
6832: .seealso: MatDiagonalScale()
6833: @*/
6834: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
6835: {
6837:   PetscMPIInt    size;


6844:   if (!mat->assembled) {
6845:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6846:   }
6847:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6848:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
6849:   if (size == 1) {
6850:     PetscInt n,m;
6851:     VecGetSize(diag,&n);
6852:     MatGetSize(mat,0,&m);
6853:     if (m == n) {
6854:       MatDiagonalScale(mat,0,diag);
6855:     } else {
6856:       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6857:     }
6858:   } else {
6859:     PetscErrorCode (*f)(Mat,Vec);
6860:     PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6861:     if (f) {
6862:       (*f)(mat,diag);
6863:     } else {
6864:       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6865:     }
6866:   }
6867:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6868:   PetscObjectStateIncrease((PetscObject)mat);
6869:   return(0);
6870: }

6874: /*@ 
6875:    MatGetInertia - Gets the inertia from a factored matrix

6877:    Collective on Mat

6879:    Input Parameter:
6880: .  mat - the matrix

6882:    Output Parameters:
6883: +   nneg - number of negative eigenvalues
6884: .   nzero - number of zero eigenvalues
6885: -   npos - number of positive eigenvalues

6887:    Level: advanced

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


6892: @*/
6893: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6894: {

6900:   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6901:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6902:   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6903:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6904:   return(0);
6905: }

6907: /* ----------------------------------------------------------------*/
6910: /*@C
6911:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

6913:    Collective on Mat and Vecs

6915:    Input Parameters:
6916: +  mat - the factored matrix
6917: -  b - the right-hand-side vectors

6919:    Output Parameter:
6920: .  x - the result vectors

6922:    Notes:
6923:    The vectors b and x cannot be the same.  I.e., one cannot
6924:    call MatSolves(A,x,x).

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

6931:    Level: developer

6933:    Concepts: matrices^triangular solves

6935: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6936: @*/
6937: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
6938: {

6944:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6945:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6946:   if (!mat->rmap->N && !mat->cmap->N) return(0);

6948:   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6949:   MatPreallocated(mat);
6950:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6951:   (*mat->ops->solves)(mat,b,x);
6952:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6953:   return(0);
6954: }

6958: /*@
6959:    MatIsSymmetric - Test whether a matrix is symmetric

6961:    Collective on Mat

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

6967:    Output Parameters:
6968: .  flg - the result

6970:    Level: intermediate

6972:    Concepts: matrix^symmetry

6974: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6975: @*/
6976: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6977: {


6984:   if (!A->symmetric_set) {
6985:     if (!A->ops->issymmetric) {
6986:       const MatType mattype;
6987:       MatGetType(A,&mattype);
6988:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6989:     }
6990:     (*A->ops->issymmetric)(A,tol,flg);
6991:     if (!tol) {
6992:       A->symmetric_set = PETSC_TRUE;
6993:       A->symmetric = *flg;
6994:       if (A->symmetric) {
6995:         A->structurally_symmetric_set = PETSC_TRUE;
6996:         A->structurally_symmetric     = PETSC_TRUE;
6997:       }
6998:     }
6999:   } else if (A->symmetric) {
7000:     *flg = PETSC_TRUE;
7001:   } else if (!tol) {
7002:     *flg = PETSC_FALSE;
7003:   } else {
7004:     if (!A->ops->issymmetric) {
7005:       const MatType mattype;
7006:       MatGetType(A,&mattype);
7007:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7008:     }
7009:     (*A->ops->issymmetric)(A,tol,flg);
7010:   }
7011:   return(0);
7012: }

7016: /*@
7017:    MatIsHermitian - Test whether a matrix is Hermitian

7019:    Collective on Mat

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

7025:    Output Parameters:
7026: .  flg - the result

7028:    Level: intermediate

7030:    Concepts: matrix^symmetry

7032: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7033: @*/
7034: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
7035: {


7042:   if (!A->hermitian_set) {
7043:     if (!A->ops->ishermitian) {
7044:       const MatType mattype;
7045:       MatGetType(A,&mattype);
7046:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7047:     }
7048:     (*A->ops->ishermitian)(A,tol,flg);
7049:     if (!tol) {
7050:       A->hermitian_set = PETSC_TRUE;
7051:       A->hermitian = *flg;
7052:       if (A->hermitian) {
7053:         A->structurally_symmetric_set = PETSC_TRUE;
7054:         A->structurally_symmetric     = PETSC_TRUE;
7055:       }
7056:     }
7057:   } else if (A->hermitian) {
7058:     *flg = PETSC_TRUE;
7059:   } else if (!tol) {
7060:     *flg = PETSC_FALSE;
7061:   } else {
7062:     if (!A->ops->ishermitian) {
7063:       const MatType mattype;
7064:       MatGetType(A,&mattype);
7065:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7066:     }
7067:     (*A->ops->ishermitian)(A,tol,flg);
7068:   }
7069:   return(0);
7070: }

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

7077:    Collective on Mat

7079:    Input Parameter:
7080: .  A - the matrix to check

7082:    Output Parameters:
7083: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7084: -  flg - the result

7086:    Level: advanced

7088:    Concepts: matrix^symmetry

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

7093: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7094: @*/
7095: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7096: {
7101:   if (A->symmetric_set) {
7102:     *set = PETSC_TRUE;
7103:     *flg = A->symmetric;
7104:   } else {
7105:     *set = PETSC_FALSE;
7106:   }
7107:   return(0);
7108: }

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

7115:    Collective on Mat

7117:    Input Parameter:
7118: .  A - the matrix to check

7120:    Output Parameters:
7121: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7122: -  flg - the result

7124:    Level: advanced

7126:    Concepts: matrix^symmetry

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

7131: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7132: @*/
7133: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7134: {
7139:   if (A->hermitian_set) {
7140:     *set = PETSC_TRUE;
7141:     *flg = A->hermitian;
7142:   } else {
7143:     *set = PETSC_FALSE;
7144:   }
7145:   return(0);
7146: }

7150: /*@
7151:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

7153:    Collective on Mat

7155:    Input Parameter:
7156: .  A - the matrix to test

7158:    Output Parameters:
7159: .  flg - the result

7161:    Level: intermediate

7163:    Concepts: matrix^symmetry

7165: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7166: @*/
7167: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7168: {

7174:   if (!A->structurally_symmetric_set) {
7175:     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7176:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7177:     A->structurally_symmetric_set = PETSC_TRUE;
7178:   }
7179:   *flg = A->structurally_symmetric;
7180:   return(0);
7181: }

7186: /*@ 
7187:    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7188:        to be communicated to other processors during the MatAssemblyBegin/End() process

7190:     Not collective

7192:    Input Parameter:
7193: .   vec - the vector

7195:    Output Parameters:
7196: +   nstash   - the size of the stash
7197: .   reallocs - the number of additional mallocs incurred.
7198: .   bnstash   - the size of the block stash
7199: -   breallocs - the number of additional mallocs incurred.in the block stash
7200:  
7201:    Level: advanced

7203: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7204:   
7205: @*/
7206: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7207: {
7210:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7211:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7212:   return(0);
7213: }

7217: /*@C
7218:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
7219:      parallel layout
7220:    
7221:    Collective on Mat

7223:    Input Parameter:
7224: .  mat - the matrix

7226:    Output Parameter:
7227: +   right - (optional) vector that the matrix can be multiplied against
7228: -   left - (optional) vector that the matrix vector product can be stored in

7230:   Level: advanced

7232: .seealso: MatCreate()
7233: @*/
7234: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7235: {

7241:   MatPreallocated(mat);
7242:   if (mat->ops->getvecs) {
7243:     (*mat->ops->getvecs)(mat,right,left);
7244:   } else {
7245:     PetscMPIInt size;
7246:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
7247:     if (right) {
7248:       VecCreate(((PetscObject)mat)->comm,right);
7249:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7250:       VecSetBlockSize(*right,mat->rmap->bs);
7251:       if (size > 1) {
7252:         /* New vectors uses Mat cmap and does not create a new one */
7253:         PetscLayoutDestroy((*right)->map);
7254:         (*right)->map = mat->cmap;
7255:         mat->cmap->refcnt++;

7257:         VecSetType(*right,VECMPI);
7258:       } else {VecSetType(*right,VECSEQ);}
7259:     }
7260:     if (left) {
7261:       VecCreate(((PetscObject)mat)->comm,left);
7262:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7263:       VecSetBlockSize(*left,mat->rmap->bs);
7264:       if (size > 1) {
7265:         /* New vectors uses Mat rmap and does not create a new one */
7266:         PetscLayoutDestroy((*left)->map);
7267:         (*left)->map = mat->rmap;
7268:         mat->rmap->refcnt++;

7270:         VecSetType(*left,VECMPI);
7271:       } else {VecSetType(*left,VECSEQ);}
7272:     }
7273:   }
7274:   if (mat->mapping) {
7275:     if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7276:     if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7277:   }
7278:   if (mat->bmapping) {
7279:     if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7280:     if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7281:   }
7282:   return(0);
7283: }

7287: /*@C
7288:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7289:      with default values.

7291:    Not Collective

7293:    Input Parameters:
7294: .    info - the MatFactorInfo data structure


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

7300:    Level: developer

7302: .seealso: MatFactorInfo

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

7307: @*/

7309: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7310: {

7314:   PetscMemzero(info,sizeof(MatFactorInfo));
7315:   return(0);
7316: }

7320: /*@
7321:    MatPtAP - Creates the matrix projection C = P^T * A * P

7323:    Collective on Mat

7325:    Input Parameters:
7326: +  A - the matrix
7327: .  P - the projection matrix
7328: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7329: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

7331:    Output Parameters:
7332: .  C - the product matrix

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

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

7340:    Level: intermediate

7342: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7343: @*/
7344: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7345: {

7351:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7352:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7355:   MatPreallocated(P);
7356:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7357:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7359:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7360:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7361:   MatPreallocated(A);

7363:   if (!A->ops->ptap) {
7364:     const MatType mattype;
7365:     MatGetType(A,&mattype);
7366:     SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7367:   }
7368:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7369:   (*A->ops->ptap)(A,P,scall,fill,C);
7370:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);

7372:   return(0);
7373: }

7377: /*@
7378:    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P

7380:    Collective on Mat

7382:    Input Parameters:
7383: +  A - the matrix
7384: -  P - the projection matrix

7386:    Output Parameters:
7387: .  C - the product matrix

7389:    Notes:
7390:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7391:    the user using MatDeatroy().

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

7396:    Level: intermediate

7398: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7399: @*/
7400: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
7401: {

7407:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7408:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7411:   MatPreallocated(P);
7412:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7413:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7416:   MatPreallocated(C);
7417:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7418:   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7419:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7420:   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);
7421:   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7422:   MatPreallocated(A);

7424:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7425:   (*A->ops->ptapnumeric)(A,P,C);
7426:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7427:   return(0);
7428: }

7432: /*@
7433:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P

7435:    Collective on Mat

7437:    Input Parameters:
7438: +  A - the matrix
7439: -  P - the projection matrix

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

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

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

7451:    Level: intermediate

7453: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7454: @*/
7455: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7456: {

7462:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7463:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7464:   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7467:   MatPreallocated(P);
7468:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7469:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7472:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7473:   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);
7474:   MatPreallocated(A);
7475:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7476:   (*A->ops->ptapsymbolic)(A,P,fill,C);
7477:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

7479:   MatSetBlockSize(*C,A->rmap->bs);

7481:   return(0);
7482: }

7486: /*@
7487:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

7489:    Collective on Mat

7491:    Input Parameters:
7492: +  A - the left matrix
7493: .  B - the right matrix
7494: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7495: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7496:           if the result is a dense matrix this is irrelevent

7498:    Output Parameters:
7499: .  C - the product matrix

7501:    Notes:
7502:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

7514:    Level: intermediate

7516: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7517: @*/
7518: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7519: {
7521:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7522:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7523:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

7528:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7529:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7532:   MatPreallocated(B);
7533:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7534:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7536:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7537:   if (scall == MAT_REUSE_MATRIX){
7540:   }
7541:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7542:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7543:   MatPreallocated(A);

7545:   fA = A->ops->matmult;
7546:   fB = B->ops->matmult;
7547:   if (fB == fA) {
7548:     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7549:     mult = fB;
7550:   } else {
7551:     /* dispatch based on the type of A and B */
7552:     char  multname[256];
7553:     PetscStrcpy(multname,"MatMatMult_");
7554:     PetscStrcat(multname,((PetscObject)A)->type_name);
7555:     PetscStrcat(multname,"_");
7556:     PetscStrcat(multname,((PetscObject)B)->type_name);
7557:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7558:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7559:     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);
7560:   }
7561:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7562:   (*mult)(A,B,scall,fill,C);
7563:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7564:   return(0);
7565: }

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

7573:    Collective on Mat

7575:    Input Parameters:
7576: +  A - the left matrix
7577: .  B - the right matrix
7578: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7579:       if C is a dense matrix this is irrelevent
7580:  
7581:    Output Parameters:
7582: .  C - the product matrix

7584:    Notes:
7585:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

7590:    This routine is currently implemented for 
7591:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7592:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7593:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7595:    Level: intermediate

7597: .seealso: MatMatMult(), MatMatMultNumeric()
7598: @*/
7599: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7600: {
7602:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7603:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7604:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

7609:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7610:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7614:   MatPreallocated(B);
7615:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7616:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7619:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7620:   if (fill == PETSC_DEFAULT) fill = 2.0;
7621:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7622:   MatPreallocated(A);
7623: 
7624:   Asymbolic = A->ops->matmultsymbolic;
7625:   Bsymbolic = B->ops->matmultsymbolic;
7626:   if (Asymbolic == Bsymbolic){
7627:     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7628:     symbolic = Bsymbolic;
7629:   } else { /* dispatch based on the type of A and B */
7630:     char  symbolicname[256];
7631:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7632:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7633:     PetscStrcat(symbolicname,"_");
7634:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7635:     PetscStrcat(symbolicname,"_C");
7636:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7637:     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);
7638:   }
7639:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7640:   (*symbolic)(A,B,fill,C);
7641:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7642:   return(0);
7643: }

7647: /*@
7648:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7649:    Call this routine after first calling MatMatMultSymbolic().

7651:    Collective on Mat

7653:    Input Parameters:
7654: +  A - the left matrix
7655: -  B - the right matrix

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

7660:    Notes:
7661:    C must have been created with MatMatMultSymbolic().

7663:    This routine is currently implemented for 
7664:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7665:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7666:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7668:    Level: intermediate

7670: .seealso: MatMatMult(), MatMatMultSymbolic()
7671: @*/
7672: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
7673: {
7675:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7676:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7677:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

7682:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7683:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7687:   MatPreallocated(B);
7688:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7689:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7693:   MatPreallocated(C);
7694:   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7695:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7697:   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7698:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7699:   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7700:   MatPreallocated(A);

7702:   Anumeric = A->ops->matmultnumeric;
7703:   Bnumeric = B->ops->matmultnumeric;
7704:   if (Anumeric == Bnumeric){
7705:     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7706:     numeric = Bnumeric;
7707:   } else {
7708:     char  numericname[256];
7709:     PetscStrcpy(numericname,"MatMatMultNumeric_");
7710:     PetscStrcat(numericname,((PetscObject)A)->type_name);
7711:     PetscStrcat(numericname,"_");
7712:     PetscStrcat(numericname,((PetscObject)B)->type_name);
7713:     PetscStrcat(numericname,"_C");
7714:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7715:     if (!numeric)
7716:       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7717:   }
7718:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7719:   (*numeric)(A,B,C);
7720:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7721:   return(0);
7722: }

7726: /*@
7727:    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.

7729:    Collective on Mat

7731:    Input Parameters:
7732: +  A - the left matrix
7733: .  B - the right matrix
7734: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7735: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

7737:    Output Parameters:
7738: .  C - the product matrix

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

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

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

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

7751:    Level: intermediate

7753: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7754: @*/
7755: PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7756: {
7758:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7759:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

7764:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7765:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7768:   MatPreallocated(B);
7769:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7770:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7772:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7773:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7774:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7775:   MatPreallocated(A);

7777:   fA = A->ops->matmulttranspose;
7778:   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7779:   fB = B->ops->matmulttranspose;
7780:   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7781:   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);

7783:   PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7784:   (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7785:   PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7786: 
7787:   return(0);
7788: }

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

7795:    Collective on Mat

7797:    Input Parameters:
7798: +  mat - the matrix
7799: .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7800: .  subcomm - MPI communicator split from the communicator where mat resides in
7801: .  mlocal_red - number of local rows of the redundant matrix
7802: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7804:    Output Parameter:
7805: .  matredundant - redundant matrix

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

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

7814:    Only MPIAIJ matrix is supported. 
7815:    
7816:    Level: advanced

7818:    Concepts: subcommunicator
7819:    Concepts: duplicate matrix

7821: .seealso: MatDestroy()
7822: @*/
7823: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7824: {

7829:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7832:   }
7833:   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7834:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7835:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7836:   MatPreallocated(mat);

7838:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7839:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7840:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7841:   return(0);
7842: }