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: }

2262: /*@C
2263:    MatGetFactorType - gets the type of factorization it is

2265:    Note Collective
2266:    as the flag

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

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

2274:     Level: intermediate

2276: .seealso:    MatFactorType, MatGetFactor()
2277: @*/
2278: PetscErrorCode  MatGetFactorType(Mat mat,MatFactorType *t)
2279: {
2283:   *t = mat->factor;
2284:   return(0);
2285: }

2287: /* ------------------------------------------------------------*/
2290: /*@C
2291:    MatGetInfo - Returns information about matrix storage (number of
2292:    nonzeros, memory, etc.).

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

2297:    Input Parameters:
2298: .  mat - the matrix

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

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

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

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

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

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

2344:     Level: intermediate

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

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

2366: /* ----------------------------------------------------------*/

2370: /*@C
2371:    MatLUFactor - Performs in-place LU factorization of matrix.

2373:    Collective on Mat

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

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

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

2392:    Level: developer

2394:    Concepts: matrices^LU factorization

2396: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2397:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo

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

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

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

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

2427: /*@C
2428:    MatILUFactor - Performs in-place ILU factorization of matrix.

2430:    Collective on Mat

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

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

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

2450:    Level: developer

2452:    Concepts: matrices^ILU factorization

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

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

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

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

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

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

2489:    Collective on Mat

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


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

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

2509:    Level: developer

2511:    Concepts: matrices^LU symbolic factorization

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

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

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

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

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

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

2548:    Collective on Mat

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

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

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

2563:    Level: developer

2565:    Concepts: matrices^LU numeric factorization

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

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

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

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

2592:   MatView_Private(fact);
2593:   PetscObjectStateIncrease((PetscObject)fact);
2594:   return(0);
2595: }

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

2603:    Collective on Mat

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

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

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

2618:    Level: developer

2620:    Concepts: matrices^Cholesky factorization

2622: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2623:           MatGetOrdering()

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

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

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

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

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

2657:    Collective on Mat

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

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

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

2676:    Level: developer

2678:    Concepts: matrices^Cholesky symbolic factorization

2680: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2681:           MatGetOrdering()

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

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

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

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

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

2717:    Collective on Mat

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


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

2731:    Level: developer

2733:    Concepts: matrices^Cholesky numeric factorization

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

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

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

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

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

2761:   MatView_Private(fact);
2762:   PetscObjectStateIncrease((PetscObject)fact);
2763:   return(0);
2764: }

2766: /* ----------------------------------------------------------------*/
2769: /*@
2770:    MatSolve - Solves A x = b, given a factored matrix.

2772:    Collective on Mat and Vec

2774:    Input Parameters:
2775: +  mat - the factored matrix
2776: -  b - the right-hand-side vector

2778:    Output Parameter:
2779: .  x - the result vector

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

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

2790:    Level: developer

2792:    Concepts: matrices^triangular solves

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

2807:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2808:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2809:   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);
2810:   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);
2811:   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);
2812:   if (!mat->rmap->N && !mat->cmap->N) return(0);
2813:   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2814:   MatPreallocated(mat);

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

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

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

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

2857:    Collective on Mat 

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

2863:    Output Parameter:
2864: .  X - the result matrix (dense matrix)

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

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

2876:    Level: developer

2878:    Concepts: matrices^triangular solves

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

2893:   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2894:   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2895:   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);
2896:   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);
2897:   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);
2898:   if (!A->rmap->N && !A->cmap->N) return(0);
2899:   MatPreallocated(A);

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


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

2920:    Collective on Mat and Vec

2922:    Input Parameters:
2923: +  mat - the factored matrix
2924: -  b - the right-hand-side vector

2926:    Output Parameter:
2927: .  x - the result vector

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

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

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

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

2946:    Level: developer

2948:    Concepts: matrices^forward solves

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

2963:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2964:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2965:   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2966:   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);
2967:   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);
2968:   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);
2969:   MatPreallocated(mat);
2970:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2971:   (*mat->ops->forwardsolve)(mat,b,x);
2972:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2973:   PetscObjectStateIncrease((PetscObject)x);
2974:   return(0);
2975: }

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

2983:    Collective on Mat and Vec

2985:    Input Parameters:
2986: +  mat - the factored matrix
2987: -  b - the right-hand-side vector

2989:    Output Parameter:
2990: .  x - the result vector

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

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

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

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

3009:    Level: developer

3011:    Concepts: matrices^backward solves

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

3026:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3027:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3028:   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3029:   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);
3030:   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);
3031:   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);
3032:   MatPreallocated(mat);

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

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

3046:    Collective on Mat and Vec

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

3053:    Output Parameter:
3054: .  x - the result vector

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

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

3064:    Level: developer

3066:    Concepts: matrices^triangular solves

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

3085:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3086:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3087:   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);
3088:   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);
3089:   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);
3090:   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);
3091:   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);
3092:   MatPreallocated(mat);

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

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

3121:    Collective on Mat and Vec

3123:    Input Parameters:
3124: +  mat - the factored matrix
3125: -  b - the right-hand-side vector

3127:    Output Parameter:
3128: .  x - the result vector

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

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

3138:    Level: developer

3140:    Concepts: matrices^triangular solves

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

3155:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3156:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3157:   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3158:   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);
3159:   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);
3160:   MatPreallocated(mat);
3161:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3162:   (*mat->ops->solvetranspose)(mat,b,x);
3163:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3164:   PetscObjectStateIncrease((PetscObject)x);
3165:   return(0);
3166: }

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

3174:    Collective on Mat and Vec

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

3181:    Output Parameter:
3182: .  x - the result vector

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

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

3192:    Level: developer

3194:    Concepts: matrices^triangular solves

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

3213:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3214:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3215:   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);
3216:   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);
3217:   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);
3218:   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);
3219:   MatPreallocated(mat);

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

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

3249:    Collective on Mat and Vec

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

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

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

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

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

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

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

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


3295:    Level: developer

3297:    Concepts: matrices^relaxation
3298:    Concepts: matrices^SOR
3299:    Concepts: matrices^Gauss-Seidel

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

3313:   if (!mat->ops->sor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3314:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3315:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3316:   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);
3317:   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);
3318:   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);
3319:   if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3320:   if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);

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

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

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

3360: /*@
3361:    MatCopy - Copys a matrix to another matrix.

3363:    Collective on Mat

3365:    Input Parameters:
3366: +  A - the matrix
3367: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3369:    Output Parameter:
3370: .  B - where the copy is put

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

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

3380:    Level: intermediate
3381:    
3382:    Concepts: matrices^copying

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

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

3398:   MatPreallocated(B);
3399:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3400:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3401:   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);
3402:   MatPreallocated(A);

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

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

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

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

3437:    Collective on Mat

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

3447:    Output Parameter:
3448: .  M - pointer to place new matrix

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

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

3459:    Level: intermediate

3461:    Concepts: matrices^converting between storage formats

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

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

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

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

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

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

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

3549:     /* 5) Use a really basic converter. */
3550:     conv = MatConvert_Basic;

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

3563: /*@C  
3564:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3566:    Not Collective

3568:    Input Parameter:
3569: .  mat - the matrix, must be a factored matrix

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

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

3578:    Level: intermediate

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

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

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

3605:    Collective on Mat

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

3612:    Output Parameters:
3613: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

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

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

3621:    Level: intermediate

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


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

3638:   PetscStrcpy(convname,"MatGetFactor_");
3639:   PetscStrcat(convname,type);
3640:   PetscStrcat(convname,"_C");
3641:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3642:   if (!conv) {
3643:     PetscTruth flag;
3644:     PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);
3645:     if (flag) {
3646:       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3647:     } else {
3648:       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);
3649:     }
3650:   }
3651:   (*conv)(mat,ftype,f);
3652:   return(0);
3653: }

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

3660:    Collective on Mat

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

3667:    Output Parameter:
3668: .    flg - PETSC_TRUE if the factorization is available

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

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

3676:    Level: intermediate

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


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

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


3708: /*@
3709:    MatDuplicate - Duplicates a matrix including the non-zero structure.

3711:    Collective on Mat

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

3718:    Output Parameter:
3719: .  M - pointer to place new matrix

3721:    Level: intermediate

3723:    Concepts: matrices^duplicating

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

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

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

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

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

3773: /*@ 
3774:    MatGetDiagonal - Gets the diagonal of a matrix.

3776:    Collective on Mat and Vec

3778:    Input Parameters:
3779: +  mat - the matrix
3780: -  v - the vector for storing the diagonal

3782:    Output Parameter:
3783: .  v - the diagonal of the matrix

3785:    Level: intermediate

3787:    Concepts: matrices^accessing diagonals

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

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

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

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

3814:    Collective on Mat and Vec

3816:    Input Parameters:
3817: .  mat - the matrix

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

3823:    Level: intermediate

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

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

3830:    Concepts: matrices^getting row maximums

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

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

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

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

3858:    Collective on Mat and Vec

3860:    Input Parameters:
3861: .  mat - the matrix

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

3867:    Level: intermediate

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

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

3874:    Concepts: matrices^getting row maximums

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

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

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

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

3902:    Collective on Mat and Vec

3904:    Input Parameters:
3905: .  mat - the matrix

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

3911:    Level: intermediate

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

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

3918:    Concepts: matrices^getting row maximums

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

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

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

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

3945:    Collective on Mat and Vec

3947:    Input Parameters:
3948: .  mat - the matrix

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

3954:    Level: intermediate

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

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

3961:    Concepts: matrices^getting row maximums

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

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

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

3985: /*@ 
3986:    MatGetRowSum - Gets the sum of each row of the matrix

3988:    Collective on Mat and Vec

3990:    Input Parameters:
3991: .  mat - the matrix

3993:    Output Parameter:
3994: .  v - the vector for storing the sum of rows

3996:    Level: intermediate

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

4000:    Concepts: matrices^getting row sums

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

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

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

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

4040:    Collective on Mat

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

4046:    Output Parameters:
4047: .  B - the transpose 

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

4052:    Level: intermediate

4054:    Concepts: matrices^transposing

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

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

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

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

4083:    Collective on Mat

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

4089:    Output Parameters:
4090: .  flg - the result

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

4097:    Level: intermediate

4099:    Concepts: matrices^transposing, matrix^symmetry

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

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

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

4128:    Collective on Mat

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

4134:    Output Parameters:
4135: .  B - the Hermitian

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

4140:    Level: intermediate

4142:    Concepts: matrices^transposing, complex conjugatex

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

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

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

4163:    Collective on Mat

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

4169:    Output Parameters:
4170: .  flg - the result

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

4177:    Level: intermediate

4179:    Concepts: matrices^transposing, matrix^symmetry

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

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

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

4209:    Collective on Mat

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

4218:    Output Parameters:
4219: .  B - the permuted matrix

4221:    Level: advanced

4223:    Concepts: matrices^permuting

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

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

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

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

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

4254:   Collective on Mat

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

4264:   Output Parameter:
4265: . B    - The permuted, sparsified matrix

4267:   Level: advanced

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

4274: .keywords: matrix, permute, sparsify

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

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

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

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

4357: /*@
4358:    MatEqual - Compares two matrices.

4360:    Collective on Mat

4362:    Input Parameters:
4363: +  A - the first matrix
4364: -  B - the second matrix

4366:    Output Parameter:
4367: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4369:    Level: intermediate

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

4384:   MatPreallocated(B);
4385:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4386:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4387:   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);
4388:   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4389:   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4390:   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);
4391:   MatPreallocated(A);

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

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

4404:    Collective on Mat

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

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

4415:    Level: intermediate

4417:    Concepts: matrices^diagonal scaling
4418:    Concepts: diagonal scaling of matrices

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

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

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

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

4448:     Collective on Mat

4450:     Input Parameters:
4451: +   mat - the matrix to be scaled
4452: -   a  - the scaling value

4454:     Output Parameter:
4455: .   mat - the scaled matrix

4457:     Level: intermediate

4459:     Concepts: matrices^scaling all entries

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

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

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

4486: /*@ 
4487:    MatNorm - Calculates various norms of a matrix.

4489:    Collective on Mat

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

4495:    Output Parameters:
4496: .  nrm - the resulting norm 

4498:    Level: intermediate

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


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

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

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

4532:    Collective on Mat

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

4545:    Level: beginner

4547:    Concepts: matrices^assembling

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

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

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

4580:    Collective on Mat

4582:    Input Parameter:
4583: .  mat - the matrix 

4585:    Output Parameter:
4586: .  assembled - PETSC_TRUE or PETSC_FALSE

4588:    Level: advanced

4590:    Concepts: matrices^assembled?

4592: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4593: @*/
4594: PetscErrorCode  MatAssembled(Mat mat,PetscTruth *assembled)
4595: {
4600:   *assembled = mat->assembled;
4601:   return(0);
4602: }

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

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

4634:   if (flg1) {
4635:     PetscViewer viewer;

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

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

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

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

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

4695:    Collective on Mat

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

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

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

4722:    Level: beginner

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


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

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

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

4789:    Collective on Mat

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

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


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

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

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

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

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

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

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

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

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

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

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

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

4875:    Level: intermediate

4877:    Concepts: matrices^setting options

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

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

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

4924:    Collective on Mat

4926:    Input Parameters:
4927: .  mat - the matrix 

4929:    Level: intermediate

4931:    Concepts: matrices^zeroing

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

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

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

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

4960:    Collective on Mat

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

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

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

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

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

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

4989:    Level: intermediate

4991:    Concepts: matrices^zeroing rows

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

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

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

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

5020:    Collective on Mat

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

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

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

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

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

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

5047:    Level: intermediate

5049:    Concepts: matrices^zeroing rows

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

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

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

5076:    Collective on Mat

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

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

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

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

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

5100:    Level: intermediate

5102:    Concepts: matrices^zeroing

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

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

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

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

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

5143:    Collective on Mat

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

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

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

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

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

5166:    Level: intermediate

5168:    Concepts: matrices^zeroing

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

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

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

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

5198:    Not Collective

5200:    Input Parameter:
5201: .  mat - the matrix

5203:    Output Parameters:
5204: +  m - the number of global rows
5205: -  n - the number of global columns

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

5209:    Level: beginner

5211:    Concepts: matrices^size

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

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

5231:    Not Collective

5233:    Input Parameters:
5234: .  mat - the matrix

5236:    Output Parameters:
5237: +  m - the number of local rows
5238: -  n - the number of local columns

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

5242:    Level: beginner

5244:    Concepts: matrices^local size

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

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

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

5267:    Input Parameters:
5268: .  mat - the matrix

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

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

5276:    Level: developer

5278:    Concepts: matrices^column ownership

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

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

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

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

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

5308:    Input Parameters:
5309: .  mat - the matrix

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

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

5317:    Level: beginner

5319:    Concepts: matrices^row ownership

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

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

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

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

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

5347:    Input Parameters:
5348: .  mat - the matrix

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

5353:    Level: beginner

5355:    Concepts: matrices^row ownership

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

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

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

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

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

5379:    Input Parameters:
5380: .  mat - the matrix

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

5385:    Level: beginner

5387:    Concepts: matrices^column ownership

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

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

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

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

5411:    Collective on Mat

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

5423:    Output Parameters:
5424: .  fact - new matrix that has been symbolically factored

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

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

5434:    Level: developer

5436:   Concepts: matrices^symbolic LU factorization
5437:   Concepts: matrices^factorization
5438:   Concepts: LU^symbolic factorization

5440: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5441:           MatGetOrdering(), MatFactorInfo

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

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

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

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

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

5478:    Collective on Mat

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

5487:    Output Parameter:
5488: .  fact - the factored matrix

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

5495:    Level: developer

5497:   Concepts: matrices^symbolic incomplete Cholesky factorization
5498:   Concepts: matrices^factorization
5499:   Concepts: Cholsky^symbolic factorization

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

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

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

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

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

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

5538:    Not Collective

5540:    Input Parameter:
5541: .  mat - the matrix

5543:    Output Parameter:
5544: .  v - the location of the values


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

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

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

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

5567:    Level: advanced

5569:    Concepts: matrices^access array

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

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

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

5593:    Not Collective

5595:    Input Parameter:
5596: +  mat - the matrix
5597: -  v - the location of the values

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

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

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

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

5619:    Level: advanced

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

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

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

5647:    Collective on Mat

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

5655:    Output Parameter:
5656: .  submat - the array of submatrices

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

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

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

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

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

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

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

5685:    Level: advanced

5687:    Concepts: matrices^accessing submatrices
5688:    Concepts: submatrices

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

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

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

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

5742:    Collective on Mat

5744:    Input Parameters:
5745: +  n - the number of local matrices
5746: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5747:                        sequence of MatGetSubMatrices())

5749:    Level: advanced

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

5754: .seealso: MatGetSubMatrices()
5755: @*/
5756: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
5757: {
5759:   PetscInt       i;

5762:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5764:   for (i=0; i<n; i++) {
5765:     MatDestroy((*mat)[i]);
5766:   }
5767:   /* memory is allocated even if n = 0 */
5768:   PetscFree(*mat);
5769:   return(0);
5770: }

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

5777:    Collective on Mat

5779:    Input Parameters:
5780: .  mat - the matrix

5782:    Output Parameter:
5783: .  matstruct - the sequential matrix with the nonzero structure of mat

5785:   Level: intermediate

5787: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5788: @*/
5789: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
5790: {

5796: 
5798:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5799:   MatPreallocated(mat);

5801:   if (!mat->ops->getseqnonzerostructure) SETERRQ1(PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
5802:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5803:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5804:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5805:   return(0);
5806: }

5810: /*@C
5811:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

5813:    Collective on Mat

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

5819:    Level: advanced

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

5823: .seealso: MatGetSeqNonzeroStructure()
5824: @*/
5825: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat)
5826: {

5831:   MatDestroy(*mat);
5832:   return(0);
5833: }

5837: /*@
5838:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5839:    replaces the index sets by larger ones that represent submatrices with
5840:    additional overlap.

5842:    Collective on Mat

5844:    Input Parameters:
5845: +  mat - the matrix
5846: .  n   - the number of index sets
5847: .  is  - the array of index sets (these index sets will changed during the call)
5848: -  ov  - the additional overlap requested

5850:    Level: developer

5852:    Concepts: overlap
5853:    Concepts: ASM^computing overlap

5855: .seealso: MatGetSubMatrices()
5856: @*/
5857: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5858: {

5864:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5865:   if (n) {
5868:   }
5869:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5870:   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5871:   MatPreallocated(mat);

5873:   if (!ov) return(0);
5874:   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5875:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5876:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
5877:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5878:   return(0);
5879: }

5883: /*@
5884:    MatGetBlockSize - Returns the matrix block size; useful especially for the
5885:    block row and block diagonal formats.
5886:    
5887:    Not Collective

5889:    Input Parameter:
5890: .  mat - the matrix

5892:    Output Parameter:
5893: .  bs - block size

5895:    Notes:
5896:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

5898:    Level: intermediate

5900:    Concepts: matrices^block size

5902: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5903: @*/
5904: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
5905: {

5912:   MatPreallocated(mat);
5913:   *bs = mat->rmap->bs;
5914:   return(0);
5915: }

5919: /*@
5920:    MatSetBlockSize - Sets the matrix block size; for many matrix types you 
5921:      cannot use this and MUST set the blocksize when you preallocate the matrix
5922:    
5923:    Collective on Mat

5925:    Input Parameters:
5926: +  mat - the matrix
5927: -  bs - block size

5929:    Notes:
5930:      For BAIJ matrices, this just checks that the block size agrees with the BAIJ size,
5931:      it is not possible to change BAIJ block sizes after preallocation.

5933:    Level: intermediate

5935:    Concepts: matrices^block size

5937: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5938: @*/
5939: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
5940: {

5946:   MatPreallocated(mat);
5947:   if (bs < 1) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Block size %d, must be positive",bs);
5948:   if (mat->ops->setblocksize) {
5949:     (*mat->ops->setblocksize)(mat,bs);
5950:   } else {
5951:     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5952:   }
5953:   return(0);
5954: }

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

5961:    Collective on Mat

5963:     Input Parameters:
5964: +   mat - the matrix
5965: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5966: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5967:                 symmetrized
5968: -   inodecompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5969:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
5970:                  always used.

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

5979:     Level: developer

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

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

5985:     Fortran Node

5987:            In Fortran use
5988: $           PetscInt ia(1), ja(1)
5989: $           PetscOffset iia, jja
5990: $      call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
5991: $
5992: $          or 
5993: $
5994: $           PetscScalar, pointer :: xx_v(:)
5995: $    call  MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
5996:   
5997:  
5998:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

6000: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
6001: @*/
6002: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6003: {

6013:   MatPreallocated(mat);
6014:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
6015:   else {
6016:     *done = PETSC_TRUE;
6017:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6018:     (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6019:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6020:   }
6021:   return(0);
6022: }

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

6029:     Collective on Mat

6031:     Input Parameters:
6032: +   mat - the matrix
6033: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6034: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6035:                 symmetrized
6036: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6037:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6038:                  always used.

6040:     Output Parameters:
6041: +   n - number of columns in the (possibly compressed) matrix
6042: .   ia - the column pointers
6043: .   ja - the row indices
6044: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

6046:     Level: developer

6048: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6049: @*/
6050: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6051: {

6061:   MatPreallocated(mat);
6062:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6063:   else {
6064:     *done = PETSC_TRUE;
6065:     (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6066:   }
6067:   return(0);
6068: }

6072: /*@C
6073:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6074:     MatGetRowIJ().

6076:     Collective on Mat

6078:     Input Parameters:
6079: +   mat - the matrix
6080: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6081: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6082:                 symmetrized
6083: -   inodecompressed -  PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6084:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6085:                  always used.

6087:     Output Parameters:
6088: +   n - size of (possibly compressed) matrix
6089: .   ia - the row pointers
6090: .   ja - the column indices
6091: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6093:     Level: developer

6095: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6096: @*/
6097: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6098: {

6107:   MatPreallocated(mat);

6109:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6110:   else {
6111:     *done = PETSC_TRUE;
6112:     (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6113:   }
6114:   return(0);
6115: }

6119: /*@C
6120:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6121:     MatGetColumnIJ().

6123:     Collective on Mat

6125:     Input Parameters:
6126: +   mat - the matrix
6127: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
6128: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6129:                 symmetrized
6130: -   inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6131:                  inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 
6132:                  always used.

6134:     Output Parameters:
6135: +   n - size of (possibly compressed) matrix
6136: .   ia - the column pointers
6137: .   ja - the row indices
6138: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

6140:     Level: developer

6142: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6143: @*/
6144: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
6145: {

6154:   MatPreallocated(mat);

6156:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6157:   else {
6158:     *done = PETSC_TRUE;
6159:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6160:   }
6161:   return(0);
6162: }

6166: /*@C
6167:     MatColoringPatch -Used inside matrix coloring routines that 
6168:     use MatGetRowIJ() and/or MatGetColumnIJ().

6170:     Collective on Mat

6172:     Input Parameters:
6173: +   mat - the matrix
6174: .   ncolors - max color value
6175: .   n   - number of entries in colorarray
6176: -   colorarray - array indicating color for each column

6178:     Output Parameters:
6179: .   iscoloring - coloring generated using colorarray information

6181:     Level: developer

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

6185: @*/
6186: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6187: {

6195:   MatPreallocated(mat);

6197:   if (!mat->ops->coloringpatch){
6198:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6199:   } else {
6200:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6201:   }
6202:   return(0);
6203: }


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

6211:    Collective on Mat

6213:    Input Parameter:
6214: .  mat - the factored matrix to be reset

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

6223:    Note that one can specify in-place ILU(0) factorization by calling 
6224: .vb
6225:      PCType(pc,PCILU);
6226:      PCFactorSeUseInPlace(pc);
6227: .ve
6228:    or by using the options -pc_type ilu -pc_factor_in_place

6230:    In-place factorization ILU(0) can also be used as a local
6231:    solver for the blocks within the block Jacobi or additive Schwarz
6232:    methods (runtime option: -sub_pc_factor_in_place).  See the discussion 
6233:    of these preconditioners in the users manual for details on setting
6234:    local solver options.

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

6240:    Level: developer

6242: .seealso: PCFactorSetUseInPlace()

6244:    Concepts: matrices^unfactored

6246: @*/
6247: PetscErrorCode  MatSetUnfactored(Mat mat)
6248: {

6254:   MatPreallocated(mat);
6255:   mat->factor = MAT_FACTOR_NONE;
6256:   if (!mat->ops->setunfactored) return(0);
6257:   (*mat->ops->setunfactored)(mat);
6258:   return(0);
6259: }

6261: /*MC
6262:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

6264:     Synopsis:
6265:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6267:     Not collective

6269:     Input Parameter:
6270: .   x - matrix

6272:     Output Parameters:
6273: +   xx_v - the Fortran90 pointer to the array
6274: -   ierr - error code

6276:     Example of Usage: 
6277: .vb
6278:       PetscScalar, pointer xx_v(:)
6279:       ....
6280:       call MatGetArrayF90(x,xx_v,ierr)
6281:       a = xx_v(3)
6282:       call MatRestoreArrayF90(x,xx_v,ierr)
6283: .ve

6285:     Notes:
6286:     Not yet supported for all F90 compilers

6288:     Level: advanced

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

6292:     Concepts: matrices^accessing array

6294: M*/

6296: /*MC
6297:     MatRestoreArrayF90 - Restores a matrix array that has been
6298:     accessed with MatGetArrayF90().

6300:     Synopsis:
6301:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6303:     Not collective

6305:     Input Parameters:
6306: +   x - matrix
6307: -   xx_v - the Fortran90 pointer to the array

6309:     Output Parameter:
6310: .   ierr - error code

6312:     Example of Usage: 
6313: .vb
6314:        PetscScalar, pointer xx_v(:)
6315:        ....
6316:        call MatGetArrayF90(x,xx_v,ierr)
6317:        a = xx_v(3)
6318:        call MatRestoreArrayF90(x,xx_v,ierr)
6319: .ve
6320:    
6321:     Notes:
6322:     Not yet supported for all F90 compilers

6324:     Level: advanced

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

6328: M*/


6333: /*@
6334:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6335:                       as the original matrix.

6337:     Collective on Mat

6339:     Input Parameters:
6340: +   mat - the original matrix
6341: .   isrow - parallel IS containing the rows this processor should obtain
6342: .   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.
6343: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6345:     Output Parameter:
6346: .   newmat - the new submatrix, of the same type as the old

6348:     Level: advanced

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

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

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

6361:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6362:     the input matrix.

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

6366:    Example usage:
6367:    Consider the following 8x8 matrix with 34 non-zero values, that is
6368:    assembled across 3 processors. Lets assume that proc0 owns 3 rows,
6369:    proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
6370:    as follows:

6372: .vb
6373:             1  2  0  |  0  3  0  |  0  4
6374:     Proc0   0  5  6  |  7  0  0  |  8  0
6375:             9  0 10  | 11  0  0  | 12  0
6376:     -------------------------------------
6377:            13  0 14  | 15 16 17  |  0  0
6378:     Proc1   0 18  0  | 19 20 21  |  0  0
6379:             0  0  0  | 22 23  0  | 24  0
6380:     -------------------------------------
6381:     Proc2  25 26 27  |  0  0 28  | 29  0
6382:            30  0  0  | 31 32 33  |  0 34
6383: .ve

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

6387: .vb
6388:             2  0  |  0  3  0  |  0
6389:     Proc0   5  6  |  7  0  0  |  8
6390:     -------------------------------
6391:     Proc1  18  0  | 19 20 21  |  0
6392:     -------------------------------
6393:     Proc2  26 27  |  0  0 28  | 29
6394:             0  0  | 31 32 33  |  0
6395: .ve


6398:     Concepts: matrices^submatrices

6400: .seealso: MatGetSubMatrices()
6401: @*/
6402: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
6403: {
6405:   PetscMPIInt    size;
6406:   Mat            *local;
6407:   IS             iscoltmp;

6416:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6417:   MatPreallocated(mat);
6418:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

6420:   if (!iscol) {
6421:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
6422:   } else {
6423:     iscoltmp = iscol;
6424:   }

6426:   /* if original matrix is on just one processor then use submatrix generated */
6427:   if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6428:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6429:     if (!iscol) {ISDestroy(iscoltmp);}
6430:     return(0);
6431:   } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
6432:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6433:     *newmat = *local;
6434:     PetscFree(local);
6435:     if (!iscol) {ISDestroy(iscoltmp);}
6436:     return(0);
6437:   } else if (!mat->ops->getsubmatrix) {
6438:     /* Create a new matrix type that implements the operation using the full matrix */
6439:     switch (cll) {
6440:       case MAT_INITIAL_MATRIX:
6441:         MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
6442:         break;
6443:       case MAT_REUSE_MATRIX:
6444:         MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
6445:         break;
6446:       default: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
6447:     }
6448:     if (!iscol) {ISDestroy(iscoltmp);}
6449:     return(0);
6450:   }

6452:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6453:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
6454:   if (!iscol) {ISDestroy(iscoltmp);}
6455:   PetscObjectStateIncrease((PetscObject)*newmat);
6456:   return(0);
6457: }

6461: /*@
6462:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6463:    used during the assembly process to store values that belong to 
6464:    other processors.

6466:    Not Collective

6468:    Input Parameters:
6469: +  mat   - the matrix
6470: .  size  - the initial size of the stash.
6471: -  bsize - the initial size of the block-stash(if used).

6473:    Options Database Keys:
6474: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6475: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

6477:    Level: intermediate

6479:    Notes: 
6480:      The block-stash is used for values set with MatSetValuesBlocked() while
6481:      the stash is used for values set with MatSetValues()

6483:      Run with the option -info and look for output of the form
6484:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6485:      to determine the appropriate value, MM, to use for size and 
6486:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6487:      to determine the value, BMM to use for bsize

6489:    Concepts: stash^setting matrix size
6490:    Concepts: matrices^stash

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

6494: @*/
6495: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6496: {

6502:   MatStashSetInitialSize_Private(&mat->stash,size);
6503:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
6504:   return(0);
6505: }

6509: /*@
6510:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
6511:      the matrix

6513:    Collective on Mat

6515:    Input Parameters:
6516: +  mat   - the matrix
6517: .  x,y - the vectors
6518: -  w - where the result is stored

6520:    Level: intermediate

6522:    Notes: 
6523:     w may be the same vector as y. 

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

6528:     Concepts: interpolation

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

6532: @*/
6533: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6534: {
6536:   PetscInt       M,N;

6544:   MatPreallocated(A);
6545:   MatGetSize(A,&M,&N);
6546:   if (N > M) {
6547:     MatMultTransposeAdd(A,x,y,w);
6548:   } else {
6549:     MatMultAdd(A,x,y,w);
6550:   }
6551:   return(0);
6552: }

6556: /*@
6557:    MatInterpolate - y = A*x or A'*x depending on the shape of 
6558:      the matrix

6560:    Collective on Mat

6562:    Input Parameters:
6563: +  mat   - the matrix
6564: -  x,y - the vectors

6566:    Level: intermediate

6568:    Notes: 
6569:     This allows one to use either the restriction or interpolation (its transpose)
6570:     matrix to do the interpolation

6572:    Concepts: matrices^interpolation

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

6576: @*/
6577: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
6578: {
6580:   PetscInt       M,N;

6587:   MatPreallocated(A);
6588:   MatGetSize(A,&M,&N);
6589:   if (N > M) {
6590:     MatMultTranspose(A,x,y);
6591:   } else {
6592:     MatMult(A,x,y);
6593:   }
6594:   return(0);
6595: }

6599: /*@
6600:    MatRestrict - y = A*x or A'*x

6602:    Collective on Mat

6604:    Input Parameters:
6605: +  mat   - the matrix
6606: -  x,y - the vectors

6608:    Level: intermediate

6610:    Notes: 
6611:     This allows one to use either the restriction or interpolation (its transpose)
6612:     matrix to do the restriction

6614:    Concepts: matrices^restriction

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

6618: @*/
6619: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
6620: {
6622:   PetscInt       M,N;

6629:   MatPreallocated(A);

6631:   MatGetSize(A,&M,&N);
6632:   if (N > M) {
6633:     MatMult(A,x,y);
6634:   } else {
6635:     MatMultTranspose(A,x,y);
6636:   }
6637:   return(0);
6638: }

6642: /*@
6643:    MatNullSpaceAttach - attaches a null space to a matrix.
6644:         This null space will be removed from the resulting vector whenever
6645:         MatMult() is called

6647:    Collective on Mat

6649:    Input Parameters:
6650: +  mat - the matrix
6651: -  nullsp - the null space object

6653:    Level: developer

6655:    Notes:
6656:       Overwrites any previous null space that may have been attached

6658:    Concepts: null space^attaching to matrix

6660: .seealso: MatCreate(), MatNullSpaceCreate()
6661: @*/
6662: PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6663: {

6670:   MatPreallocated(mat);
6671:   PetscObjectReference((PetscObject)nullsp);
6672:   if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6673:   mat->nullsp = nullsp;
6674:   return(0);
6675: }

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

6682:    Collective on Mat

6684:    Input Parameters:
6685: +  mat - the matrix
6686: .  row - row/column permutation
6687: .  fill - expected fill factor >= 1.0
6688: -  level - level of fill, for ICC(k)

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

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

6698:    Level: developer

6700:    Concepts: matrices^incomplete Cholesky factorization
6701:    Concepts: Cholesky factorization

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

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

6708: @*/
6709: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6710: {

6718:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6719:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6720:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6721:   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6722:   MatPreallocated(mat);
6723:   (*mat->ops->iccfactor)(mat,row,info);
6724:   PetscObjectStateIncrease((PetscObject)mat);
6725:   return(0);
6726: }

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

6733:    Not Collective

6735:    Input Parameters:
6736: +  mat - the matrix
6737: -  v - the values compute with ADIC

6739:    Level: developer

6741:    Notes:
6742:      Must call MatSetColoring() before using this routine. Also this matrix must already
6743:      have its nonzero pattern determined.

6745: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6746:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6747: @*/
6748: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
6749: {


6757:   if (!mat->assembled) {
6758:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6759:   }
6760:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6761:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6762:   (*mat->ops->setvaluesadic)(mat,v);
6763:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6764:   MatView_Private(mat);
6765:   PetscObjectStateIncrease((PetscObject)mat);
6766:   return(0);
6767: }


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

6775:    Not Collective

6777:    Input Parameters:
6778: +  mat - the matrix
6779: -  coloring - the coloring

6781:    Level: developer

6783: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6784:           MatSetValues(), MatSetValuesAdic()
6785: @*/
6786: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
6787: {


6795:   if (!mat->assembled) {
6796:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6797:   }
6798:   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6799:   (*mat->ops->setcoloring)(mat,coloring);
6800:   return(0);
6801: }

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

6808:    Not Collective

6810:    Input Parameters:
6811: +  mat - the matrix
6812: .  nl - leading dimension of v
6813: -  v - the values compute with ADIFOR

6815:    Level: developer

6817:    Notes:
6818:      Must call MatSetColoring() before using this routine. Also this matrix must already
6819:      have its nonzero pattern determined.

6821: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6822:           MatSetValues(), MatSetColoring()
6823: @*/
6824: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6825: {


6833:   if (!mat->assembled) {
6834:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6835:   }
6836:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6837:   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6838:   (*mat->ops->setvaluesadifor)(mat,nl,v);
6839:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6840:   PetscObjectStateIncrease((PetscObject)mat);
6841:   return(0);
6842: }

6846: /*@ 
6847:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
6848:          ghosted ones.

6850:    Not Collective

6852:    Input Parameters:
6853: +  mat - the matrix
6854: -  diag = the diagonal values, including ghost ones

6856:    Level: developer

6858:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6859:       
6860: .seealso: MatDiagonalScale()
6861: @*/
6862: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
6863: {
6865:   PetscMPIInt    size;


6872:   if (!mat->assembled) {
6873:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6874:   }
6875:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6876:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
6877:   if (size == 1) {
6878:     PetscInt n,m;
6879:     VecGetSize(diag,&n);
6880:     MatGetSize(mat,0,&m);
6881:     if (m == n) {
6882:       MatDiagonalScale(mat,0,diag);
6883:     } else {
6884:       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6885:     }
6886:   } else {
6887:     PetscErrorCode (*f)(Mat,Vec);
6888:     PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6889:     if (f) {
6890:       (*f)(mat,diag);
6891:     } else {
6892:       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6893:     }
6894:   }
6895:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6896:   PetscObjectStateIncrease((PetscObject)mat);
6897:   return(0);
6898: }

6902: /*@ 
6903:    MatGetInertia - Gets the inertia from a factored matrix

6905:    Collective on Mat

6907:    Input Parameter:
6908: .  mat - the matrix

6910:    Output Parameters:
6911: +   nneg - number of negative eigenvalues
6912: .   nzero - number of zero eigenvalues
6913: -   npos - number of positive eigenvalues

6915:    Level: advanced

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


6920: @*/
6921: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6922: {

6928:   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6929:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6930:   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6931:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6932:   return(0);
6933: }

6935: /* ----------------------------------------------------------------*/
6938: /*@C
6939:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

6941:    Collective on Mat and Vecs

6943:    Input Parameters:
6944: +  mat - the factored matrix
6945: -  b - the right-hand-side vectors

6947:    Output Parameter:
6948: .  x - the result vectors

6950:    Notes:
6951:    The vectors b and x cannot be the same.  I.e., one cannot
6952:    call MatSolves(A,x,x).

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

6959:    Level: developer

6961:    Concepts: matrices^triangular solves

6963: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6964: @*/
6965: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
6966: {

6972:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
6973:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6974:   if (!mat->rmap->N && !mat->cmap->N) return(0);

6976:   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6977:   MatPreallocated(mat);
6978:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6979:   (*mat->ops->solves)(mat,b,x);
6980:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6981:   return(0);
6982: }

6986: /*@
6987:    MatIsSymmetric - Test whether a matrix is symmetric

6989:    Collective on Mat

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

6995:    Output Parameters:
6996: .  flg - the result

6998:    Level: intermediate

7000:    Concepts: matrix^symmetry

7002: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7003: @*/
7004: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
7005: {


7012:   if (!A->symmetric_set) {
7013:     if (!A->ops->issymmetric) {
7014:       const MatType mattype;
7015:       MatGetType(A,&mattype);
7016:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7017:     }
7018:     (*A->ops->issymmetric)(A,tol,flg);
7019:     if (!tol) {
7020:       A->symmetric_set = PETSC_TRUE;
7021:       A->symmetric = *flg;
7022:       if (A->symmetric) {
7023:         A->structurally_symmetric_set = PETSC_TRUE;
7024:         A->structurally_symmetric     = PETSC_TRUE;
7025:       }
7026:     }
7027:   } else if (A->symmetric) {
7028:     *flg = PETSC_TRUE;
7029:   } else if (!tol) {
7030:     *flg = PETSC_FALSE;
7031:   } else {
7032:     if (!A->ops->issymmetric) {
7033:       const MatType mattype;
7034:       MatGetType(A,&mattype);
7035:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7036:     }
7037:     (*A->ops->issymmetric)(A,tol,flg);
7038:   }
7039:   return(0);
7040: }

7044: /*@
7045:    MatIsHermitian - Test whether a matrix is Hermitian

7047:    Collective on Mat

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

7053:    Output Parameters:
7054: .  flg - the result

7056:    Level: intermediate

7058:    Concepts: matrix^symmetry

7060: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7061: @*/
7062: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
7063: {


7070:   if (!A->hermitian_set) {
7071:     if (!A->ops->ishermitian) {
7072:       const MatType mattype;
7073:       MatGetType(A,&mattype);
7074:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7075:     }
7076:     (*A->ops->ishermitian)(A,tol,flg);
7077:     if (!tol) {
7078:       A->hermitian_set = PETSC_TRUE;
7079:       A->hermitian = *flg;
7080:       if (A->hermitian) {
7081:         A->structurally_symmetric_set = PETSC_TRUE;
7082:         A->structurally_symmetric     = PETSC_TRUE;
7083:       }
7084:     }
7085:   } else if (A->hermitian) {
7086:     *flg = PETSC_TRUE;
7087:   } else if (!tol) {
7088:     *flg = PETSC_FALSE;
7089:   } else {
7090:     if (!A->ops->ishermitian) {
7091:       const MatType mattype;
7092:       MatGetType(A,&mattype);
7093:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7094:     }
7095:     (*A->ops->ishermitian)(A,tol,flg);
7096:   }
7097:   return(0);
7098: }

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

7105:    Collective on Mat

7107:    Input Parameter:
7108: .  A - the matrix to check

7110:    Output Parameters:
7111: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
7112: -  flg - the result

7114:    Level: advanced

7116:    Concepts: matrix^symmetry

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

7121: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7122: @*/
7123: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7124: {
7129:   if (A->symmetric_set) {
7130:     *set = PETSC_TRUE;
7131:     *flg = A->symmetric;
7132:   } else {
7133:     *set = PETSC_FALSE;
7134:   }
7135:   return(0);
7136: }

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

7143:    Collective on Mat

7145:    Input Parameter:
7146: .  A - the matrix to check

7148:    Output Parameters:
7149: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
7150: -  flg - the result

7152:    Level: advanced

7154:    Concepts: matrix^symmetry

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

7159: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7160: @*/
7161: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
7162: {
7167:   if (A->hermitian_set) {
7168:     *set = PETSC_TRUE;
7169:     *flg = A->hermitian;
7170:   } else {
7171:     *set = PETSC_FALSE;
7172:   }
7173:   return(0);
7174: }

7178: /*@
7179:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

7181:    Collective on Mat

7183:    Input Parameter:
7184: .  A - the matrix to test

7186:    Output Parameters:
7187: .  flg - the result

7189:    Level: intermediate

7191:    Concepts: matrix^symmetry

7193: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7194: @*/
7195: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7196: {

7202:   if (!A->structurally_symmetric_set) {
7203:     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7204:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7205:     A->structurally_symmetric_set = PETSC_TRUE;
7206:   }
7207:   *flg = A->structurally_symmetric;
7208:   return(0);
7209: }

7214: /*@ 
7215:    MatStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
7216:        to be communicated to other processors during the MatAssemblyBegin/End() process

7218:     Not collective

7220:    Input Parameter:
7221: .   vec - the vector

7223:    Output Parameters:
7224: +   nstash   - the size of the stash
7225: .   reallocs - the number of additional mallocs incurred.
7226: .   bnstash   - the size of the block stash
7227: -   breallocs - the number of additional mallocs incurred.in the block stash
7228:  
7229:    Level: advanced

7231: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7232:   
7233: @*/
7234: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7235: {
7238:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7239:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7240:   return(0);
7241: }

7245: /*@C
7246:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
7247:      parallel layout
7248:    
7249:    Collective on Mat

7251:    Input Parameter:
7252: .  mat - the matrix

7254:    Output Parameter:
7255: +   right - (optional) vector that the matrix can be multiplied against
7256: -   left - (optional) vector that the matrix vector product can be stored in

7258:   Level: advanced

7260: .seealso: MatCreate()
7261: @*/
7262: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7263: {

7269:   MatPreallocated(mat);
7270:   if (mat->ops->getvecs) {
7271:     (*mat->ops->getvecs)(mat,right,left);
7272:   } else {
7273:     PetscMPIInt size;
7274:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
7275:     if (right) {
7276:       VecCreate(((PetscObject)mat)->comm,right);
7277:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7278:       VecSetBlockSize(*right,mat->rmap->bs);
7279:       if (size > 1) {
7280:         /* New vectors uses Mat cmap and does not create a new one */
7281:         PetscLayoutDestroy((*right)->map);
7282:         (*right)->map = mat->cmap;
7283:         mat->cmap->refcnt++;

7285:         VecSetType(*right,VECMPI);
7286:       } else {VecSetType(*right,VECSEQ);}
7287:     }
7288:     if (left) {
7289:       VecCreate(((PetscObject)mat)->comm,left);
7290:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7291:       VecSetBlockSize(*left,mat->rmap->bs);
7292:       if (size > 1) {
7293:         /* New vectors uses Mat rmap and does not create a new one */
7294:         PetscLayoutDestroy((*left)->map);
7295:         (*left)->map = mat->rmap;
7296:         mat->rmap->refcnt++;

7298:         VecSetType(*left,VECMPI);
7299:       } else {VecSetType(*left,VECSEQ);}
7300:     }
7301:   }
7302:   if (mat->mapping) {
7303:     if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7304:     if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7305:   }
7306:   if (mat->bmapping) {
7307:     if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7308:     if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7309:   }
7310:   return(0);
7311: }

7315: /*@C
7316:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7317:      with default values.

7319:    Not Collective

7321:    Input Parameters:
7322: .    info - the MatFactorInfo data structure


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

7328:    Level: developer

7330: .seealso: MatFactorInfo

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

7335: @*/

7337: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7338: {

7342:   PetscMemzero(info,sizeof(MatFactorInfo));
7343:   return(0);
7344: }

7348: /*@
7349:    MatPtAP - Creates the matrix projection C = P^T * A * P

7351:    Collective on Mat

7353:    Input Parameters:
7354: +  A - the matrix
7355: .  P - the projection matrix
7356: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7357: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

7359:    Output Parameters:
7360: .  C - the product matrix

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

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

7368:    Level: intermediate

7370: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7371: @*/
7372: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7373: {

7379:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7380:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7383:   MatPreallocated(P);
7384:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7385:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7387:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7388:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7389:   MatPreallocated(A);

7391:   if (!A->ops->ptap) {
7392:     const MatType mattype;
7393:     MatGetType(A,&mattype);
7394:     SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype);
7395:   }
7396:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7397:   (*A->ops->ptap)(A,P,scall,fill,C);
7398:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);

7400:   return(0);
7401: }

7405: /*@
7406:    MatPtAPNumeric - Computes the matrix projection C = P^T * A * P

7408:    Collective on Mat

7410:    Input Parameters:
7411: +  A - the matrix
7412: -  P - the projection matrix

7414:    Output Parameters:
7415: .  C - the product matrix

7417:    Notes:
7418:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7419:    the user using MatDeatroy().

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

7424:    Level: intermediate

7426: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7427: @*/
7428: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
7429: {

7435:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7436:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7439:   MatPreallocated(P);
7440:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7441:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7444:   MatPreallocated(C);
7445:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7446:   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7447:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7448:   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);
7449:   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7450:   MatPreallocated(A);

7452:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7453:   (*A->ops->ptapnumeric)(A,P,C);
7454:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7455:   return(0);
7456: }

7460: /*@
7461:    MatPtAPSymbolic - Creates the (i,j) structure of the matrix projection C = P^T * A * P

7463:    Collective on Mat

7465:    Input Parameters:
7466: +  A - the matrix
7467: -  P - the projection matrix

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

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

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

7479:    Level: intermediate

7481: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7482: @*/
7483: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7484: {

7490:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7491:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7492:   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7495:   MatPreallocated(P);
7496:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7497:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7500:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7501:   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);
7502:   MatPreallocated(A);
7503:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7504:   (*A->ops->ptapsymbolic)(A,P,fill,C);
7505:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

7507:   MatSetBlockSize(*C,A->rmap->bs);

7509:   return(0);
7510: }

7514: /*@
7515:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

7517:    Collective on Mat

7519:    Input Parameters:
7520: +  A - the left matrix
7521: .  B - the right matrix
7522: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7523: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7524:           if the result is a dense matrix this is irrelevent

7526:    Output Parameters:
7527: .  C - the product matrix

7529:    Notes:
7530:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

7542:    Level: intermediate

7544: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7545: @*/
7546: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7547: {
7549:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7550:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7551:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

7556:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7557:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7560:   MatPreallocated(B);
7561:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7562:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7564:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7565:   if (scall == MAT_REUSE_MATRIX){
7568:   }
7569:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7570:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7571:   MatPreallocated(A);

7573:   fA = A->ops->matmult;
7574:   fB = B->ops->matmult;
7575:   if (fB == fA) {
7576:     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7577:     mult = fB;
7578:   } else {
7579:     /* dispatch based on the type of A and B */
7580:     char  multname[256];
7581:     PetscStrcpy(multname,"MatMatMult_");
7582:     PetscStrcat(multname,((PetscObject)A)->type_name);
7583:     PetscStrcat(multname,"_");
7584:     PetscStrcat(multname,((PetscObject)B)->type_name);
7585:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7586:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7587:     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);
7588:   }
7589:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7590:   (*mult)(A,B,scall,fill,C);
7591:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7592:   return(0);
7593: }

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

7601:    Collective on Mat

7603:    Input Parameters:
7604: +  A - the left matrix
7605: .  B - the right matrix
7606: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7607:       if C is a dense matrix this is irrelevent
7608:  
7609:    Output Parameters:
7610: .  C - the product matrix

7612:    Notes:
7613:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

7618:    This routine is currently implemented for 
7619:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7620:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7621:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7623:    Level: intermediate

7625: .seealso: MatMatMult(), MatMatMultNumeric()
7626: @*/
7627: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7628: {
7630:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7631:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7632:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

7637:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7638:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7642:   MatPreallocated(B);
7643:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7644:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7647:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7648:   if (fill == PETSC_DEFAULT) fill = 2.0;
7649:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7650:   MatPreallocated(A);
7651: 
7652:   Asymbolic = A->ops->matmultsymbolic;
7653:   Bsymbolic = B->ops->matmultsymbolic;
7654:   if (Asymbolic == Bsymbolic){
7655:     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7656:     symbolic = Bsymbolic;
7657:   } else { /* dispatch based on the type of A and B */
7658:     char  symbolicname[256];
7659:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7660:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7661:     PetscStrcat(symbolicname,"_");
7662:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7663:     PetscStrcat(symbolicname,"_C");
7664:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7665:     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);
7666:   }
7667:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7668:   (*symbolic)(A,B,fill,C);
7669:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7670:   return(0);
7671: }

7675: /*@
7676:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7677:    Call this routine after first calling MatMatMultSymbolic().

7679:    Collective on Mat

7681:    Input Parameters:
7682: +  A - the left matrix
7683: -  B - the right matrix

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

7688:    Notes:
7689:    C must have been created with MatMatMultSymbolic().

7691:    This routine is currently implemented for 
7692:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7693:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7694:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7696:    Level: intermediate

7698: .seealso: MatMatMult(), MatMatMultSymbolic()
7699: @*/
7700: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
7701: {
7703:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7704:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7705:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

7710:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7711:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7715:   MatPreallocated(B);
7716:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7717:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7721:   MatPreallocated(C);
7722:   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7723:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7725:   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7726:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7727:   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7728:   MatPreallocated(A);

7730:   Anumeric = A->ops->matmultnumeric;
7731:   Bnumeric = B->ops->matmultnumeric;
7732:   if (Anumeric == Bnumeric){
7733:     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7734:     numeric = Bnumeric;
7735:   } else {
7736:     char  numericname[256];
7737:     PetscStrcpy(numericname,"MatMatMultNumeric_");
7738:     PetscStrcat(numericname,((PetscObject)A)->type_name);
7739:     PetscStrcat(numericname,"_");
7740:     PetscStrcat(numericname,((PetscObject)B)->type_name);
7741:     PetscStrcat(numericname,"_C");
7742:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7743:     if (!numeric)
7744:       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7745:   }
7746:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7747:   (*numeric)(A,B,C);
7748:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7749:   return(0);
7750: }

7754: /*@
7755:    MatMatMultTranspose - Performs Matrix-Matrix Multiplication C=A^T*B.

7757:    Collective on Mat

7759:    Input Parameters:
7760: +  A - the left matrix
7761: .  B - the right matrix
7762: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7763: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

7765:    Output Parameters:
7766: .  C - the product matrix

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

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

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

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

7779:    Level: intermediate

7781: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7782: @*/
7783: PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7784: {
7786:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7787:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

7792:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7793:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7796:   MatPreallocated(B);
7797:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7798:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7800:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7801:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7802:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7803:   MatPreallocated(A);

7805:   fA = A->ops->matmulttranspose;
7806:   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7807:   fB = B->ops->matmulttranspose;
7808:   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7809:   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);

7811:   PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7812:   (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7813:   PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7814: 
7815:   return(0);
7816: }

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

7823:    Collective on Mat

7825:    Input Parameters:
7826: +  mat - the matrix
7827: .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7828: .  subcomm - MPI communicator split from the communicator where mat resides in
7829: .  mlocal_red - number of local rows of the redundant matrix
7830: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7832:    Output Parameter:
7833: .  matredundant - redundant matrix

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

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

7842:    Only MPIAIJ matrix is supported. 
7843:    
7844:    Level: advanced

7846:    Concepts: subcommunicator
7847:    Concepts: duplicate matrix

7849: .seealso: MatDestroy()
7850: @*/
7851: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7852: {

7857:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7860:   }
7861:   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7862:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7863:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7864:   MatPreallocated(mat);

7866:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7867:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7868:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7869:   return(0);
7870: }