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_Relax, 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_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
 26: PetscLogEvent  MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
 27: PetscLogEvent  MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;

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

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

 39:    Not Collective

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

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

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

 51:    Level: advanced

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

 60:   MPI_Comm_size(((PetscObject)A)->comm,&size);
 61:   PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);
 62:   if (f) {
 63:     (*f)(A,iscopy,reuse,a);
 64:   } else if (size == 1) {
 65:     *a = A;
 66:   } else {
 67:     SETERRQ(PETSC_ERR_SUP,"Cannot get diagonal part for this matrix");
 68:   }
 69:   return(0);
 70: }

 74: /*@
 75:    MatRealPart - Zeros out the imaginary part of the matrix

 77:    Collective on Mat

 79:    Input Parameters:
 80: .  mat - the matrix

 82:    Level: advanced


 85: .seealso: MatImaginaryPart()
 86: @*/
 87: PetscErrorCode  MatRealPart(Mat mat)
 88: {

 94:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
 95:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
 96:   if (!mat->ops->realpart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
 97:   MatPreallocated(mat);
 98:   (*mat->ops->realpart)(mat);
 99:   return(0);
100: }


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

108:    Collective on Mat

110:    Input Parameters:
111: .  mat - the matrix

113:    Level: advanced


116: .seealso: MatRealPart()
117: @*/
118: PetscErrorCode  MatImaginaryPart(Mat mat)
119: {

125:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
126:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
127:   if (!mat->ops->imaginarypart) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
128:   MatPreallocated(mat);
129:   (*mat->ops->imaginarypart)(mat);
130:   return(0);
131: }

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

138:    Collective on Mat

140:    Input Parameter:
141: .  mat - the matrix

143:    Output Parameters:
144: +  missing - is any diagonal missing
145: -  dd - first diagonal entry that is missing (optional)

147:    Level: advanced


150: .seealso: MatRealPart()
151: @*/
152: PetscErrorCode  MatMissingDiagonal(Mat mat,PetscTruth *missing,PetscInt *dd)
153: {

159:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
160:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
161:   if (!mat->ops->missingdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
162:   (*mat->ops->missingdiagonal)(mat,missing,dd);
163:   return(0);
164: }

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

173:    Not Collective

175:    Input Parameters:
176: +  mat - the matrix
177: -  row - the row to get

179:    Output Parameters:
180: +  ncols -  if not NULL, the number of nonzeros in the row
181: .  cols - if not NULL, the column numbers
182: -  vals - if not NULL, the values

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

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

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

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

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

206:    Fortran Notes:
207:    The calling sequence from Fortran is 
208: .vb
209:    MatGetRow(matrix,row,ncols,cols,values,ierr)
210:          Mat     matrix (input)
211:          integer row    (input)
212:          integer ncols  (output)
213:          integer cols(maxcols) (output)
214:          double precision (or double complex) values(maxcols) output
215: .ve
216:    where maxcols >= maximum nonzeros in any row of the matrix.


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

223:    Level: advanced

225:    Concepts: matrices^row access

227: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
228: @*/
229: PetscErrorCode  MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
230: {
232:   PetscInt       incols;

237:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
238:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
239:   if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
240:   MatPreallocated(mat);
241:   PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
242:   (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);
243:   if (ncols) *ncols = incols;
244:   PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
245:   return(0);
246: }

250: /*@
251:    MatConjugate - replaces the matrix values with their complex conjugates

253:    Collective on Mat

255:    Input Parameters:
256: .  mat - the matrix

258:    Level: advanced

260: .seealso:  VecConjugate()
261: @*/
262: PetscErrorCode  MatConjugate(Mat mat)
263: {

268:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
269:   if (!mat->ops->conjugate) SETERRQ(PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov");
270:   (*mat->ops->conjugate)(mat);
271:   return(0);
272: }

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

279:    Not Collective

281:    Input Parameters:
282: +  mat - the matrix
283: .  row - the row to get
284: .  ncols, cols - the number of nonzeros and their columns
285: -  vals - if nonzero the column values

287:    Notes: 
288:    This routine should be called after you have finished examining the entries.

290:    Fortran Notes:
291:    The calling sequence from Fortran is 
292: .vb
293:    MatRestoreRow(matrix,row,ncols,cols,values,ierr)
294:       Mat     matrix (input)
295:       integer row    (input)
296:       integer ncols  (output)
297:       integer cols(maxcols) (output)
298:       double precision (or double complex) values(maxcols) output
299: .ve
300:    Where maxcols >= maximum nonzeros in any row of the matrix. 

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

305:    Level: advanced

307: .seealso:  MatGetRow()
308: @*/
309: PetscErrorCode  MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
310: {

316:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
317:   if (!mat->ops->restorerow) return(0);
318:   (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
319:   return(0);
320: }

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

328:    Not Collective

330:    Input Parameters:
331: +  mat - the matrix

333:    Notes:
334:    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.

336:    Level: advanced

338:    Concepts: matrices^row access

340: .seealso: MatRestoreRowRowUpperTriangular()
341: @*/
342: PetscErrorCode  MatGetRowUpperTriangular(Mat mat)
343: {

349:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
350:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
351:   if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
352:   MatPreallocated(mat);
353:   (*mat->ops->getrowuppertriangular)(mat);
354:   return(0);
355: }

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

362:    Not Collective

364:    Input Parameters:
365: +  mat - the matrix

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


371:    Level: advanced

373: .seealso:  MatGetRowUpperTriangular()
374: @*/
375: PetscErrorCode  MatRestoreRowUpperTriangular(Mat mat)
376: {

381:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
382:   if (!mat->ops->restorerowuppertriangular) return(0);
383:   (*mat->ops->restorerowuppertriangular)(mat);
384:   return(0);
385: }

389: /*@C
390:    MatSetOptionsPrefix - Sets the prefix used for searching for all 
391:    Mat options in the database.

393:    Collective on Mat

395:    Input Parameter:
396: +  A - the Mat context
397: -  prefix - the prefix to prepend to all option names

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

403:    Level: advanced

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

407: .seealso: MatSetFromOptions()
408: @*/
409: PetscErrorCode  MatSetOptionsPrefix(Mat A,const char prefix[])
410: {

415:   PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
416:   return(0);
417: }

421: /*@C
422:    MatAppendOptionsPrefix - Appends to the prefix used for searching for all 
423:    Mat options in the database.

425:    Collective on Mat

427:    Input Parameters:
428: +  A - the Mat context
429: -  prefix - the prefix to prepend to all option names

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

435:    Level: advanced

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

439: .seealso: MatGetOptionsPrefix()
440: @*/
441: PetscErrorCode  MatAppendOptionsPrefix(Mat A,const char prefix[])
442: {
444: 
447:   PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
448:   return(0);
449: }

453: /*@C
454:    MatGetOptionsPrefix - Sets the prefix used for searching for all 
455:    Mat options in the database.

457:    Not Collective

459:    Input Parameter:
460: .  A - the Mat context

462:    Output Parameter:
463: .  prefix - pointer to the prefix string used

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

468:    Level: advanced

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

472: .seealso: MatAppendOptionsPrefix()
473: @*/
474: PetscErrorCode  MatGetOptionsPrefix(Mat A,const char *prefix[])
475: {

480:   PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
481:   return(0);
482: }

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

489:    Collective on Mat

491:    Input Parameters:
492: .  A - the Mat context

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

498:    Level: advanced

500: .keywords: Mat, setup

502: .seealso: MatCreate(), MatDestroy()
503: @*/
504: PetscErrorCode  MatSetUp(Mat A)
505: {
506:   PetscMPIInt    size;

511:   if (!((PetscObject)A)->type_name) {
512:     MPI_Comm_size(((PetscObject)A)->comm, &size);
513:     if (size == 1) {
514:       MatSetType(A, MATSEQAIJ);
515:     } else {
516:       MatSetType(A, MATMPIAIJ);
517:     }
518:   }
519:   MatSetUpPreallocation(A);
520:   return(0);
521: }

525: /*@C
526:    MatView - Visualizes a matrix object.

528:    Collective on Mat

530:    Input Parameters:
531: +  mat - the matrix
532: -  viewer - visualization context

534:   Notes:
535:   The available visualization contexts include
536: +    PETSC_VIEWER_STDOUT_SELF - standard output (default)
537: .    PETSC_VIEWER_STDOUT_WORLD - synchronized standard
538:         output where only the first processor opens
539:         the file.  All other processors send their 
540:         data to the first processor to print. 
541: -     PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure

543:    The user can open alternative visualization contexts with
544: +    PetscViewerASCIIOpen() - Outputs matrix to a specified file
545: .    PetscViewerBinaryOpen() - Outputs matrix in binary to a
546:          specified file; corresponding input uses MatLoad()
547: .    PetscViewerDrawOpen() - Outputs nonzero matrix structure to 
548:          an X window display
549: -    PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
550:          Currently only the sequential dense and AIJ
551:          matrix types support the Socket viewer.

553:    The user can call PetscViewerSetFormat() to specify the output
554:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
555:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
556: +    PETSC_VIEWER_DEFAULT - default, prints matrix contents
557: .    PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
558: .    PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
559: .    PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 
560:          format common among all matrix types
561: .    PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 
562:          format (which is in many cases the same as the default)
563: .    PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
564:          size and structure (not the matrix entries)
565: .    PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
566:          the matrix structure

568:    Options Database Keys:
569: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
570: .  -mat_view_info_detailed - Prints more detailed info
571: .  -mat_view - Prints matrix in ASCII format
572: .  -mat_view_matlab - Prints matrix in Matlab format
573: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
574: .  -display <name> - Sets display name (default is host)
575: .  -draw_pause <sec> - Sets number of seconds to pause after display
576: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
577: .  -viewer_socket_machine <machine>
578: .  -viewer_socket_port <port>
579: .  -mat_view_binary - save matrix to file in binary format
580: -  -viewer_binary_filename <name>
581:    Level: beginner

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

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

589:    Concepts: matrices^viewing
590:    Concepts: matrices^plotting
591:    Concepts: matrices^printing

593: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 
594:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
595: @*/
596: PetscErrorCode  MatView(Mat mat,PetscViewer viewer)
597: {
598:   PetscErrorCode    ierr;
599:   PetscInt          rows,cols;
600:   PetscTruth        iascii;
601:   const MatType     cstr;
602:   PetscViewerFormat format;

607:   if (!viewer) {
608:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
609:   }
612:   if (!mat->assembled) SETERRQ(PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
613:   MatPreallocated(mat);

615:   PetscLogEventBegin(MAT_View,mat,viewer,0,0);
616:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
617:   if (iascii) {
618:     PetscViewerGetFormat(viewer,&format);
619:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
620:       if (((PetscObject)mat)->prefix) {
621:         PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",((PetscObject)mat)->prefix);
622:       } else {
623:         PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");
624:       }
625:       PetscViewerASCIIPushTab(viewer);
626:       MatGetType(mat,&cstr);
627:       MatGetSize(mat,&rows,&cols);
628:       PetscViewerASCIIPrintf(viewer,"type=%s, rows=%D, cols=%D\n",cstr,rows,cols);
629:       if (mat->factor) {
630:         const MatSolverPackage solver;
631:         MatFactorGetSolverPackage(mat,&solver);
632:         PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
633:       }
634:       if (mat->ops->getinfo) {
635:         MatInfo info;
636:         MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
637:         PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);
638:       }
639:     }
640:   }
641:   if (mat->ops->view) {
642:     PetscViewerASCIIPushTab(viewer);
643:     (*mat->ops->view)(mat,viewer);
644:     PetscViewerASCIIPopTab(viewer);
645:   } else if (!iascii) {
646:     SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
647:   }
648:   if (iascii) {
649:     PetscViewerGetFormat(viewer,&format);
650:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
651:       PetscViewerASCIIPopTab(viewer);
652:     }
653:   }
654:   PetscLogEventEnd(MAT_View,mat,viewer,0,0);
655:   return(0);
656: }

660: /*@
661:    MatScaleSystem - Scale a vector solution and right hand side to 
662:    match the scaling of a scaled matrix.
663:   
664:    Collective on Mat

666:    Input Parameter:
667: +  mat - the matrix
668: .  b - right hand side vector (or PETSC_NULL)
669: -  x - solution vector (or PETSC_NULL)


672:    Notes: 
673:    For AIJ, and BAIJ matrix formats, the matrices are not 
674:    internally scaled, so this does nothing. For MPIROWBS it
675:    permutes and diagonally scales.

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

680:    Level: Developer            

682:    Concepts: matrices^scaling

684: .seealso: MatUseScaledForm(), MatUnScaleSystem()
685: @*/
686: PetscErrorCode  MatScaleSystem(Mat mat,Vec b,Vec x)
687: {

693:   MatPreallocated(mat);

697:   if (mat->ops->scalesystem) {
698:     (*mat->ops->scalesystem)(mat,b,x);
699:   }
700:   return(0);
701: }

705: /*@
706:    MatUnScaleSystem - Unscales a vector solution and right hand side to 
707:    match the original scaling of a scaled matrix.
708:   
709:    Collective on Mat

711:    Input Parameter:
712: +  mat - the matrix
713: .  b - right hand side vector (or PETSC_NULL)
714: -  x - solution vector (or PETSC_NULL)


717:    Notes: 
718:    For AIJ and BAIJ matrix formats, the matrices are not 
719:    internally scaled, so this does nothing. For MPIROWBS it
720:    permutes and diagonally scales.

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

725:    Level: Developer            

727: .seealso: MatUseScaledForm(), MatScaleSystem()
728: @*/
729: PetscErrorCode  MatUnScaleSystem(Mat mat,Vec b,Vec x)
730: {

736:   MatPreallocated(mat);
739:   if (mat->ops->unscalesystem) {
740:     (*mat->ops->unscalesystem)(mat,b,x);
741:   }
742:   return(0);
743: }

747: /*@
748:    MatUseScaledForm - For matrix storage formats that scale the 
749:    matrix (for example MPIRowBS matrices are diagonally scaled on
750:    assembly) indicates matrix operations (MatMult() etc) are 
751:    applied using the scaled matrix.
752:   
753:    Collective on Mat

755:    Input Parameter:
756: +  mat - the matrix
757: -  scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for 
758:             applying the original matrix

760:    Notes: 
761:    For scaled matrix formats, applying the original, unscaled matrix
762:    will be slightly more expensive

764:    Level: Developer            

766: .seealso: MatScaleSystem(), MatUnScaleSystem()
767: @*/
768: PetscErrorCode  MatUseScaledForm(Mat mat,PetscTruth scaled)
769: {

775:   MatPreallocated(mat);
776:   if (mat->ops->usescaledform) {
777:     (*mat->ops->usescaledform)(mat,scaled);
778:   }
779:   return(0);
780: }

784: /*@
785:    MatDestroy - Frees space taken by a matrix.
786:   
787:    Collective on Mat

789:    Input Parameter:
790: .  A - the matrix

792:    Level: beginner

794: @*/
795: PetscErrorCode  MatDestroy(Mat A)
796: {
800:   if (--((PetscObject)A)->refct > 0) return(0);
801:   MatPreallocated(A);
802:   /* if memory was published with AMS then destroy it */
803:   PetscObjectDepublish(A);
804:   if (A->ops->destroy) {
805:     (*A->ops->destroy)(A);
806:   }
807:   if (A->mapping) {
808:     ISLocalToGlobalMappingDestroy(A->mapping);
809:   }
810:   if (A->bmapping) {
811:     ISLocalToGlobalMappingDestroy(A->bmapping);
812:   }

814:   if (A->spptr){PetscFree(A->spptr);}
815:   PetscMapDestroy(A->rmap);
816:   PetscMapDestroy(A->cmap);
817:   PetscHeaderDestroy(A);
818:   return(0);
819: }

823: /*@
824:    MatValid - Checks whether a matrix object is valid.

826:    Collective on Mat

828:    Input Parameter:
829: .  m - the matrix to check 

831:    Output Parameter:
832:    flg - flag indicating matrix status, either
833:    PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise.

835:    Level: developer

837:    Concepts: matrices^validity
838: @*/
839: PetscErrorCode  MatValid(Mat m,PetscTruth *flg)
840: {
843:   if (!m)                                          *flg = PETSC_FALSE;
844:   else if (((PetscObject)m)->cookie != MAT_COOKIE) *flg = PETSC_FALSE;
845:   else                                             *flg = PETSC_TRUE;
846:   return(0);
847: }

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

856:    Not Collective

858:    Input Parameters:
859: +  mat - the matrix
860: .  v - a logically two-dimensional array of values
861: .  m, idxm - the number of rows and their global indices 
862: .  n, idxn - the number of columns and their global indices
863: -  addv - either ADD_VALUES or INSERT_VALUES, where
864:    ADD_VALUES adds values to any existing entries, and
865:    INSERT_VALUES replaces existing entries with new values

867:    Notes:
868:    By default the values, v, are row-oriented and unsorted.
869:    See MatSetOption() for other options.

871:    Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 
872:    options cannot be mixed without intervening calls to the assembly
873:    routines.

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

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

883:    Efficiency Alert:
884:    The routine MatSetValuesBlocked() may offer much better efficiency
885:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

887:    Level: beginner

889:    Concepts: matrices^putting entries in

891: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
892:           InsertMode, INSERT_VALUES, ADD_VALUES
893: @*/
894: PetscErrorCode  MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
895: {

901:   if (!m || !n) return(0); /* no values to insert */
904:   MatPreallocated(mat);
905:   if (mat->insertmode == NOT_SET_VALUES) {
906:     mat->insertmode = addv;
907:   }
908: #if defined(PETSC_USE_DEBUG)
909:   else if (mat->insertmode != addv) {
910:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
911:   }
912:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
913: #endif

915:   if (mat->assembled) {
916:     mat->was_assembled = PETSC_TRUE;
917:     mat->assembled     = PETSC_FALSE;
918:   }
919:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
920:   if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
921:   (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
922:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
923:   return(0);
924: }


929: /*@ 
930:    MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
931:         values into a matrix

933:    Not Collective

935:    Input Parameters:
936: +  mat - the matrix
937: .  row - the (block) row to set
938: -  v - a logically two-dimensional array of values

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

943:    All the nonzeros in the row must be provided

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

947:    The row must belong to this process

949:    Level: intermediate

951:    Concepts: matrices^putting entries in

953: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
954:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
955: @*/
956: PetscErrorCode  MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
957: {

964:   MatSetValuesRow(mat, mat->mapping->indices[row],v);
965:   return(0);
966: }

970: /*@ 
971:    MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
972:         values into a matrix

974:    Not Collective

976:    Input Parameters:
977: +  mat - the matrix
978: .  row - the (block) row to set
979: -  v - a logically two-dimensional array of values

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

984:    All the nonzeros in the row must be provided

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

988:    The row must belong to this process

990:    Level: intermediate

992:    Concepts: matrices^putting entries in

994: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
995:           InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
996: @*/
997: PetscErrorCode  MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
998: {

1005: #if defined(PETSC_USE_DEBUG)
1006:   if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1007:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1008: #endif
1009:   mat->insertmode = INSERT_VALUES;

1011:   if (mat->assembled) {
1012:     mat->was_assembled = PETSC_TRUE;
1013:     mat->assembled     = PETSC_FALSE;
1014:   }
1015:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1016:   if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1017:   (*mat->ops->setvaluesrow)(mat,row,v);
1018:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1019:   return(0);
1020: }

1024: /*@
1025:    MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1026:      Using structured grid indexing

1028:    Not Collective

1030:    Input Parameters:
1031: +  mat - the matrix
1032: .  v - a logically two-dimensional array of values
1033: .  m - number of rows being entered
1034: .  idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1035: .  n - number of columns being entered
1036: .  idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 
1037: -  addv - either ADD_VALUES or INSERT_VALUES, where
1038:    ADD_VALUES adds values to any existing entries, and
1039:    INSERT_VALUES replaces existing entries with new values

1041:    Notes:
1042:    By default the values, v, are row-oriented and unsorted.
1043:    See MatSetOption() for other options.

1045:    Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 
1046:    options cannot be mixed without intervening calls to the assembly
1047:    routines.

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

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

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

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

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

1065:    In Fortran idxm and idxn should be declared as
1066: $     MatStencil idxm(4,m),idxn(4,n)
1067:    and the values inserted using
1068: $    idxm(MatStencil_i,1) = i
1069: $    idxm(MatStencil_j,1) = j
1070: $    idxm(MatStencil_k,1) = k
1071: $    idxm(MatStencil_c,1) = c
1072:    etc

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

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

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

1085:    Efficiency Alert:
1086:    The routine MatSetValuesBlockedStencil() may offer much better efficiency
1087:    for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).

1089:    Level: beginner

1091:    Concepts: matrices^putting entries in

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

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

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

1113:   for (i=0; i<m; i++) {
1114:     for (j=0; j<3-sdim; j++) dxm++;
1115:     tmp = *dxm++ - starts[0];
1116:     for (j=0; j<dim-1; j++) {
1117:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1118:       else                                       tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1119:     }
1120:     if (mat->stencil.noc) dxm++;
1121:     jdxm[i] = tmp;
1122:   }
1123:   for (i=0; i<n; i++) {
1124:     for (j=0; j<3-sdim; j++) dxn++;
1125:     tmp = *dxn++ - starts[0];
1126:     for (j=0; j<dim-1; j++) {
1127:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1128:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1129:     }
1130:     if (mat->stencil.noc) dxn++;
1131:     jdxn[i] = tmp;
1132:   }
1133:   MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1134:   return(0);
1135: }

1139: /*@C 
1140:    MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1141:      Using structured grid indexing

1143:    Not Collective

1145:    Input Parameters:
1146: +  mat - the matrix
1147: .  v - a logically two-dimensional array of values
1148: .  m - number of rows being entered
1149: .  idxm - grid coordinates for matrix rows being entered
1150: .  n - number of columns being entered
1151: .  idxn - grid coordinates for matrix columns being entered 
1152: -  addv - either ADD_VALUES or INSERT_VALUES, where
1153:    ADD_VALUES adds values to any existing entries, and
1154:    INSERT_VALUES replaces existing entries with new values

1156:    Notes:
1157:    By default the values, v, are row-oriented and unsorted.
1158:    See MatSetOption() for other options.

1160:    Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 
1161:    options cannot be mixed without intervening calls to the assembly
1162:    routines.

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

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

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

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

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

1180:    In Fortran idxm and idxn should be declared as
1181: $     MatStencil idxm(4,m),idxn(4,n)
1182:    and the values inserted using
1183: $    idxm(MatStencil_i,1) = i
1184: $    idxm(MatStencil_j,1) = j
1185: $    idxm(MatStencil_k,1) = k
1186:    etc

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

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

1196:    Level: beginner

1198:    Concepts: matrices^putting entries in

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

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

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

1220:   for (i=0; i<m; i++) {
1221:     for (j=0; j<3-sdim; j++) dxm++;
1222:     tmp = *dxm++ - starts[0];
1223:     for (j=0; j<sdim-1; j++) {
1224:       if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1225:       else                                      tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1226:     }
1227:     dxm++;
1228:     jdxm[i] = tmp;
1229:   }
1230:   for (i=0; i<n; i++) {
1231:     for (j=0; j<3-sdim; j++) dxn++;
1232:     tmp = *dxn++ - starts[0];
1233:     for (j=0; j<sdim-1; j++) {
1234:       if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
1235:       else                                       tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1236:     }
1237:     dxn++;
1238:     jdxn[i] = tmp;
1239:   }
1240:   MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1241:   return(0);
1242: }

1246: /*@ 
1247:    MatSetStencil - Sets the grid information for setting values into a matrix via
1248:         MatSetValuesStencil()

1250:    Not Collective

1252:    Input Parameters:
1253: +  mat - the matrix
1254: .  dim - dimension of the grid 1, 2, or 3
1255: .  dims - number of grid points in x, y, and z direction, including ghost points on your processor
1256: .  starts - starting point of ghost nodes on your processor in x, y, and z direction 
1257: -  dof - number of degrees of freedom per node


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

1263:    For matrices generated with DAGetMatrix() this routine is automatically called and so not needed by the
1264:    user.
1265:    
1266:    Level: beginner

1268:    Concepts: matrices^putting entries in

1270: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1271:           MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1272: @*/
1273: PetscErrorCode  MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1274: {
1275:   PetscInt i;


1282:   mat->stencil.dim = dim + (dof > 1);
1283:   for (i=0; i<dim; i++) {
1284:     mat->stencil.dims[i]   = dims[dim-i-1];      /* copy the values in backwards */
1285:     mat->stencil.starts[i] = starts[dim-i-1];
1286:   }
1287:   mat->stencil.dims[dim]   = dof;
1288:   mat->stencil.starts[dim] = 0;
1289:   mat->stencil.noc         = (PetscTruth)(dof == 1);
1290:   return(0);
1291: }

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

1298:    Not Collective

1300:    Input Parameters:
1301: +  mat - the matrix
1302: .  v - a logically two-dimensional array of values
1303: .  m, idxm - the number of block rows and their global block indices 
1304: .  n, idxn - the number of block columns and their global block indices
1305: -  addv - either ADD_VALUES or INSERT_VALUES, where
1306:    ADD_VALUES adds values to any existing entries, and
1307:    INSERT_VALUES replaces existing entries with new values

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

1316:    By default the values, v, are row-oriented and unsorted. So the layout of 
1317:    v is the same as for MatSetValues(). See MatSetOption() for other options.

1319:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
1320:    options cannot be mixed without intervening calls to the assembly
1321:    routines.

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

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

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

1337:    Example:
1338: $   Suppose m=n=2 and block size(bs) = 2 The array is 
1339: $
1340: $   1  2  | 3  4
1341: $   5  6  | 7  8
1342: $   - - - | - - -
1343: $   9  10 | 11 12
1344: $   13 14 | 15 16
1345: $
1346: $   v[] should be passed in like
1347: $   v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1348: $
1349: $  If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1350: $   v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]

1352:    Level: intermediate

1354:    Concepts: matrices^putting entries in blocked

1356: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1357: @*/
1358: PetscErrorCode  MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1359: {

1365:   if (!m || !n) return(0); /* no values to insert */
1369:   MatPreallocated(mat);
1370:   if (mat->insertmode == NOT_SET_VALUES) {
1371:     mat->insertmode = addv;
1372:   }
1373: #if defined(PETSC_USE_DEBUG) 
1374:   else if (mat->insertmode != addv) {
1375:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1376:   }
1377:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1378: #endif

1380:   if (mat->assembled) {
1381:     mat->was_assembled = PETSC_TRUE;
1382:     mat->assembled     = PETSC_FALSE;
1383:   }
1384:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1385:   if (mat->ops->setvaluesblocked) {
1386:     (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1387:   } else {
1388:     PetscInt buf[4096],*ibufm=0,*ibufn=0;
1389:     PetscInt i,j,*iidxm,*iidxn,bs=mat->rmap->bs;
1390:     if ((m+n)*bs <= 4096) {
1391:       iidxm = buf; iidxn = buf + m*bs;
1392:     } else {
1393:       PetscMalloc2(m*bs,PetscInt,&ibufm,n*bs,PetscInt,&ibufn);
1394:       iidxm = ibufm; iidxn = ibufn;
1395:     }
1396:     for (i=0; i<m; i++) {
1397:       for (j=0; j<bs; j++) {
1398:         iidxm[i*bs+j] = bs*idxm[i] + j;
1399:       }
1400:     }
1401:     for (i=0; i<n; i++) {
1402:       for (j=0; j<bs; j++) {
1403:         iidxn[i*bs+j] = bs*idxn[i] + j;
1404:       }
1405:     }
1406:     MatSetValues(mat,bs*m,iidxm,bs*n,iidxn,v,addv);
1407:     PetscFree2(ibufm,ibufn);
1408:   }
1409:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1410:   return(0);
1411: }

1415: /*@ 
1416:    MatGetValues - Gets a block of values from a matrix.

1418:    Not Collective; currently only returns a local block

1420:    Input Parameters:
1421: +  mat - the matrix
1422: .  v - a logically two-dimensional array for storing the values
1423: .  m, idxm - the number of rows and their global indices 
1424: -  n, idxn - the number of columns and their global indices

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

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

1434:    MatGetValues() requires that the matrix has been assembled
1435:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1436:    MatSetValues() and MatGetValues() CANNOT be made in succession
1437:    without intermediate matrix assembly.

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

1442:    Level: advanced

1444:    Concepts: matrices^accessing values

1446: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1447: @*/
1448: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1449: {

1458:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1459:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1460:   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1461:   MatPreallocated(mat);

1463:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1464:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1465:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1466:   return(0);
1467: }

1471: /*@
1472:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1473:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1474:    using a local (per-processor) numbering.

1476:    Not Collective

1478:    Input Parameters:
1479: +  x - the matrix
1480: -  mapping - mapping created with ISLocalToGlobalMappingCreate() 
1481:              or ISLocalToGlobalMappingCreateIS()

1483:    Level: intermediate

1485:    Concepts: matrices^local to global mapping
1486:    Concepts: local to global mapping^for matrices

1488: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1489: @*/
1490: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1491: {
1497:   if (x->mapping) {
1498:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1499:   }
1500:   MatPreallocated(x);

1502:   if (x->ops->setlocaltoglobalmapping) {
1503:     (*x->ops->setlocaltoglobalmapping)(x,mapping);
1504:   } else {
1505:     PetscObjectReference((PetscObject)mapping);
1506:     if (x->mapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1507:     x->mapping = mapping;
1508:   }
1509:   return(0);
1510: }

1514: /*@
1515:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1516:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1517:    entries using a local (per-processor) numbering.

1519:    Not Collective

1521:    Input Parameters:
1522: +  x - the matrix
1523: -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
1524:              ISLocalToGlobalMappingCreateIS()

1526:    Level: intermediate

1528:    Concepts: matrices^local to global mapping blocked
1529:    Concepts: local to global mapping^for matrices, blocked

1531: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1532:            MatSetValuesBlocked(), MatSetValuesLocal()
1533: @*/
1534: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1535: {
1541:   if (x->bmapping) {
1542:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1543:   }
1544:   PetscObjectReference((PetscObject)mapping);
1545:   if (x->bmapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1546:   x->bmapping = mapping;
1547:   return(0);
1548: }

1552: /*@
1553:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1554:    using a local ordering of the nodes. 

1556:    Not Collective

1558:    Input Parameters:
1559: +  x - the matrix
1560: .  nrow, irow - number of rows and their local indices
1561: .  ncol, icol - number of columns and their local indices
1562: .  y -  a logically two-dimensional array of values
1563: -  addv - either INSERT_VALUES or ADD_VALUES, where
1564:    ADD_VALUES adds values to any existing entries, and
1565:    INSERT_VALUES replaces existing entries with new values

1567:    Notes:
1568:    Before calling MatSetValuesLocal(), the user must first set the
1569:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

1571:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
1572:    options cannot be mixed without intervening calls to the assembly
1573:    routines.

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

1578:    Level: intermediate

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

1582: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1583:            MatSetValueLocal()
1584: @*/
1585: PetscErrorCode  MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1586: {
1588:   PetscInt       irowm[2048],icolm[2048];

1593:   if (!nrow || !ncol) return(0); /* no values to insert */
1597:   MatPreallocated(mat);
1598:   if (mat->insertmode == NOT_SET_VALUES) {
1599:     mat->insertmode = addv;
1600:   }
1601: #if defined(PETSC_USE_DEBUG) 
1602:   else if (mat->insertmode != addv) {
1603:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1604:   }
1605:   if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) {
1606:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1607:   }
1608:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1609: #endif

1611:   if (mat->assembled) {
1612:     mat->was_assembled = PETSC_TRUE;
1613:     mat->assembled     = PETSC_FALSE;
1614:   }
1615:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1616:   if (!mat->ops->setvalueslocal) {
1617:     ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);
1618:     ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);
1619:     (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);
1620:   } else {
1621:     (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1622:   }
1623:   mat->same_nonzero = PETSC_FALSE;
1624:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1625:   return(0);
1626: }

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

1634:    Not Collective

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

1645:    Notes:
1646:    Before calling MatSetValuesBlockedLocal(), the user must first set the
1647:    local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(),
1648:    where the mapping MUST be set for matrix blocks, not for matrix elements.

1650:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
1651:    options cannot be mixed without intervening calls to the assembly
1652:    routines.

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

1657:    Level: intermediate

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

1661: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1662: @*/
1663: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1664: {
1666:   PetscInt       irowm[2048],icolm[2048];

1671:   if (!nrow || !ncol) return(0); /* no values to insert */
1675:   MatPreallocated(mat);
1676:   if (mat->insertmode == NOT_SET_VALUES) {
1677:     mat->insertmode = addv;
1678:   }
1679: #if defined(PETSC_USE_DEBUG) 
1680:   else if (mat->insertmode != addv) {
1681:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1682:   }
1683:   if (!mat->bmapping) {
1684:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()");
1685:   }
1686:   if (nrow > 2048 || ncol > 2048) {
1687:     SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %D %D",nrow,ncol);
1688:   }
1689:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1690: #endif

1692:   if (mat->assembled) {
1693:     mat->was_assembled = PETSC_TRUE;
1694:     mat->assembled     = PETSC_FALSE;
1695:   }
1696:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1697:   ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);
1698:   ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);
1699:   if (mat->ops->setvaluesblocked) {
1700:   (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);
1701:   } else {
1702:     PetscInt buf[4096],*ibufm=0,*ibufn=0;
1703:     PetscInt i,j,*iirowm,*iicolm,bs=mat->rmap->bs;
1704:     if ((nrow+ncol)*bs <= 4096) {
1705:       iirowm = buf; iicolm = buf + nrow*bs;
1706:     } else {
1707:       PetscMalloc2(nrow*bs,PetscInt,&ibufm,ncol*bs,PetscInt,&ibufn);
1708:       iirowm = ibufm; iicolm = ibufn;
1709:     }
1710:     for (i=0; i<nrow; i++) {
1711:       for (j=0; j<bs; j++) {
1712:         iirowm[i*bs+j] = bs*irowm[i] + j;
1713:       }
1714:     }
1715:     for (i=0; i<ncol; i++) {
1716:       for (j=0; j<bs; j++) {
1717:         iicolm[i*bs+j] = bs*icolm[i] + j;
1718:       }
1719:     }
1720:     MatSetValues(mat,bs*nrow,iirowm,bs*ncol,iicolm,y,addv);
1721:     PetscFree2(ibufm,ibufn);
1722:   }
1723:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1724:   return(0);
1725: }

1727: /* --------------------------------------------------------*/
1730: /*@
1731:    MatMult - Computes the matrix-vector product, y = Ax.

1733:    Collective on Mat and Vec

1735:    Input Parameters:
1736: +  mat - the matrix
1737: -  x   - the vector to be multiplied

1739:    Output Parameters:
1740: .  y - the result

1742:    Notes:
1743:    The vectors x and y cannot be the same.  I.e., one cannot
1744:    call MatMult(A,y,y).

1746:    Level: beginner

1748:    Concepts: matrix-vector product

1750: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1751: @*/
1752: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
1753: {


1762:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1763:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1764:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1765: #ifndef PETSC_HAVE_CONSTRAINTS
1766:   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);
1767:   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);
1768:   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);
1769: #endif
1770:   MatPreallocated(mat);

1772:   if (mat->nullsp) {
1773:     MatNullSpaceRemove(mat->nullsp,x,&x);
1774:   }

1776:   if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1777:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1778:   (*mat->ops->mult)(mat,x,y);
1779:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);

1781:   if (mat->nullsp) {
1782:     MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1783:   }
1784:   PetscObjectStateIncrease((PetscObject)y);
1785:   return(0);
1786: }

1790: /*@
1791:    MatMultTranspose - Computes matrix transpose times a vector.

1793:    Collective on Mat and Vec

1795:    Input Parameters:
1796: +  mat - the matrix
1797: -  x   - the vector to be multilplied

1799:    Output Parameters:
1800: .  y - the result

1802:    Notes:
1803:    The vectors x and y cannot be the same.  I.e., one cannot
1804:    call MatMultTranspose(A,y,y).

1806:    Level: beginner

1808:    Concepts: matrix vector product^transpose

1810: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1811: @*/
1812: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
1813: {


1822:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1823:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1824:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1825: #ifndef PETSC_HAVE_CONSTRAINTS
1826:   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);
1827:   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);
1828: #endif
1829:   MatPreallocated(mat);

1831:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1832:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1833:   (*mat->ops->multtranspose)(mat,x,y);
1834:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1835:   PetscObjectStateIncrease((PetscObject)y);
1836:   return(0);
1837: }

1841: /*@
1842:     MatMultAdd -  Computes v3 = v2 + A * v1.

1844:     Collective on Mat and Vec

1846:     Input Parameters:
1847: +   mat - the matrix
1848: -   v1, v2 - the vectors

1850:     Output Parameters:
1851: .   v3 - the result

1853:     Notes:
1854:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1855:     call MatMultAdd(A,v1,v2,v1).

1857:     Level: beginner

1859:     Concepts: matrix vector product^addition

1861: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1862: @*/
1863: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1864: {


1874:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1875:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1876:   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);
1877:   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);
1878:   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);
1879:   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);
1880:   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);
1881:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1882:   MatPreallocated(mat);

1884:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
1885:   (*mat->ops->multadd)(mat,v1,v2,v3);
1886:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
1887:   PetscObjectStateIncrease((PetscObject)v3);
1888:   return(0);
1889: }

1893: /*@
1894:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

1896:    Collective on Mat and Vec

1898:    Input Parameters:
1899: +  mat - the matrix
1900: -  v1, v2 - the vectors

1902:    Output Parameters:
1903: .  v3 - the result

1905:    Notes:
1906:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1907:    call MatMultTransposeAdd(A,v1,v2,v1).

1909:    Level: beginner

1911:    Concepts: matrix vector product^transpose and addition

1913: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1914: @*/
1915: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1916: {


1926:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1927:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1928:   if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1929:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1930:   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);
1931:   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);
1932:   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);
1933:   MatPreallocated(mat);

1935:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
1936:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
1937:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
1938:   PetscObjectStateIncrease((PetscObject)v3);
1939:   return(0);
1940: }

1944: /*@
1945:    MatMultConstrained - The inner multiplication routine for a
1946:    constrained matrix P^T A P.

1948:    Collective on Mat and Vec

1950:    Input Parameters:
1951: +  mat - the matrix
1952: -  x   - the vector to be multilplied

1954:    Output Parameters:
1955: .  y - the result

1957:    Notes:
1958:    The vectors x and y cannot be the same.  I.e., one cannot
1959:    call MatMult(A,y,y).

1961:    Level: beginner

1963: .keywords: matrix, multiply, matrix-vector product, constraint
1964: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1965: @*/
1966: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
1967: {

1974:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1975:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1976:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1977:   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);
1978:   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);
1979:   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);

1981:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1982:   (*mat->ops->multconstrained)(mat,x,y);
1983:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1984:   PetscObjectStateIncrease((PetscObject)y);

1986:   return(0);
1987: }

1991: /*@
1992:    MatMultTransposeConstrained - The inner multiplication routine for a
1993:    constrained matrix P^T A^T P.

1995:    Collective on Mat and Vec

1997:    Input Parameters:
1998: +  mat - the matrix
1999: -  x   - the vector to be multilplied

2001:    Output Parameters:
2002: .  y - the result

2004:    Notes:
2005:    The vectors x and y cannot be the same.  I.e., one cannot
2006:    call MatMult(A,y,y).

2008:    Level: beginner

2010: .keywords: matrix, multiply, matrix-vector product, constraint
2011: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
2012: @*/
2013: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2014: {

2021:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2022:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2023:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2024:   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);
2025:   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);

2027:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2028:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2029:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2030:   PetscObjectStateIncrease((PetscObject)y);

2032:   return(0);
2033: }
2034: /* ------------------------------------------------------------*/
2037: /*@C
2038:    MatGetInfo - Returns information about matrix storage (number of
2039:    nonzeros, memory, etc.).

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

2044:    Input Parameters:
2045: .  mat - the matrix

2047:    Output Parameters:
2048: +  flag - flag indicating the type of parameters to be returned
2049:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2050:    MAT_GLOBAL_SUM - sum over all processors)
2051: -  info - matrix information context

2053:    Notes:
2054:    The MatInfo context contains a variety of matrix data, including
2055:    number of nonzeros allocated and used, number of mallocs during
2056:    matrix assembly, etc.  Additional information for factored matrices
2057:    is provided (such as the fill ratio, number of mallocs during
2058:    factorization, etc.).  Much of this info is printed to PETSC_STDOUT
2059:    when using the runtime options 
2060: $       -info -mat_view_info

2062:    Example for C/C++ Users:
2063:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2064:    data within the MatInfo context.  For example, 
2065: .vb
2066:       MatInfo info;
2067:       Mat     A;
2068:       double  mal, nz_a, nz_u;

2070:       MatGetInfo(A,MAT_LOCAL,&info);
2071:       mal  = info.mallocs;
2072:       nz_a = info.nz_allocated;
2073: .ve

2075:    Example for Fortran Users:
2076:    Fortran users should declare info as a double precision
2077:    array of dimension MAT_INFO_SIZE, and then extract the parameters
2078:    of interest.  See the file ${PETSC_DIR}/include/finclude/petscmat.h
2079:    a complete list of parameter names.
2080: .vb
2081:       double  precision info(MAT_INFO_SIZE)
2082:       double  precision mal, nz_a
2083:       Mat     A
2084:       integer ierr

2086:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2087:       mal = info(MAT_INFO_MALLOCS)
2088:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2089: .ve

2091:     Level: intermediate

2093:     Concepts: matrices^getting information on
2094:     
2095:     Developer Note: fortran interface is not autogenerated as the f90
2096:     interface defintion cannot be generated correctly [due to MatInfo]
2097:  
2098: @*/
2099: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2100: {

2107:   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2108:   MatPreallocated(mat);
2109:   (*mat->ops->getinfo)(mat,flag,info);
2110:   return(0);
2111: }

2113: /* ----------------------------------------------------------*/
2116: /*@C  
2117:    MatILUDTFactor - Performs a drop tolerance ILU factorization.

2119:    Collective on Mat

2121:    Input Parameters:
2122: +  mat - the matrix
2123: .  row - row permutation
2124: .  col - column permutation
2125: -  info - information about the factorization to be done

2127:    Output Parameters:
2128: .  fact - the factored matrix

2130:    Level: developer

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

2137:    This is currently only supported for the SeqAIJ matrix format using code
2138:    from Yousef Saad's SPARSEKIT2  package (translated to C with f2c) and/or
2139:    Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright
2140:    and thus can be distributed with PETSc.

2142:     Concepts: matrices^ILUDT factorization

2144: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2145: @*/
2146: PetscErrorCode  MatILUDTFactor(Mat mat,IS row,IS col,const MatFactorInfo *info,Mat *fact)
2147: {

2157:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2158:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2159:   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2160:   MatPreallocated(mat);
2161:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2162:   (*mat->ops->iludtfactor)(mat,row,col,info,fact);
2163:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2164:   PetscObjectStateIncrease((PetscObject)*fact);

2166:   return(0);
2167: }

2171: /*@C
2172:    MatLUFactor - Performs in-place LU factorization of matrix.

2174:    Collective on Mat

2176:    Input Parameters:
2177: +  mat - the matrix
2178: .  row - row permutation
2179: .  col - column permutation
2180: -  info - options for factorization, includes 
2181: $          fill - expected fill as ratio of original fill.
2182: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2183: $                   Run with the option -info to determine an optimal value to use

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

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

2193:    Level: developer

2195:    Concepts: matrices^LU factorization

2197: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2198:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo

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

2203: @*/
2204: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2205: {

2214:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2215:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2216:   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2217:   MatPreallocated(mat);

2219:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2220:   (*mat->ops->lufactor)(mat,row,col,info);
2221:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2222:   PetscObjectStateIncrease((PetscObject)mat);
2223:   return(0);
2224: }

2228: /*@C
2229:    MatILUFactor - Performs in-place ILU factorization of matrix.

2231:    Collective on Mat

2233:    Input Parameters:
2234: +  mat - the matrix
2235: .  row - row permutation
2236: .  col - column permutation
2237: -  info - structure containing 
2238: $      levels - number of levels of fill.
2239: $      expected fill - as ratio of original fill.
2240: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2241:                 missing diagonal entries)

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

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

2251:    Level: developer

2253:    Concepts: matrices^ILU factorization

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

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

2260: @*/
2261: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2262: {

2271:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2272:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2273:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2274:   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2275:   MatPreallocated(mat);

2277:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2278:   (*mat->ops->ilufactor)(mat,row,col,info);
2279:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2280:   PetscObjectStateIncrease((PetscObject)mat);
2281:   return(0);
2282: }

2286: /*@C
2287:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2288:    Call this routine before calling MatLUFactorNumeric().

2290:    Collective on Mat

2292:    Input Parameters:
2293: +  fact - the factor matrix obtained with MatGetFactor()
2294: .  mat - the matrix
2295: .  row, col - row and column permutations
2296: -  info - options for factorization, includes 
2297: $          fill - expected fill as ratio of original fill.
2298: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2299: $                   Run with the option -info to determine an optimal value to use


2302:    Notes:
2303:    See the users manual for additional information about
2304:    choosing the fill factor for better efficiency.

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

2310:    Level: developer

2312:    Concepts: matrices^LU symbolic factorization

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

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

2319: @*/
2320: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2321: {

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

2336:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2337:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2338:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2339:   PetscObjectStateIncrease((PetscObject)fact);
2340:   return(0);
2341: }

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

2349:    Collective on Mat

2351:    Input Parameters:
2352: +  fact - the factor matrix obtained with MatGetFactor()
2353: .  mat - the matrix
2354: -  info - options for factorization

2356:    Notes:
2357:    See MatLUFactor() for in-place factorization.  See 
2358:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

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

2364:    Level: developer

2366:    Concepts: matrices^LU numeric factorization

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

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

2373: @*/
2374: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2375: {

2383:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2384:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2385:     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);
2386:   }
2387:   if (!(fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2388:   MatPreallocated(mat);
2389:   PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2390:   (fact->ops->lufactornumeric)(fact,mat,info);
2391:   PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);

2393:   MatView_Private(fact);
2394:   PetscObjectStateIncrease((PetscObject)fact);
2395:   return(0);
2396: }

2400: /*@C
2401:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2402:    symmetric matrix. 

2404:    Collective on Mat

2406:    Input Parameters:
2407: +  mat - the matrix
2408: .  perm - row and column permutations
2409: -  f - expected fill as ratio of original fill

2411:    Notes:
2412:    See MatLUFactor() for the nonsymmetric case.  See also
2413:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2419:    Level: developer

2421:    Concepts: matrices^Cholesky factorization

2423: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2424:           MatGetOrdering()

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

2429: @*/
2430: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2431: {

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

2445:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2446:   (*mat->ops->choleskyfactor)(mat,perm,info);
2447:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2448:   PetscObjectStateIncrease((PetscObject)mat);
2449:   return(0);
2450: }

2454: /*@C
2455:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2456:    of a symmetric matrix. 

2458:    Collective on Mat

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

2469:    Notes:
2470:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2471:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2477:    Level: developer

2479:    Concepts: matrices^Cholesky symbolic factorization

2481: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2482:           MatGetOrdering()

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

2487: @*/
2488: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2489: {

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

2504:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2505:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2506:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2507:   PetscObjectStateIncrease((PetscObject)fact);
2508:   return(0);
2509: }

2513: /*@C
2514:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2515:    of a symmetric matrix. Call this routine after first calling
2516:    MatCholeskyFactorSymbolic().

2518:    Collective on Mat

2520:    Input Parameters:
2521: +  fact - the factor matrix obtained with MatGetFactor()
2522: .  mat - the initial matrix
2523: .  info - options for factorization
2524: -  fact - the symbolic factor of mat


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

2532:    Level: developer

2534:    Concepts: matrices^Cholesky numeric factorization

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

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

2541: @*/
2542: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2543: {

2551:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2552:   if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2553:   if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) {
2554:     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);
2555:   }
2556:   MatPreallocated(mat);

2558:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2559:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
2560:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

2562:   MatView_Private(fact);
2563:   PetscObjectStateIncrease((PetscObject)fact);
2564:   return(0);
2565: }

2567: /* ----------------------------------------------------------------*/
2570: /*@
2571:    MatSolve - Solves A x = b, given a factored matrix.

2573:    Collective on Mat and Vec

2575:    Input Parameters:
2576: +  mat - the factored matrix
2577: -  b - the right-hand-side vector

2579:    Output Parameter:
2580: .  x - the result vector

2582:    Notes:
2583:    The vectors b and x cannot be the same.  I.e., one cannot
2584:    call MatSolve(A,x,x).

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

2591:    Level: developer

2593:    Concepts: matrices^triangular solves

2595: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2596: @*/
2597: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
2598: {

2608:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2609:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2610:   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);
2611:   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);
2612:   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);
2613:   if (!mat->rmap->N && !mat->cmap->N) return(0);
2614:   if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2615:   MatPreallocated(mat);

2617:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2618:   (*mat->ops->solve)(mat,b,x);
2619:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2620:   PetscObjectStateIncrease((PetscObject)x);
2621:   return(0);
2622: }

2626: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
2627: {
2629:   Vec            b,x;
2630:   PetscInt       m,N,i;
2631:   PetscScalar    *bb,*xx;

2634:   MatGetArray(B,&bb);
2635:   MatGetArray(X,&xx);
2636:   MatGetLocalSize(B,&m,PETSC_NULL);  /* number local rows */
2637:   MatGetSize(B,PETSC_NULL,&N);       /* total columns in dense matrix */
2638:   VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&b);
2639:   VecCreateMPIWithArray(((PetscObject)A)->comm,m,PETSC_DETERMINE,PETSC_NULL,&x);
2640:   for (i=0; i<N; i++) {
2641:     VecPlaceArray(b,bb + i*m);
2642:     VecPlaceArray(x,xx + i*m);
2643:     MatSolve(A,b,x);
2644:     VecResetArray(x);
2645:     VecResetArray(b);
2646:   }
2647:   VecDestroy(b);
2648:   VecDestroy(x);
2649:   MatRestoreArray(B,&bb);
2650:   MatRestoreArray(X,&xx);
2651:   return(0);
2652: }

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

2659:    Collective on Mat 

2661:    Input Parameters:
2662: +  mat - the factored matrix
2663: -  B - the right-hand-side matrix  (dense matrix)

2665:    Output Parameter:
2666: .  X - the result matrix (dense matrix)

2668:    Notes:
2669:    The matrices b and x cannot be the same.  I.e., one cannot
2670:    call MatMatSolve(A,x,x).

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

2678:    Level: developer

2680:    Concepts: matrices^triangular solves

2682: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2683: @*/
2684: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
2685: {

2695:   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2696:   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2697:   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);
2698:   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);
2699:   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);
2700:   if (!A->rmap->N && !A->cmap->N) return(0);
2701:   MatPreallocated(A);

2703:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
2704:   if (!A->ops->matsolve) {
2705:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
2706:     MatMatSolve_Basic(A,B,X);
2707:   } else {
2708:     (*A->ops->matsolve)(A,B,X);
2709:   }
2710:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
2711:   PetscObjectStateIncrease((PetscObject)X);
2712:   return(0);
2713: }


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

2722:    Collective on Mat and Vec

2724:    Input Parameters:
2725: +  mat - the factored matrix
2726: -  b - the right-hand-side vector

2728:    Output Parameter:
2729: .  x - the result vector

2731:    Notes:
2732:    MatSolve() should be used for most applications, as it performs
2733:    a forward solve followed by a backward solve.

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

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

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

2748:    Level: developer

2750:    Concepts: matrices^forward solves

2752: .seealso: MatSolve(), MatBackwardSolve()
2753: @ */
2754: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
2755: {

2765:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2766:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2767:   if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2768:   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);
2769:   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);
2770:   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);
2771:   MatPreallocated(mat);
2772:   PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
2773:   (*mat->ops->forwardsolve)(mat,b,x);
2774:   PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
2775:   PetscObjectStateIncrease((PetscObject)x);
2776:   return(0);
2777: }

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

2785:    Collective on Mat and Vec

2787:    Input Parameters:
2788: +  mat - the factored matrix
2789: -  b - the right-hand-side vector

2791:    Output Parameter:
2792: .  x - the result vector

2794:    Notes:
2795:    MatSolve() should be used for most applications, as it performs
2796:    a forward solve followed by a backward solve.

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

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

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

2811:    Level: developer

2813:    Concepts: matrices^backward solves

2815: .seealso: MatSolve(), MatForwardSolve()
2816: @ */
2817: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
2818: {

2828:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2829:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2830:   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2831:   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);
2832:   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);
2833:   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);
2834:   MatPreallocated(mat);

2836:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
2837:   (*mat->ops->backwardsolve)(mat,b,x);
2838:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
2839:   PetscObjectStateIncrease((PetscObject)x);
2840:   return(0);
2841: }

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

2848:    Collective on Mat and Vec

2850:    Input Parameters:
2851: +  mat - the factored matrix
2852: .  b - the right-hand-side vector
2853: -  y - the vector to be added to 

2855:    Output Parameter:
2856: .  x - the result vector

2858:    Notes:
2859:    The vectors b and x cannot be the same.  I.e., one cannot
2860:    call MatSolveAdd(A,x,y,x).

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

2866:    Level: developer

2868:    Concepts: matrices^triangular solves

2870: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2871: @*/
2872: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2873: {
2874:   PetscScalar    one = 1.0;
2875:   Vec            tmp;

2887:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2888:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2889:   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);
2890:   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);
2891:   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);
2892:   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);
2893:   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);
2894:   MatPreallocated(mat);

2896:   PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
2897:   if (mat->ops->solveadd)  {
2898:     (*mat->ops->solveadd)(mat,b,y,x);
2899:   } else {
2900:     /* do the solve then the add manually */
2901:     if (x != y) {
2902:       MatSolve(mat,b,x);
2903:       VecAXPY(x,one,y);
2904:     } else {
2905:       VecDuplicate(x,&tmp);
2906:       PetscLogObjectParent(mat,tmp);
2907:       VecCopy(x,tmp);
2908:       MatSolve(mat,b,x);
2909:       VecAXPY(x,one,tmp);
2910:       VecDestroy(tmp);
2911:     }
2912:   }
2913:   PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
2914:   PetscObjectStateIncrease((PetscObject)x);
2915:   return(0);
2916: }

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

2923:    Collective on Mat and Vec

2925:    Input Parameters:
2926: +  mat - the factored matrix
2927: -  b - the right-hand-side vector

2929:    Output Parameter:
2930: .  x - the result vector

2932:    Notes:
2933:    The vectors b and x cannot be the same.  I.e., one cannot
2934:    call MatSolveTranspose(A,x,x).

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

2940:    Level: developer

2942:    Concepts: matrices^triangular solves

2944: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
2945: @*/
2946: PetscErrorCode  MatSolveTranspose(Mat mat,Vec b,Vec x)
2947: {

2957:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2958:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2959:   if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
2960:   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);
2961:   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);
2962:   MatPreallocated(mat);
2963:   PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
2964:   (*mat->ops->solvetranspose)(mat,b,x);
2965:   PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
2966:   PetscObjectStateIncrease((PetscObject)x);
2967:   return(0);
2968: }

2972: /*@
2973:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
2974:                       factored matrix. 

2976:    Collective on Mat and Vec

2978:    Input Parameters:
2979: +  mat - the factored matrix
2980: .  b - the right-hand-side vector
2981: -  y - the vector to be added to 

2983:    Output Parameter:
2984: .  x - the result vector

2986:    Notes:
2987:    The vectors b and x cannot be the same.  I.e., one cannot
2988:    call MatSolveTransposeAdd(A,x,y,x).

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

2994:    Level: developer

2996:    Concepts: matrices^triangular solves

2998: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
2999: @*/
3000: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3001: {
3002:   PetscScalar    one = 1.0;
3004:   Vec            tmp;

3015:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3016:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3017:   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);
3018:   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);
3019:   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);
3020:   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);
3021:   MatPreallocated(mat);

3023:   PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3024:   if (mat->ops->solvetransposeadd) {
3025:     (*mat->ops->solvetransposeadd)(mat,b,y,x);
3026:   } else {
3027:     /* do the solve then the add manually */
3028:     if (x != y) {
3029:       MatSolveTranspose(mat,b,x);
3030:       VecAXPY(x,one,y);
3031:     } else {
3032:       VecDuplicate(x,&tmp);
3033:       PetscLogObjectParent(mat,tmp);
3034:       VecCopy(x,tmp);
3035:       MatSolveTranspose(mat,b,x);
3036:       VecAXPY(x,one,tmp);
3037:       VecDestroy(tmp);
3038:     }
3039:   }
3040:   PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3041:   PetscObjectStateIncrease((PetscObject)x);
3042:   return(0);
3043: }
3044: /* ----------------------------------------------------------------*/

3048: /*@
3049:    MatRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.

3051:    Collective on Mat and Vec

3053:    Input Parameters:
3054: +  mat - the matrix
3055: .  b - the right hand side
3056: .  omega - the relaxation factor
3057: .  flag - flag indicating the type of SOR (see below)
3058: .  shift -  diagonal shift
3059: .  its - the number of iterations
3060: -  lits - the number of local iterations 

3062:    Output Parameters:
3063: .  x - the solution (can contain an initial guess)

3065:    SOR Flags:
3066: .     SOR_FORWARD_SWEEP - forward SOR
3067: .     SOR_BACKWARD_SWEEP - backward SOR
3068: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3069: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
3070: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
3071: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3072: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
3073:          upper/lower triangular part of matrix to
3074:          vector (with omega)
3075: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3077:    Notes:
3078:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3079:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3080:    on each processor. 

3082:    Application programmers will not generally use MatRelax() directly,
3083:    but instead will employ the KSP/PC interface.

3085:    Notes for Advanced Users:
3086:    The flags are implemented as bitwise inclusive or operations.
3087:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3088:    to specify a zero initial guess for SSOR.

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

3094:    See also, MatPBRelax(). This routine will automatically call the point block
3095:    version if the point version is not available.

3097:    Level: developer

3099:    Concepts: matrices^relaxation
3100:    Concepts: matrices^SOR
3101:    Concepts: matrices^Gauss-Seidel

3103: @*/
3104: PetscErrorCode  MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3105: {

3115:   if (!mat->ops->relax && !mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3116:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3117:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3118:   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);
3119:   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);
3120:   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);
3121:   if (its <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3122:   if (lits <= 0) SETERRQ1(PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);

3124:   MatPreallocated(mat);
3125:   PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3126:   if (mat->ops->relax) {
3127:     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);
3128:   } else {
3129:     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3130:   }
3131:   PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3132:   PetscObjectStateIncrease((PetscObject)x);
3133:   return(0);
3134: }

3138: /*@
3139:    MatPBRelax - Computes relaxation (SOR, Gauss-Seidel) sweeps.

3141:    Collective on Mat and Vec

3143:    See MatRelax() for usage

3145:    For multi-component PDEs where the Jacobian is stored in a point block format
3146:    (with the PETSc BAIJ matrix formats) the relaxation is done one point block at 
3147:    a time. That is, the small (for example, 4 by 4) blocks along the diagonal are solved
3148:    simultaneously (that is a 4 by 4 linear solve is done) to update all the values at a point.

3150:    Level: developer

3152: @*/
3153: PetscErrorCode  MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3154: {

3164:   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3165:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3166:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3167:   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);
3168:   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);
3169:   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);
3170:   MatPreallocated(mat);

3172:   PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3173:   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3174:   PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3175:   PetscObjectStateIncrease((PetscObject)x);
3176:   return(0);
3177: }

3181: /*
3182:       Default matrix copy routine.
3183: */
3184: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3185: {
3186:   PetscErrorCode    ierr;
3187:   PetscInt          i,rstart,rend,nz;
3188:   const PetscInt    *cwork;
3189:   const PetscScalar *vwork;

3192:   if (B->assembled) {
3193:     MatZeroEntries(B);
3194:   }
3195:   MatGetOwnershipRange(A,&rstart,&rend);
3196:   for (i=rstart; i<rend; i++) {
3197:     MatGetRow(A,i,&nz,&cwork,&vwork);
3198:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3199:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3200:   }
3201:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3202:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3203:   PetscObjectStateIncrease((PetscObject)B);
3204:   return(0);
3205: }

3209: /*@
3210:    MatCopy - Copys a matrix to another matrix.

3212:    Collective on Mat

3214:    Input Parameters:
3215: +  A - the matrix
3216: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3218:    Output Parameter:
3219: .  B - where the copy is put

3221:    Notes:
3222:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
3223:    same nonzero pattern or the routine will crash.

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

3229:    Level: intermediate
3230:    
3231:    Concepts: matrices^copying

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

3235: @*/
3236: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3237: {
3239:   PetscInt       i;

3247:   MatPreallocated(B);
3248:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3249:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3250:   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);
3251:   MatPreallocated(A);

3253:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3254:   if (A->ops->copy) {
3255:     (*A->ops->copy)(A,B,str);
3256:   } else { /* generic conversion */
3257:     MatCopy_Basic(A,B,str);
3258:   }
3259:   if (A->mapping) {
3260:     if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
3261:     MatSetLocalToGlobalMapping(B,A->mapping);
3262:   }
3263:   if (A->bmapping) {
3264:     if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
3265:     MatSetLocalToGlobalMappingBlock(B,A->mapping);
3266:   }

3268:   B->stencil.dim = A->stencil.dim;
3269:   B->stencil.noc = A->stencil.noc;
3270:   for (i=0; i<=A->stencil.dim; i++) {
3271:     B->stencil.dims[i]   = A->stencil.dims[i];
3272:     B->stencil.starts[i] = A->stencil.starts[i];
3273:   }

3275:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3276:   PetscObjectStateIncrease((PetscObject)B);
3277:   return(0);
3278: }

3282: /*@C  
3283:    MatConvert - Converts a matrix to another matrix, either of the same
3284:    or different type.

3286:    Collective on Mat

3288:    Input Parameters:
3289: +  mat - the matrix
3290: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3291:    same type as the original matrix.
3292: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3293:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3294:    MAT_INITIAL_MATRIX.

3296:    Output Parameter:
3297: .  M - pointer to place new matrix

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

3304:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3305:    the MPI communicator of the generated matrix is always the same as the communicator
3306:    of the input matrix.

3308:    Level: intermediate

3310:    Concepts: matrices^converting between storage formats

3312: .seealso: MatCopy(), MatDuplicate()
3313: @*/
3314: PetscErrorCode  MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3315: {
3316:   PetscErrorCode         ierr;
3317:   PetscTruth             sametype,issame,flg;
3318:   char                   convname[256],mtype[256];
3319:   Mat                    B;

3325:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3326:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3327:   MatPreallocated(mat);

3329:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3330:   if (flg) {
3331:     newtype = mtype;
3332:   }
3333:   PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3334:   PetscStrcmp(newtype,"same",&issame);
3335:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3336:     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3337:   }

3339:   if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3340: 
3341:   if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3342:     (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3343:   } else {
3344:     PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL;
3345:     const char     *prefix[3] = {"seq","mpi",""};
3346:     PetscInt       i;
3347:     /* 
3348:        Order of precedence:
3349:        1) See if a specialized converter is known to the current matrix.
3350:        2) See if a specialized converter is known to the desired matrix class.
3351:        3) See if a good general converter is registered for the desired class
3352:           (as of 6/27/03 only MATMPIADJ falls into this category).
3353:        4) See if a good general converter is known for the current matrix.
3354:        5) Use a really basic converter.
3355:     */
3356: 
3357:     /* 1) See if a specialized converter is known to the current matrix and the desired class */
3358:     for (i=0; i<3; i++) {
3359:       PetscStrcpy(convname,"MatConvert_");
3360:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3361:       PetscStrcat(convname,"_");
3362:       PetscStrcat(convname,prefix[i]);
3363:       PetscStrcat(convname,newtype);
3364:       PetscStrcat(convname,"_C");
3365:       PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3366:       if (conv) goto foundconv;
3367:     }

3369:     /* 2)  See if a specialized converter is known to the desired matrix class. */
3370:     MatCreate(((PetscObject)mat)->comm,&B);
3371:     MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3372:     MatSetType(B,newtype);
3373:     for (i=0; i<3; i++) {
3374:       PetscStrcpy(convname,"MatConvert_");
3375:       PetscStrcat(convname,((PetscObject)mat)->type_name);
3376:       PetscStrcat(convname,"_");
3377:       PetscStrcat(convname,prefix[i]);
3378:       PetscStrcat(convname,newtype);
3379:       PetscStrcat(convname,"_C");
3380:       PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
3381:       if (conv) {
3382:         MatDestroy(B);
3383:         goto foundconv;
3384:       }
3385:     }

3387:     /* 3) See if a good general converter is registered for the desired class */
3388:     conv = B->ops->convertfrom;
3389:     MatDestroy(B);
3390:     if (conv) goto foundconv;

3392:     /* 4) See if a good general converter is known for the current matrix */
3393:     if (mat->ops->convert) {
3394:       conv = mat->ops->convert;
3395:     }
3396:     if (conv) goto foundconv;

3398:     /* 5) Use a really basic converter. */
3399:     conv = MatConvert_Basic;

3401:     foundconv:
3402:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3403:     (*conv)(mat,newtype,reuse,M);
3404:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3405:   }
3406:   PetscObjectStateIncrease((PetscObject)*M);
3407:   return(0);
3408: }

3412: /*@C  
3413:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3415:    Not Collective

3417:    Input Parameter:
3418: .  mat - the matrix, must be a factored matrix

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

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

3427:    Level: intermediate

3429: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3430: @*/
3431: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3432: {
3433:   PetscErrorCode         ierr;
3434:   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);

3439:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3440:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3441:   if (!conv) {
3442:     *type = MAT_SOLVER_PETSC;
3443:   } else {
3444:     (*conv)(mat,type);
3445:   }
3446:   return(0);
3447: }

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

3454:    Collective on Mat

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

3461:    Output Parameters:
3462: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

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

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

3470:    Level: intermediate

3472: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3473: @*/
3474: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3475: {
3476:   PetscErrorCode         ierr;
3477:   char                   convname[256];
3478:   PetscErrorCode         (*conv)(Mat,MatFactorType,Mat*);


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

3487:   PetscStrcpy(convname,"MatGetFactor_");
3488:   PetscStrcat(convname,((PetscObject)mat)->type_name);
3489:   PetscStrcat(convname,"_");
3490:   PetscStrcat(convname,type);
3491:   PetscStrcat(convname,"_C");
3492:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3493:   if (!conv) {
3494:     PetscTruth flag;
3495:     PetscStrcasecmp(MAT_SOLVER_PETSC,type,&flag);
3496:     if (flag) {
3497:       SETERRQ1(PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc direct solver",((PetscObject)mat)->type_name);
3498:     } else {
3499:       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);
3500:     }
3501:   }
3502:   (*conv)(mat,ftype,f);
3503:   return(0);
3504: }

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

3511:    Collective on Mat

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

3518:    Output Parameter:
3519: .    flg - PETSC_TRUE if the factorization is available

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

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

3527:    Level: intermediate

3529: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3530: @*/
3531: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3532: {
3533:   PetscErrorCode         ierr;
3534:   char                   convname[256];
3535:   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscTruth*);


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

3544:   PetscStrcpy(convname,"MatGetFactorAvailable_");
3545:   PetscStrcat(convname,((PetscObject)mat)->type_name);
3546:   PetscStrcat(convname,"_");
3547:   PetscStrcat(convname,type);
3548:   PetscStrcat(convname,"_C");
3549:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3550:   if (!conv) {
3551:     *flg = PETSC_FALSE;
3552:   } else {
3553:     (*conv)(mat,ftype,flg);
3554:   }
3555:   return(0);
3556: }


3561: /*@
3562:    MatDuplicate - Duplicates a matrix including the non-zero structure.

3564:    Collective on Mat

3566:    Input Parameters:
3567: +  mat - the matrix
3568: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3569:         values as well or not

3571:    Output Parameter:
3572: .  M - pointer to place new matrix

3574:    Level: intermediate

3576:    Concepts: matrices^duplicating

3578: .seealso: MatCopy(), MatConvert()
3579: @*/
3580: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3581: {
3583:   Mat            B;
3584:   PetscInt       i;

3590:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3591:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3592:   MatPreallocated(mat);

3594:   *M  = 0;
3595:   if (!mat->ops->duplicate) {
3596:     SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type");
3597:   }
3598:   PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3599:   (*mat->ops->duplicate)(mat,op,M);
3600:   B = *M;
3601:   if (mat->mapping) {
3602:     MatSetLocalToGlobalMapping(B,mat->mapping);
3603:   }
3604:   if (mat->bmapping) {
3605:     MatSetLocalToGlobalMappingBlock(B,mat->bmapping);
3606:   }
3607:   PetscMapCopy(((PetscObject)mat)->comm,mat->rmap,B->rmap);
3608:   PetscMapCopy(((PetscObject)mat)->comm,mat->cmap,B->cmap);
3609: 
3610:   B->stencil.dim = mat->stencil.dim;
3611:   B->stencil.noc = mat->stencil.noc;
3612:   for (i=0; i<=mat->stencil.dim; i++) {
3613:     B->stencil.dims[i]   = mat->stencil.dims[i];
3614:     B->stencil.starts[i] = mat->stencil.starts[i];
3615:   }

3617:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3618:   PetscObjectStateIncrease((PetscObject)B);
3619:   return(0);
3620: }

3624: /*@ 
3625:    MatGetDiagonal - Gets the diagonal of a matrix.

3627:    Collective on Mat and Vec

3629:    Input Parameters:
3630: +  mat - the matrix
3631: -  v - the vector for storing the diagonal

3633:    Output Parameter:
3634: .  v - the diagonal of the matrix

3636:    Level: intermediate

3638:    Concepts: matrices^accessing diagonals

3640: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3641: @*/
3642: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
3643: {

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

3654:   (*mat->ops->getdiagonal)(mat,v);
3655:   PetscObjectStateIncrease((PetscObject)v);
3656:   return(0);
3657: }

3661: /*@ 
3662:    MatGetRowMin - Gets the minimum value (of the real part) of each
3663:         row of the matrix

3665:    Collective on Mat and Vec

3667:    Input Parameters:
3668: .  mat - the matrix

3670:    Output Parameter:
3671: +  v - the vector for storing the maximums
3672: -  idx - the indices of the column found for each row (optional)

3674:    Level: intermediate

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

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

3681:    Concepts: matrices^getting row maximums

3683: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3684:           MatGetRowMax()
3685: @*/
3686: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3687: {

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

3698:   (*mat->ops->getrowmin)(mat,v,idx);
3699:   PetscObjectStateIncrease((PetscObject)v);
3700:   return(0);
3701: }

3705: /*@ 
3706:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3707:         row of the matrix

3709:    Collective on Mat and Vec

3711:    Input Parameters:
3712: .  mat - the matrix

3714:    Output Parameter:
3715: +  v - the vector for storing the minimums
3716: -  idx - the indices of the column found for each row (optional)

3718:    Level: intermediate

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

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

3725:    Concepts: matrices^getting row maximums

3727: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3728: @*/
3729: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3730: {

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

3742:   (*mat->ops->getrowminabs)(mat,v,idx);
3743:   PetscObjectStateIncrease((PetscObject)v);
3744:   return(0);
3745: }

3749: /*@ 
3750:    MatGetRowMax - Gets the maximum value (of the real part) of each
3751:         row of the matrix

3753:    Collective on Mat and Vec

3755:    Input Parameters:
3756: .  mat - the matrix

3758:    Output Parameter:
3759: +  v - the vector for storing the maximums
3760: -  idx - the indices of the column found for each row (optional)

3762:    Level: intermediate

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

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

3769:    Concepts: matrices^getting row maximums

3771: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3772: @*/
3773: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3774: {

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

3785:   (*mat->ops->getrowmax)(mat,v,idx);
3786:   PetscObjectStateIncrease((PetscObject)v);
3787:   return(0);
3788: }

3792: /*@ 
3793:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3794:         row of the matrix

3796:    Collective on Mat and Vec

3798:    Input Parameters:
3799: .  mat - the matrix

3801:    Output Parameter:
3802: +  v - the vector for storing the maximums
3803: -  idx - the indices of the column found for each row (optional)

3805:    Level: intermediate

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

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

3812:    Concepts: matrices^getting row maximums

3814: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3815: @*/
3816: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3817: {

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

3829:   (*mat->ops->getrowmaxabs)(mat,v,idx);
3830:   PetscObjectStateIncrease((PetscObject)v);
3831:   return(0);
3832: }

3836: /*@ 
3837:    MatGetRowSum - Gets the sum of each row of the matrix

3839:    Collective on Mat and Vec

3841:    Input Parameters:
3842: .  mat - the matrix

3844:    Output Parameter:
3845: .  v - the vector for storing the maximums

3847:    Level: intermediate

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

3851:    Concepts: matrices^getting row sums

3853: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3854: @*/
3855: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
3856: {
3857:   PetscInt       start, end, row;
3858:   PetscScalar   *array;

3865:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3866:   MatPreallocated(mat);
3867:   MatGetOwnershipRange(mat, &start, &end);
3868:   VecGetArray(v, &array);
3869:   for(row = start; row < end; ++row) {
3870:     PetscInt           ncols, col;
3871:     const PetscInt    *cols;
3872:     const PetscScalar *vals;

3874:     array[row - start] = 0.0;
3875:     MatGetRow(mat, row, &ncols, &cols, &vals);
3876:     for(col = 0; col < ncols; col++) {
3877:       array[row - start] += vals[col];
3878:     }
3879:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
3880:   }
3881:   VecRestoreArray(v, &array);
3882:   PetscObjectStateIncrease((PetscObject) v);
3883:   return(0);
3884: }

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

3891:    Collective on Mat

3893:    Input Parameter:
3894: +  mat - the matrix to transpose
3895: -  reuse - store the transpose matrix in the provided B

3897:    Output Parameters:
3898: .  B - the transpose 

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

3903:    Level: intermediate

3905:    Concepts: matrices^transposing

3907: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3908: @*/
3909: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3910: {

3916:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3917:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3918:   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3919:   MatPreallocated(mat);

3921:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
3922:   (*mat->ops->transpose)(mat,reuse,B);
3923:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
3924:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
3925:   return(0);
3926: }

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

3934:    Collective on Mat

3936:    Input Parameter:
3937: +  A - the matrix to test
3938: -  B - the matrix to test against, this can equal the first parameter

3940:    Output Parameters:
3941: .  flg - the result

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

3948:    Level: intermediate

3950:    Concepts: matrices^transposing, matrix^symmetry

3952: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3953: @*/
3954: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3955: {
3956:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

3962:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
3963:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
3964:   if (f && g) {
3965:     if (f==g) {
3966:       (*f)(A,B,tol,flg);
3967:     } else {
3968:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3969:     }
3970:   }
3971:   return(0);
3972: }

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

3979:    Collective on Mat

3981:    Input Parameter:
3982: +  A - the matrix to test
3983: -  B - the matrix to test against, this can equal the first parameter

3985:    Output Parameters:
3986: .  flg - the result

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

3993:    Level: intermediate

3995:    Concepts: matrices^transposing, matrix^symmetry

3997: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
3998: @*/
3999: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4000: {
4001:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

4007:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4008:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4009:   if (f && g) {
4010:     if (f==g) {
4011:       (*f)(A,B,tol,flg);
4012:     } else {
4013:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4014:     }
4015:   }
4016:   return(0);
4017: }

4021: /*@
4022:    MatPermute - Creates a new matrix with rows and columns permuted from the 
4023:    original.

4025:    Collective on Mat

4027:    Input Parameters:
4028: +  mat - the matrix to permute
4029: .  row - row permutation, each processor supplies only the permutation for its rows
4030: -  col - column permutation, each processor needs the entire column permutation, that is
4031:          this is the same size as the total number of columns in the matrix

4033:    Output Parameters:
4034: .  B - the permuted matrix

4036:    Level: advanced

4038:    Concepts: matrices^permuting

4040: .seealso: MatGetOrdering()
4041: @*/
4042: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4043: {

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

4057:   (*mat->ops->permute)(mat,row,col,B);
4058:   PetscObjectStateIncrease((PetscObject)*B);
4059:   return(0);
4060: }

4064: /*@
4065:   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the 
4066:   original and sparsified to the prescribed tolerance.

4068:   Collective on Mat

4070:   Input Parameters:
4071: + A    - The matrix to permute
4072: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4073: . frac - The half-bandwidth as a fraction of the total size, or 0.0
4074: . tol  - The drop tolerance
4075: . rowp - The row permutation
4076: - colp - The column permutation

4078:   Output Parameter:
4079: . B    - The permuted, sparsified matrix

4081:   Level: advanced

4083:   Note:
4084:   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4085:   restrict the half-bandwidth of the resulting matrix to 5% of the
4086:   total matrix size.

4088: .keywords: matrix, permute, sparsify

4090: .seealso: MatGetOrdering(), MatPermute()
4091: @*/
4092: PetscErrorCode  MatPermuteSparsify(Mat A, PetscInt band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B)
4093: {
4094:   IS                irowp, icolp;
4095:   const PetscInt    *rows, *cols;
4096:   PetscInt          M, N, locRowStart, locRowEnd;
4097:   PetscInt          nz, newNz;
4098:   const PetscInt    *cwork;
4099:   PetscInt          *cnew;
4100:   const PetscScalar *vwork;
4101:   PetscScalar       *vnew;
4102:   PetscInt          bw, issize;
4103:   PetscInt          row, locRow, newRow, col, newCol;
4104:   PetscErrorCode    ierr;

4111:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
4112:   if (A->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
4113:   if (!A->ops->permutesparsify) {
4114:     MatGetSize(A, &M, &N);
4115:     MatGetOwnershipRange(A, &locRowStart, &locRowEnd);
4116:     ISGetSize(rowp, &issize);
4117:     if (issize != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for row permutation, should be %D", issize, M);
4118:     ISGetSize(colp, &issize);
4119:     if (issize != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %D for column permutation, should be %D", issize, N);
4120:     ISInvertPermutation(rowp, 0, &irowp);
4121:     ISGetIndices(irowp, &rows);
4122:     ISInvertPermutation(colp, 0, &icolp);
4123:     ISGetIndices(icolp, &cols);
4124:     PetscMalloc(N * sizeof(PetscInt),         &cnew);
4125:     PetscMalloc(N * sizeof(PetscScalar), &vnew);

4127:     /* Setup bandwidth to include */
4128:     if (band == PETSC_DECIDE) {
4129:       if (frac <= 0.0)
4130:         bw = (PetscInt) (M * 0.05);
4131:       else
4132:         bw = (PetscInt) (M * frac);
4133:     } else {
4134:       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4135:       bw = band;
4136:     }

4138:     /* Put values into new matrix */
4139:     MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B);
4140:     for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) {
4141:       MatGetRow(A, row, &nz, &cwork, &vwork);
4142:       newRow   = rows[locRow]+locRowStart;
4143:       for(col = 0, newNz = 0; col < nz; col++) {
4144:         newCol = cols[cwork[col]];
4145:         if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) {
4146:           cnew[newNz] = newCol;
4147:           vnew[newNz] = vwork[col];
4148:           newNz++;
4149:         }
4150:       }
4151:       MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES);
4152:       MatRestoreRow(A, row, &nz, &cwork, &vwork);
4153:     }
4154:     PetscFree(cnew);
4155:     PetscFree(vnew);
4156:     MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY);
4157:     MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY);
4158:     ISRestoreIndices(irowp, &rows);
4159:     ISRestoreIndices(icolp, &cols);
4160:     ISDestroy(irowp);
4161:     ISDestroy(icolp);
4162:   } else {
4163:     (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B);
4164:   }
4165:   PetscObjectStateIncrease((PetscObject)*B);
4166:   return(0);
4167: }

4171: /*@
4172:    MatEqual - Compares two matrices.

4174:    Collective on Mat

4176:    Input Parameters:
4177: +  A - the first matrix
4178: -  B - the second matrix

4180:    Output Parameter:
4181: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4183:    Level: intermediate

4185:    Concepts: matrices^equality between
4186: @*/
4187: PetscErrorCode  MatEqual(Mat A,Mat B,PetscTruth *flg)
4188: {

4198:   MatPreallocated(B);
4199:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4200:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4201:   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);
4202:   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4203:   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4204:   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);
4205:   MatPreallocated(A);

4207:   (*A->ops->equal)(A,B,flg);
4208:   return(0);
4209: }

4213: /*@
4214:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4215:    matrices that are stored as vectors.  Either of the two scaling
4216:    matrices can be PETSC_NULL.

4218:    Collective on Mat

4220:    Input Parameters:
4221: +  mat - the matrix to be scaled
4222: .  l - the left scaling vector (or PETSC_NULL)
4223: -  r - the right scaling vector (or PETSC_NULL)

4225:    Notes:
4226:    MatDiagonalScale() computes A = LAR, where
4227:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)

4229:    Level: intermediate

4231:    Concepts: matrices^diagonal scaling
4232:    Concepts: diagonal scaling of matrices

4234: .seealso: MatScale()
4235: @*/
4236: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4237: {

4243:   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4246:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4247:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4248:   MatPreallocated(mat);

4250:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4251:   (*mat->ops->diagonalscale)(mat,l,r);
4252:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4253:   PetscObjectStateIncrease((PetscObject)mat);
4254:   return(0);
4255: }

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

4262:     Collective on Mat

4264:     Input Parameters:
4265: +   mat - the matrix to be scaled
4266: -   a  - the scaling value

4268:     Output Parameter:
4269: .   mat - the scaled matrix

4271:     Level: intermediate

4273:     Concepts: matrices^scaling all entries

4275: .seealso: MatDiagonalScale()
4276: @*/
4277: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4278: {

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

4289:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4290:   if (a != 1.0) {
4291:     (*mat->ops->scale)(mat,a);
4292:     PetscObjectStateIncrease((PetscObject)mat);
4293:   }
4294:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4295:   return(0);
4296: }

4300: /*@ 
4301:    MatNorm - Calculates various norms of a matrix.

4303:    Collective on Mat

4305:    Input Parameters:
4306: +  mat - the matrix
4307: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4309:    Output Parameters:
4310: .  nrm - the resulting norm 

4312:    Level: intermediate

4314:    Concepts: matrices^norm
4315:    Concepts: norm^of matrix
4316: @*/
4317: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4318: {


4326:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4327:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4328:   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4329:   MatPreallocated(mat);

4331:   (*mat->ops->norm)(mat,type,nrm);
4332:   return(0);
4333: }

4335: /* 
4336:      This variable is used to prevent counting of MatAssemblyBegin() that
4337:    are called from within a MatAssemblyEnd().
4338: */
4339: static PetscInt MatAssemblyEnd_InUse = 0;
4342: /*@
4343:    MatAssemblyBegin - Begins assembling the matrix.  This routine should
4344:    be called after completing all calls to MatSetValues().

4346:    Collective on Mat

4348:    Input Parameters:
4349: +  mat - the matrix 
4350: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4351:  
4352:    Notes: 
4353:    MatSetValues() generally caches the values.  The matrix is ready to
4354:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4355:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4356:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4357:    using the matrix.

4359:    Level: beginner

4361:    Concepts: matrices^assembling

4363: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4364: @*/
4365: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4366: {

4372:   MatPreallocated(mat);
4373:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4374:   if (mat->assembled) {
4375:     mat->was_assembled = PETSC_TRUE;
4376:     mat->assembled     = PETSC_FALSE;
4377:   }
4378:   if (!MatAssemblyEnd_InUse) {
4379:     PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4380:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4381:     PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4382:   } else {
4383:     if (mat->ops->assemblybegin){(*mat->ops->assemblybegin)(mat,type);}
4384:   }
4385:   return(0);
4386: }

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

4394:    Collective on Mat

4396:    Input Parameter:
4397: .  mat - the matrix 

4399:    Output Parameter:
4400: .  assembled - PETSC_TRUE or PETSC_FALSE

4402:    Level: advanced

4404:    Concepts: matrices^assembled?

4406: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4407: @*/
4408: PetscErrorCode  MatAssembled(Mat mat,PetscTruth *assembled)
4409: {
4414:   *assembled = mat->assembled;
4415:   return(0);
4416: }

4420: /*
4421:     Processes command line options to determine if/how a matrix
4422:   is to be viewed. Called by MatAssemblyEnd() and MatLoad().
4423: */
4424: PetscErrorCode MatView_Private(Mat mat)
4425: {
4426:   PetscErrorCode    ierr;
4427:   PetscTruth        flg1,flg2,flg3,flg4,flg6,flg7,flg8;
4428:   static PetscTruth incall = PETSC_FALSE;
4429: #if defined(PETSC_USE_SOCKET_VIEWER)
4430:   PetscTruth        flg5;
4431: #endif

4434:   if (incall) return(0);
4435:   incall = PETSC_TRUE;
4436:   PetscOptionsBegin(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,"Matrix Options","Mat");
4437:     PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg1);
4438:     PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg2);
4439:     PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg3);
4440:     PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg4);
4441: #if defined(PETSC_USE_SOCKET_VIEWER)
4442:     PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg5);
4443: #endif
4444:     PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg6);
4445:     PetscOptionsName("-mat_view_draw","Draw the matrix nonzero structure","MatView",&flg7);
4446:   PetscOptionsEnd();

4448:   if (flg1) {
4449:     PetscViewer viewer;

4451:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4452:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4453:     MatView(mat,viewer);
4454:     PetscViewerPopFormat(viewer);
4455:   }
4456:   if (flg2) {
4457:     PetscViewer viewer;

4459:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4460:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4461:     MatView(mat,viewer);
4462:     PetscViewerPopFormat(viewer);
4463:   }
4464:   if (flg3) {
4465:     PetscViewer viewer;

4467:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4468:     MatView(mat,viewer);
4469:   }
4470:   if (flg4) {
4471:     PetscViewer viewer;

4473:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4474:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);
4475:     MatView(mat,viewer);
4476:     PetscViewerPopFormat(viewer);
4477:   }
4478: #if defined(PETSC_USE_SOCKET_VIEWER)
4479:   if (flg5) {
4480:     MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4481:     PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));
4482:   }
4483: #endif
4484:   if (flg6) {
4485:     MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4486:     PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));
4487:   }
4488:   if (flg7) {
4489:     PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8);
4490:     if (flg8) {
4491:       PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);
4492:     }
4493:     MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4494:     PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4495:     if (flg8) {
4496:       PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));
4497:     }
4498:   }
4499:   incall = PETSC_FALSE;
4500:   return(0);
4501: }

4505: /*@
4506:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4507:    be called after MatAssemblyBegin().

4509:    Collective on Mat

4511:    Input Parameters:
4512: +  mat - the matrix 
4513: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

4515:    Options Database Keys:
4516: +  -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly()
4517: .  -mat_view_info_detailed - Prints more detailed info
4518: .  -mat_view - Prints matrix in ASCII format
4519: .  -mat_view_matlab - Prints matrix in Matlab format
4520: .  -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4521: .  -display <name> - Sets display name (default is host)
4522: .  -draw_pause <sec> - Sets number of seconds to pause after display
4523: .  -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual)
4524: .  -viewer_socket_machine <machine>
4525: .  -viewer_socket_port <port>
4526: .  -mat_view_binary - save matrix to file in binary format
4527: -  -viewer_binary_filename <name>

4529:    Notes: 
4530:    MatSetValues() generally caches the values.  The matrix is ready to
4531:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4532:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4533:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4534:    using the matrix.

4536:    Level: beginner

4538: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4539: @*/
4540: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4541: {
4542:   PetscErrorCode  ierr;
4543:   static PetscInt inassm = 0;
4544:   PetscTruth      flg;


4550:   inassm++;
4551:   MatAssemblyEnd_InUse++;
4552:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4553:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4554:     if (mat->ops->assemblyend) {
4555:       (*mat->ops->assemblyend)(mat,type);
4556:     }
4557:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4558:   } else {
4559:     if (mat->ops->assemblyend) {
4560:       (*mat->ops->assemblyend)(mat,type);
4561:     }
4562:   }

4564:   /* Flush assembly is not a true assembly */
4565:   if (type != MAT_FLUSH_ASSEMBLY) {
4566:     mat->assembled  = PETSC_TRUE; mat->num_ass++;
4567:   }
4568:   mat->insertmode = NOT_SET_VALUES;
4569:   MatAssemblyEnd_InUse--;
4570:   PetscObjectStateIncrease((PetscObject)mat);
4571:   if (!mat->symmetric_eternal) {
4572:     mat->symmetric_set              = PETSC_FALSE;
4573:     mat->hermitian_set              = PETSC_FALSE;
4574:     mat->structurally_symmetric_set = PETSC_FALSE;
4575:   }
4576:   if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4577:     MatView_Private(mat);
4578:     PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);
4579:     if (flg) {
4580:       PetscReal tol = 0.0;
4581:       PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);
4582:       MatIsSymmetric(mat,tol,&flg);
4583:       if (flg) {
4584:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);
4585:       } else {
4586:         PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);
4587:       }
4588:     }
4589:   }
4590:   inassm--;
4591:   return(0);
4592: }


4597: /*@
4598:    MatCompress - Tries to store the matrix in as little space as 
4599:    possible.  May fail if memory is already fully used, since it
4600:    tries to allocate new space.

4602:    Collective on Mat

4604:    Input Parameters:
4605: .  mat - the matrix 

4607:    Level: advanced

4609: @*/
4610: PetscErrorCode  MatCompress(Mat mat)
4611: {

4617:   MatPreallocated(mat);
4618:   if (mat->ops->compress) {(*mat->ops->compress)(mat);}
4619:   return(0);
4620: }

4624: /*@
4625:    MatSetOption - Sets a parameter option for a matrix. Some options
4626:    may be specific to certain storage formats.  Some options
4627:    determine how values will be inserted (or added). Sorted, 
4628:    row-oriented input will generally assemble the fastest. The default
4629:    is row-oriented, nonsorted input. 

4631:    Collective on Mat

4633:    Input Parameters:
4634: +  mat - the matrix 
4635: .  option - the option, one of those listed below (and possibly others),
4636: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

4638:   Options Describing Matrix Structure:
4639: +    MAT_SYMMETRIC - symmetric in terms of both structure and value
4640: .    MAT_HERMITIAN - transpose is the complex conjugation
4641: .    MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
4642: -    MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
4643:                             you set to be kept with all future use of the matrix
4644:                             including after MatAssemblyBegin/End() which could
4645:                             potentially change the symmetry structure, i.e. you 
4646:                             KNOW the matrix will ALWAYS have the property you set.


4649:    Options For Use with MatSetValues():
4650:    Insert a logically dense subblock, which can be
4651: .    MAT_ROW_ORIENTED - row-oriented (default)

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

4657:    When (re)assembling a matrix, we can restrict the input for
4658:    efficiency/debugging purposes.  These options include
4659: +    MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
4660:         allowed if they generate a new nonzero
4661: .    MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
4662: .    MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
4663: .    MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
4664: -    MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly

4666:    Notes:
4667:    Some options are relevant only for particular matrix types and
4668:    are thus ignored by others.  Other options are not supported by
4669:    certain matrix types and will generate an error message if set.

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

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

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

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

4694:    MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 
4695:    other processors should be dropped, rather than stashed.
4696:    This is useful if you know that the "owning" processor is also 
4697:    always generating the correct matrix entries, so that PETSc need
4698:    not transfer duplicate entries generated on another processor.
4699:    
4700:    MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
4701:    searches during matrix assembly. When this flag is set, the hash table
4702:    is created during the first Matrix Assembly. This hash table is
4703:    used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
4704:    to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 
4705:    should be used with MAT_USE_HASH_TABLE flag. This option is currently
4706:    supported by MATMPIBAIJ format only.

4708:    MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries
4709:    are kept in the nonzero structure

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

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

4717:    Level: intermediate

4719:    Concepts: matrices^setting options

4721: @*/
4722: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4723: {

4729:   if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op);
4730:   MatPreallocated(mat);
4731:   switch (op) {
4732:   case MAT_SYMMETRIC:
4733:     mat->symmetric                  = flg;
4734:     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4735:     mat->symmetric_set              = PETSC_TRUE;
4736:     mat->structurally_symmetric_set = flg;
4737:     break;
4738:   case MAT_HERMITIAN:
4739:     mat->hermitian                  = flg;
4740:     if (flg) mat->structurally_symmetric     = PETSC_TRUE;
4741:     mat->hermitian_set              = PETSC_TRUE;
4742:     mat->structurally_symmetric_set = flg;
4743:     break;
4744:   case MAT_STRUCTURALLY_SYMMETRIC:
4745:     mat->structurally_symmetric     = flg;
4746:     mat->structurally_symmetric_set = PETSC_TRUE;
4747:     break;
4748:   case MAT_SYMMETRY_ETERNAL:
4749:     mat->symmetric_eternal          = flg;
4750:     break;
4751:   default:
4752:     break;
4753:   }
4754:   if (mat->ops->setoption) {
4755:     (*mat->ops->setoption)(mat,op,flg);
4756:   }
4757:   return(0);
4758: }

4762: /*@
4763:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4764:    this routine retains the old nonzero structure.

4766:    Collective on Mat

4768:    Input Parameters:
4769: .  mat - the matrix 

4771:    Level: intermediate

4773:    Concepts: matrices^zeroing

4775: .seealso: MatZeroRows()
4776: @*/
4777: PetscErrorCode  MatZeroEntries(Mat mat)
4778: {

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

4789:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
4790:   (*mat->ops->zeroentries)(mat);
4791:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
4792:   PetscObjectStateIncrease((PetscObject)mat);
4793:   return(0);
4794: }

4798: /*@C
4799:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4800:    of a set of rows of a matrix.

4802:    Collective on Mat

4804:    Input Parameters:
4805: +  mat - the matrix
4806: .  numRows - the number of rows to remove
4807: .  rows - the global row indices
4808: -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)

4810:    Notes:
4811:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4812:    but does not release memory.  For the dense and block diagonal
4813:    formats this does not alter the nonzero structure.

4815:    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4816:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4817:    merely zeroed.

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

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

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

4831:    Level: intermediate

4833:    Concepts: matrices^zeroing rows

4835: .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4836: @*/
4837: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4838: {

4845:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4846:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4847:   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4848:   MatPreallocated(mat);

4850:   (*mat->ops->zerorows)(mat,numRows,rows,diag);
4851:   MatView_Private(mat);
4852:   PetscObjectStateIncrease((PetscObject)mat);
4853:   return(0);
4854: }

4858: /*@C
4859:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4860:    of a set of rows of a matrix.

4862:    Collective on Mat

4864:    Input Parameters:
4865: +  mat - the matrix
4866: .  is - index set of rows to remove
4867: -  diag - value put in all diagonals of eliminated rows

4869:    Notes:
4870:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4871:    but does not release memory.  For the dense and block diagonal
4872:    formats this does not alter the nonzero structure.

4874:    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4875:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4876:    merely zeroed.

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

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

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

4889:    Level: intermediate

4891:    Concepts: matrices^zeroing rows

4893: .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4894: @*/
4895: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4896: {
4897:   PetscInt       numRows;
4898:   const PetscInt *rows;

4905:   ISGetLocalSize(is,&numRows);
4906:   ISGetIndices(is,&rows);
4907:   MatZeroRows(mat,numRows,rows,diag);
4908:   ISRestoreIndices(is,&rows);
4909:   return(0);
4910: }

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

4918:    Collective on Mat

4920:    Input Parameters:
4921: +  mat - the matrix
4922: .  numRows - the number of rows to remove
4923: .  rows - the global row indices
4924: -  diag - value put in all diagonals of eliminated rows

4926:    Notes:
4927:    Before calling MatZeroRowsLocal(), the user must first set the
4928:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

4930:    For the AIJ matrix formats this removes the old nonzero structure,
4931:    but does not release memory.  For the dense and block diagonal
4932:    formats this does not alter the nonzero structure.

4934:    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
4935:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
4936:    merely zeroed.

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

4942:    Level: intermediate

4944:    Concepts: matrices^zeroing

4946: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4947: @*/
4948: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4949: {

4956:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4957:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4958:   MatPreallocated(mat);

4960:   if (mat->ops->zerorowslocal) {
4961:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);
4962:   } else {
4963:     IS             is, newis;
4964:     const PetscInt *newRows;

4966:     if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
4967:     ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,&is);
4968:     ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);
4969:     ISGetIndices(newis,&newRows);
4970:     (*mat->ops->zerorows)(mat,numRows,newRows,diag);
4971:     ISRestoreIndices(newis,&newRows);
4972:     ISDestroy(newis);
4973:     ISDestroy(is);
4974:   }
4975:   PetscObjectStateIncrease((PetscObject)mat);
4976:   return(0);
4977: }

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

4985:    Collective on Mat

4987:    Input Parameters:
4988: +  mat - the matrix
4989: .  is - index set of rows to remove
4990: -  diag - value put in all diagonals of eliminated rows

4992:    Notes:
4993:    Before calling MatZeroRowsLocalIS(), the user must first set the
4994:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

4996:    For the AIJ matrix formats this removes the old nonzero structure,
4997:    but does not release memory.  For the dense and block diagonal
4998:    formats this does not alter the nonzero structure.

5000:    If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS,PETSC_TRUE) the nonzero structure
5001:    of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5002:    merely zeroed.

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

5008:    Level: intermediate

5010:    Concepts: matrices^zeroing

5012: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5013: @*/
5014: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5015: {
5017:   PetscInt       numRows;
5018:   const PetscInt *rows;

5024:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5025:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5026:   MatPreallocated(mat);

5028:   ISGetLocalSize(is,&numRows);
5029:   ISGetIndices(is,&rows);
5030:   MatZeroRowsLocal(mat,numRows,rows,diag);
5031:   ISRestoreIndices(is,&rows);
5032:   return(0);
5033: }

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

5040:    Not Collective

5042:    Input Parameter:
5043: .  mat - the matrix

5045:    Output Parameters:
5046: +  m - the number of global rows
5047: -  n - the number of global columns

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

5051:    Level: beginner

5053:    Concepts: matrices^size

5055: .seealso: MatGetLocalSize()
5056: @*/
5057: PetscErrorCode  MatGetSize(Mat mat,PetscInt *m,PetscInt* n)
5058: {
5061:   if (m) *m = mat->rmap->N;
5062:   if (n) *n = mat->cmap->N;
5063:   return(0);
5064: }

5068: /*@
5069:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5070:    stored locally.  This information may be implementation dependent, so
5071:    use with care.

5073:    Not Collective

5075:    Input Parameters:
5076: .  mat - the matrix

5078:    Output Parameters:
5079: +  m - the number of local rows
5080: -  n - the number of local columns

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

5084:    Level: beginner

5086:    Concepts: matrices^local size

5088: .seealso: MatGetSize()
5089: @*/
5090: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5091: {
5096:   if (m) *m = mat->rmap->n;
5097:   if (n) *n = mat->cmap->n;
5098:   return(0);
5099: }

5103: /*@
5104:    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5105:    this processor.

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

5109:    Input Parameters:
5110: .  mat - the matrix

5112:    Output Parameters:
5113: +  m - the global index of the first local column
5114: -  n - one more than the global index of the last local column

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

5118:    Level: developer

5120:    Concepts: matrices^column ownership

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

5124: @*/
5125: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5126: {

5134:   MatPreallocated(mat);
5135:   if (m) *m = mat->cmap->rstart;
5136:   if (n) *n = mat->cmap->rend;
5137:   return(0);
5138: }

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

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

5150:    Input Parameters:
5151: .  mat - the matrix

5153:    Output Parameters:
5154: +  m - the global index of the first local row
5155: -  n - one more than the global index of the last local row

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

5159:    Level: beginner

5161:    Concepts: matrices^row ownership

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

5165: @*/
5166: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5167: {

5175:   MatPreallocated(mat);
5176:   if (m) *m = mat->rmap->rstart;
5177:   if (n) *n = mat->rmap->rend;
5178:   return(0);
5179: }

5183: /*@C
5184:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5185:    each process

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

5189:    Input Parameters:
5190: .  mat - the matrix

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

5195:    Level: beginner

5197:    Concepts: matrices^row ownership

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

5201: @*/
5202: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5203: {

5209:   MatPreallocated(mat);
5210:   PetscMapGetRanges(mat->rmap,ranges);
5211:   return(0);
5212: }

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

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

5221:    Input Parameters:
5222: .  mat - the matrix

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

5227:    Level: beginner

5229:    Concepts: matrices^column ownership

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

5233: @*/
5234: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5235: {

5241:   MatPreallocated(mat);
5242:   PetscMapGetRanges(mat->cmap,ranges);
5243:   return(0);
5244: }

5248: /*@C
5249:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5250:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
5251:    to complete the factorization.

5253:    Collective on Mat

5255:    Input Parameters:
5256: +  mat - the matrix
5257: .  row - row permutation
5258: .  column - column permutation
5259: -  info - structure containing 
5260: $      levels - number of levels of fill.
5261: $      expected fill - as ratio of original fill.
5262: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5263:                 missing diagonal entries)

5265:    Output Parameters:
5266: .  fact - new matrix that has been symbolically factored

5268:    Notes:
5269:    See the users manual for additional information about
5270:    choosing the fill factor for better efficiency.

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

5276:    Level: developer

5278:   Concepts: matrices^symbolic LU factorization
5279:   Concepts: matrices^factorization
5280:   Concepts: LU^symbolic factorization

5282: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5283:           MatGetOrdering(), MatFactorInfo

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

5288: @*/
5289: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5290: {

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

5307:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
5308:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
5309:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
5310:   return(0);
5311: }

5315: /*@C
5316:    MatICCFactorSymbolic - Performs symbolic incomplete
5317:    Cholesky factorization for a symmetric matrix.  Use 
5318:    MatCholeskyFactorNumeric() to complete the factorization.

5320:    Collective on Mat

5322:    Input Parameters:
5323: +  mat - the matrix
5324: .  perm - row and column permutation
5325: -  info - structure containing 
5326: $      levels - number of levels of fill.
5327: $      expected fill - as ratio of original fill.

5329:    Output Parameter:
5330: .  fact - the factored matrix

5332:    Notes:
5333:    Most users should employ the KSP interface for linear solvers
5334:    instead of working directly with matrix algebra routines such as this.
5335:    See, e.g., KSPCreate().

5337:    Level: developer

5339:   Concepts: matrices^symbolic incomplete Cholesky factorization
5340:   Concepts: matrices^factorization
5341:   Concepts: Cholsky^symbolic factorization

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

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

5348: @*/
5349: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5350: {

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

5366:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
5367:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
5368:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
5369:   return(0);
5370: }

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

5380:    Not Collective

5382:    Input Parameter:
5383: .  mat - the matrix

5385:    Output Parameter:
5386: .  v - the location of the values


5389:    Fortran Note:
5390:    This routine is used differently from Fortran, e.g.,
5391: .vb
5392:         Mat         mat
5393:         PetscScalar mat_array(1)
5394:         PetscOffset i_mat
5395:         PetscErrorCode ierr
5396:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5402:         [... other code ...]
5403:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5404: .ve

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

5409:    Level: advanced

5411:    Concepts: matrices^access array

5413: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5414: @*/
5415: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
5416: {

5423:   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5424:   MatPreallocated(mat);
5425:   (*mat->ops->getarray)(mat,v);
5426:   CHKMEMQ;
5427:   return(0);
5428: }

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

5435:    Not Collective

5437:    Input Parameter:
5438: +  mat - the matrix
5439: -  v - the location of the values

5441:    Fortran Note:
5442:    This routine is used differently from Fortran, e.g.,
5443: .vb
5444:         Mat         mat
5445:         PetscScalar mat_array(1)
5446:         PetscOffset i_mat
5447:         PetscErrorCode ierr
5448:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5454:         [... other code ...]
5455:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5456: .ve

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

5461:    Level: advanced

5463: .seealso: MatGetArray(), MatRestoreArrayF90()
5464: @*/
5465: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
5466: {

5473: #if defined(PETSC_USE_DEBUG)
5474:   CHKMEMQ;
5475: #endif
5476:   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5477:   (*mat->ops->restorearray)(mat,v);
5478:   PetscObjectStateIncrease((PetscObject)mat);
5479:   return(0);
5480: }

5484: /*@C
5485:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5486:    points to an array of valid matrices, they may be reused to store the new
5487:    submatrices.

5489:    Collective on Mat

5491:    Input Parameters:
5492: +  mat - the matrix
5493: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5494: .  irow, icol - index sets of rows and columns to extract
5495: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

5497:    Output Parameter:
5498: .  submat - the array of submatrices

5500:    Notes:
5501:    MatGetSubMatrices() can extract ONLY sequential submatrices
5502:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5503:    to extract a parallel submatrix.

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

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

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

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

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

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

5527:    Level: advanced

5529:    Concepts: matrices^accessing submatrices
5530:    Concepts: submatrices

5532: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5533: @*/
5534: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5535: {
5537:   PetscInt        i;
5538:   PetscTruth      eq;

5543:   if (n) {
5548:   }
5550:   if (n && scall == MAT_REUSE_MATRIX) {
5553:   }
5554:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5555:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5556:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5557:   MatPreallocated(mat);

5559:   PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
5560:   (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
5561:   PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
5562:   for (i=0; i<n; i++) {
5563:     if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
5564:       ISEqual(irow[i],icol[i],&eq);
5565:       if (eq) {
5566:         if (mat->symmetric){
5567:           MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
5568:         } else if (mat->hermitian) {
5569:           MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
5570:         } else if (mat->structurally_symmetric) {
5571:           MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
5572:         }
5573:       }
5574:     }
5575:   }
5576:   return(0);
5577: }

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

5584:    Collective on Mat

5586:    Input Parameters:
5587: +  n - the number of local matrices
5588: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5589:                        sequence of MatGetSubMatrices())

5591:    Level: advanced

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

5596: .seealso: MatGetSubMatrices()
5597: @*/
5598: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
5599: {
5601:   PetscInt       i;

5604:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5606:   for (i=0; i<n; i++) {
5607:     MatDestroy((*mat)[i]);
5608:   }
5609:   /* memory is allocated even if n = 0 */
5610:   PetscFree(*mat);
5611:   return(0);
5612: }

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

5619:    Collective on Mat

5621:    Input Parameters:
5622: .  mat - the matrix

5624:    Output Parameter:
5625: .  matstruct - the sequential matrix with the nonzero structure of mat

5627:   Level: intermediate

5629: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5630: @*/
5631: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5632: {

5638: 
5640:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5641:   MatPreallocated(mat);

5643:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5644:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5645:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5646:   return(0);
5647: }

5651: /*@C
5652:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

5654:    Collective on Mat

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

5660:    Level: advanced

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

5664: .seealso: MatGetSeqNonzeroStructure()
5665: @*/
5666: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat[])
5667: {

5672:   MatDestroyMatrices(1,mat);
5673:   return(0);
5674: }

5678: /*@
5679:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5680:    replaces the index sets by larger ones that represent submatrices with
5681:    additional overlap.

5683:    Collective on Mat

5685:    Input Parameters:
5686: +  mat - the matrix
5687: .  n   - the number of index sets
5688: .  is  - the array of index sets (these index sets will changed during the call)
5689: -  ov  - the additional overlap requested

5691:    Level: developer

5693:    Concepts: overlap
5694:    Concepts: ASM^computing overlap

5696: .seealso: MatGetSubMatrices()
5697: @*/
5698: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5699: {

5705:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
5706:   if (n) {
5709:   }
5710:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5711:   if (mat->factor)     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5712:   MatPreallocated(mat);

5714:   if (!ov) return(0);
5715:   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5716:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5717:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
5718:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5719:   return(0);
5720: }

5724: /*@
5725:    MatGetBlockSize - Returns the matrix block size; useful especially for the
5726:    block row and block diagonal formats.
5727:    
5728:    Not Collective

5730:    Input Parameter:
5731: .  mat - the matrix

5733:    Output Parameter:
5734: .  bs - block size

5736:    Notes:
5737:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

5739:    Level: intermediate

5741:    Concepts: matrices^block size

5743: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5744: @*/
5745: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
5746: {

5753:   MatPreallocated(mat);
5754:   *bs = mat->rmap->bs;
5755:   return(0);
5756: }

5760: /*@
5761:    MatSetBlockSize - Sets the matrix block size; for many matrix types you 
5762:      cannot use this and MUST set the blocksize when you preallocate the matrix
5763:    
5764:    Collective on Mat

5766:    Input Parameters:
5767: +  mat - the matrix
5768: -  bs - block size

5770:    Notes:
5771:      Only works for shell and AIJ matrices

5773:    Level: intermediate

5775:    Concepts: matrices^block size

5777: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5778: @*/
5779: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
5780: {

5786:   MatPreallocated(mat);
5787:   if (mat->ops->setblocksize) {
5788:     /* XXX should check if (bs < 1) ??? */
5789:     PetscMapSetBlockSize(mat->rmap,bs);
5790:     PetscMapSetBlockSize(mat->cmap,bs);
5791:     (*mat->ops->setblocksize)(mat,bs);
5792:   } else {
5793:     SETERRQ1(PETSC_ERR_ARG_INCOMP,"Cannot set the blocksize for matrix type %s",((PetscObject)mat)->type_name);
5794:   }
5795:   return(0);
5796: }

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

5803:    Collective on Mat

5805:     Input Parameters:
5806: +   mat - the matrix
5807: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5808: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5809:                 symmetrized
5810: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5811:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5812:                  nonzero structure which is different than the full nonzero structure]

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

5821:     Level: developer

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

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

5827:     Fortran Node

5829:            In Fortran use
5830: $           PetscInt ia(1), ja(1)
5831: $           PetscOffset iia, jja
5832: $      call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5833:  
5834:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

5836: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5837: @*/
5838: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5839: {

5849:   MatPreallocated(mat);
5850:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5851:   else {
5852:     *done = PETSC_TRUE;
5853:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
5854:     (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5855:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
5856:   }
5857:   return(0);
5858: }

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

5865:     Collective on Mat

5867:     Input Parameters:
5868: +   mat - the matrix
5869: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5870: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5871:                 symmetrized
5872: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5873:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5874:                  nonzero structure which is different than the full nonzero structure]

5876:     Output Parameters:
5877: +   n - number of columns in the (possibly compressed) matrix
5878: .   ia - the column pointers
5879: .   ja - the row indices
5880: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

5882:     Level: developer

5884: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5885: @*/
5886: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5887: {

5897:   MatPreallocated(mat);
5898:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5899:   else {
5900:     *done = PETSC_TRUE;
5901:     (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5902:   }
5903:   return(0);
5904: }

5908: /*@C
5909:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5910:     MatGetRowIJ().

5912:     Collective on Mat

5914:     Input Parameters:
5915: +   mat - the matrix
5916: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5917: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5918:                 symmetrized
5919: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5920:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5921:                  nonzero structure which is different than the full nonzero structure]

5923:     Output Parameters:
5924: +   n - size of (possibly compressed) matrix
5925: .   ia - the row pointers
5926: .   ja - the column indices
5927: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

5929:     Level: developer

5931: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5932: @*/
5933: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5934: {

5943:   MatPreallocated(mat);

5945:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5946:   else {
5947:     *done = PETSC_TRUE;
5948:     (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5949:   }
5950:   return(0);
5951: }

5955: /*@C
5956:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5957:     MatGetColumnIJ().

5959:     Collective on Mat

5961:     Input Parameters:
5962: +   mat - the matrix
5963: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5964: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5965:                 symmetrized
5966: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5967:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5968:                  nonzero structure which is different than the full nonzero structure]

5970:     Output Parameters:
5971: +   n - size of (possibly compressed) matrix
5972: .   ia - the column pointers
5973: .   ja - the row indices
5974: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

5976:     Level: developer

5978: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5979: @*/
5980: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5981: {

5990:   MatPreallocated(mat);

5992:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5993:   else {
5994:     *done = PETSC_TRUE;
5995:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5996:   }
5997:   return(0);
5998: }

6002: /*@C
6003:     MatColoringPatch -Used inside matrix coloring routines that 
6004:     use MatGetRowIJ() and/or MatGetColumnIJ().

6006:     Collective on Mat

6008:     Input Parameters:
6009: +   mat - the matrix
6010: .   ncolors - max color value
6011: .   n   - number of entries in colorarray
6012: -   colorarray - array indicating color for each column

6014:     Output Parameters:
6015: .   iscoloring - coloring generated using colorarray information

6017:     Level: developer

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

6021: @*/
6022: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6023: {

6031:   MatPreallocated(mat);

6033:   if (!mat->ops->coloringpatch){
6034:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6035:   } else {
6036:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6037:   }
6038:   return(0);
6039: }


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

6047:    Collective on Mat

6049:    Input Parameter:
6050: .  mat - the factored matrix to be reset

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

6059:    Note that one can specify in-place ILU(0) factorization by calling 
6060: .vb
6061:      PCType(pc,PCILU);
6062:      PCFactorSeUseInPlace(pc);
6063: .ve
6064:    or by using the options -pc_type ilu -pc_factor_in_place

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

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

6076:    Level: developer

6078: .seealso: PCFactorSetUseInPlace()

6080:    Concepts: matrices^unfactored

6082: @*/
6083: PetscErrorCode  MatSetUnfactored(Mat mat)
6084: {

6090:   MatPreallocated(mat);
6091:   mat->factor = MAT_FACTOR_NONE;
6092:   if (!mat->ops->setunfactored) return(0);
6093:   (*mat->ops->setunfactored)(mat);
6094:   return(0);
6095: }

6097: /*MC
6098:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

6100:     Synopsis:
6101:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6103:     Not collective

6105:     Input Parameter:
6106: .   x - matrix

6108:     Output Parameters:
6109: +   xx_v - the Fortran90 pointer to the array
6110: -   ierr - error code

6112:     Example of Usage: 
6113: .vb
6114:       PetscScalar, pointer xx_v(:)
6115:       ....
6116:       call MatGetArrayF90(x,xx_v,ierr)
6117:       a = xx_v(3)
6118:       call MatRestoreArrayF90(x,xx_v,ierr)
6119: .ve

6121:     Notes:
6122:     Not yet supported for all F90 compilers

6124:     Level: advanced

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

6128:     Concepts: matrices^accessing array

6130: M*/

6132: /*MC
6133:     MatRestoreArrayF90 - Restores a matrix array that has been
6134:     accessed with MatGetArrayF90().

6136:     Synopsis:
6137:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6139:     Not collective

6141:     Input Parameters:
6142: +   x - matrix
6143: -   xx_v - the Fortran90 pointer to the array

6145:     Output Parameter:
6146: .   ierr - error code

6148:     Example of Usage: 
6149: .vb
6150:        PetscScalar, pointer xx_v(:)
6151:        ....
6152:        call MatGetArrayF90(x,xx_v,ierr)
6153:        a = xx_v(3)
6154:        call MatRestoreArrayF90(x,xx_v,ierr)
6155: .ve
6156:    
6157:     Notes:
6158:     Not yet supported for all F90 compilers

6160:     Level: advanced

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

6164: M*/


6169: /*@
6170:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6171:                       as the original matrix.

6173:     Collective on Mat

6175:     Input Parameters:
6176: +   mat - the original matrix
6177: .   isrow - rows this processor should obtain
6178: .   iscol - columns for all processors you wish to keep
6179: .   csize - number of columns "local" to this processor (does nothing for sequential 
6180:             matrices). This should match the result from VecGetLocalSize(x,...) if you 
6181:             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6182: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6184:     Output Parameter:
6185: .   newmat - the new submatrix, of the same type as the old

6187:     Level: advanced

6189:     Notes: the iscol argument MUST be the same on each processor. You might be 
6190:     able to create the iscol argument with ISAllGather(). The rows is isrow will be
6191:     sorted into the same order as the original matrix.

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

6199:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6200:     the input matrix.

6202:     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
6203:     use csize = PETSC_DECIDE also in this case.

6205:     Concepts: matrices^submatrices

6207: .seealso: MatGetSubMatrices(), ISAllGather()
6208: @*/
6209: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
6210: {
6212:   PetscMPIInt    size;
6213:   Mat            *local;
6214:   IS             iscoltmp;

6223:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6224:   MatPreallocated(mat);
6225:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

6227:   if (!iscol) {
6228:     if (csize == PETSC_DECIDE) csize = mat->cmap->n;
6229:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->N,0,1,&iscoltmp);
6230:   } else {
6231:     iscoltmp = iscol;
6232:   }

6234:   /* if original matrix is on just one processor then use submatrix generated */
6235:   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6236:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6237:     if (!iscol) {ISDestroy(iscoltmp);}
6238:     return(0);
6239:   } else if (!mat->ops->getsubmatrix && size == 1) {
6240:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6241:     *newmat = *local;
6242:     PetscFree(local);
6243:     if (!iscol) {ISDestroy(iscoltmp);}
6244:     return(0);
6245:   }

6247:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6248:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);
6249:   if (!iscol) {ISDestroy(iscoltmp);}
6250:   PetscObjectStateIncrease((PetscObject)*newmat);
6251:   return(0);
6252: }

6256: /*@
6257:     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6258:                          as the original matrix.

6260:     Collective on Mat

6262:     Input Parameters:
6263: +   mat - the original matrix
6264: .   nrows - the number of rows this processor should obtain
6265: .   rows - rows this processor should obtain
6266: .   ncols - the number of columns for all processors you wish to keep
6267: .   cols - columns for all processors you wish to keep
6268: .   csize - number of columns "local" to this processor (does nothing for sequential 
6269:             matrices). This should match the result from VecGetLocalSize(x,...) if you 
6270:             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6271: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6273:     Output Parameter:
6274: .   newmat - the new submatrix, of the same type as the old

6276:     Level: advanced

6278:     Notes: the iscol argument MUST be the same on each processor. You might be 
6279:     able to create the iscol argument with ISAllGather().

6281:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6282:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6283:    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX  
6284:    will reuse the matrix generated the first time.

6286:     Concepts: matrices^submatrices

6288: .seealso: MatGetSubMatrices(), ISAllGather()
6289: @*/
6290: PetscErrorCode  MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6291: {
6292:   IS             isrow, iscol;

6302:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6303:   MatPreallocated(mat);
6304:   ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);
6305:   ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);
6306:   MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);
6307:   ISDestroy(isrow);
6308:   ISDestroy(iscol);
6309:   return(0);
6310: }

6314: /*@
6315:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6316:    used during the assembly process to store values that belong to 
6317:    other processors.

6319:    Not Collective

6321:    Input Parameters:
6322: +  mat   - the matrix
6323: .  size  - the initial size of the stash.
6324: -  bsize - the initial size of the block-stash(if used).

6326:    Options Database Keys:
6327: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6328: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

6330:    Level: intermediate

6332:    Notes: 
6333:      The block-stash is used for values set with MatSetValuesBlocked() while
6334:      the stash is used for values set with MatSetValues()

6336:      Run with the option -info and look for output of the form
6337:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6338:      to determine the appropriate value, MM, to use for size and 
6339:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6340:      to determine the value, BMM to use for bsize

6342:    Concepts: stash^setting matrix size
6343:    Concepts: matrices^stash

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

6347: @*/
6348: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6349: {

6355:   MatStashSetInitialSize_Private(&mat->stash,size);
6356:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
6357:   return(0);
6358: }

6362: /*@
6363:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
6364:      the matrix

6366:    Collective on Mat

6368:    Input Parameters:
6369: +  mat   - the matrix
6370: .  x,y - the vectors
6371: -  w - where the result is stored

6373:    Level: intermediate

6375:    Notes: 
6376:     w may be the same vector as y. 

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

6381:     Concepts: interpolation

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

6385: @*/
6386: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6387: {
6389:   PetscInt       M,N;

6397:   MatPreallocated(A);
6398:   MatGetSize(A,&M,&N);
6399:   if (N > M) {
6400:     MatMultTransposeAdd(A,x,y,w);
6401:   } else {
6402:     MatMultAdd(A,x,y,w);
6403:   }
6404:   return(0);
6405: }

6409: /*@
6410:    MatInterpolate - y = A*x or A'*x depending on the shape of 
6411:      the matrix

6413:    Collective on Mat

6415:    Input Parameters:
6416: +  mat   - the matrix
6417: -  x,y - the vectors

6419:    Level: intermediate

6421:    Notes: 
6422:     This allows one to use either the restriction or interpolation (its transpose)
6423:     matrix to do the interpolation

6425:    Concepts: matrices^interpolation

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

6429: @*/
6430: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
6431: {
6433:   PetscInt       M,N;

6440:   MatPreallocated(A);
6441:   MatGetSize(A,&M,&N);
6442:   if (N > M) {
6443:     MatMultTranspose(A,x,y);
6444:   } else {
6445:     MatMult(A,x,y);
6446:   }
6447:   return(0);
6448: }

6452: /*@
6453:    MatRestrict - y = A*x or A'*x

6455:    Collective on Mat

6457:    Input Parameters:
6458: +  mat   - the matrix
6459: -  x,y - the vectors

6461:    Level: intermediate

6463:    Notes: 
6464:     This allows one to use either the restriction or interpolation (its transpose)
6465:     matrix to do the restriction

6467:    Concepts: matrices^restriction

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

6471: @*/
6472: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
6473: {
6475:   PetscInt       M,N;

6482:   MatPreallocated(A);

6484:   MatGetSize(A,&M,&N);
6485:   if (N > M) {
6486:     MatMult(A,x,y);
6487:   } else {
6488:     MatMultTranspose(A,x,y);
6489:   }
6490:   return(0);
6491: }

6495: /*@
6496:    MatNullSpaceAttach - attaches a null space to a matrix.
6497:         This null space will be removed from the resulting vector whenever
6498:         MatMult() is called

6500:    Collective on Mat

6502:    Input Parameters:
6503: +  mat - the matrix
6504: -  nullsp - the null space object

6506:    Level: developer

6508:    Notes:
6509:       Overwrites any previous null space that may have been attached

6511:    Concepts: null space^attaching to matrix

6513: .seealso: MatCreate(), MatNullSpaceCreate()
6514: @*/
6515: PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6516: {

6523:   MatPreallocated(mat);
6524:   PetscObjectReference((PetscObject)nullsp);
6525:   if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6526:   mat->nullsp = nullsp;
6527:   return(0);
6528: }

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

6535:    Collective on Mat

6537:    Input Parameters:
6538: +  mat - the matrix
6539: .  row - row/column permutation
6540: .  fill - expected fill factor >= 1.0
6541: -  level - level of fill, for ICC(k)

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

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

6551:    Level: developer

6553:    Concepts: matrices^incomplete Cholesky factorization
6554:    Concepts: Cholesky factorization

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

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

6561: @*/
6562: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6563: {

6571:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6572:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6573:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6574:   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6575:   MatPreallocated(mat);
6576:   (*mat->ops->iccfactor)(mat,row,info);
6577:   PetscObjectStateIncrease((PetscObject)mat);
6578:   return(0);
6579: }

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

6586:    Not Collective

6588:    Input Parameters:
6589: +  mat - the matrix
6590: -  v - the values compute with ADIC

6592:    Level: developer

6594:    Notes:
6595:      Must call MatSetColoring() before using this routine. Also this matrix must already
6596:      have its nonzero pattern determined.

6598: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6599:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6600: @*/
6601: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
6602: {


6610:   if (!mat->assembled) {
6611:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6612:   }
6613:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6614:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6615:   (*mat->ops->setvaluesadic)(mat,v);
6616:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6617:   MatView_Private(mat);
6618:   PetscObjectStateIncrease((PetscObject)mat);
6619:   return(0);
6620: }


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

6628:    Not Collective

6630:    Input Parameters:
6631: +  mat - the matrix
6632: -  coloring - the coloring

6634:    Level: developer

6636: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6637:           MatSetValues(), MatSetValuesAdic()
6638: @*/
6639: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
6640: {


6648:   if (!mat->assembled) {
6649:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6650:   }
6651:   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6652:   (*mat->ops->setcoloring)(mat,coloring);
6653:   return(0);
6654: }

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

6661:    Not Collective

6663:    Input Parameters:
6664: +  mat - the matrix
6665: .  nl - leading dimension of v
6666: -  v - the values compute with ADIFOR

6668:    Level: developer

6670:    Notes:
6671:      Must call MatSetColoring() before using this routine. Also this matrix must already
6672:      have its nonzero pattern determined.

6674: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6675:           MatSetValues(), MatSetColoring()
6676: @*/
6677: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6678: {


6686:   if (!mat->assembled) {
6687:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6688:   }
6689:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6690:   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6691:   (*mat->ops->setvaluesadifor)(mat,nl,v);
6692:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6693:   PetscObjectStateIncrease((PetscObject)mat);
6694:   return(0);
6695: }

6699: /*@ 
6700:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
6701:          ghosted ones.

6703:    Not Collective

6705:    Input Parameters:
6706: +  mat - the matrix
6707: -  diag = the diagonal values, including ghost ones

6709:    Level: developer

6711:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6712:       
6713: .seealso: MatDiagonalScale()
6714: @*/
6715: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
6716: {
6718:   PetscMPIInt    size;


6725:   if (!mat->assembled) {
6726:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6727:   }
6728:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6729:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
6730:   if (size == 1) {
6731:     PetscInt n,m;
6732:     VecGetSize(diag,&n);
6733:     MatGetSize(mat,0,&m);
6734:     if (m == n) {
6735:       MatDiagonalScale(mat,0,diag);
6736:     } else {
6737:       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6738:     }
6739:   } else {
6740:     PetscErrorCode (*f)(Mat,Vec);
6741:     PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6742:     if (f) {
6743:       (*f)(mat,diag);
6744:     } else {
6745:       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6746:     }
6747:   }
6748:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6749:   PetscObjectStateIncrease((PetscObject)mat);
6750:   return(0);
6751: }

6755: /*@ 
6756:    MatGetInertia - Gets the inertia from a factored matrix

6758:    Collective on Mat

6760:    Input Parameter:
6761: .  mat - the matrix

6763:    Output Parameters:
6764: +   nneg - number of negative eigenvalues
6765: .   nzero - number of zero eigenvalues
6766: -   npos - number of positive eigenvalues

6768:    Level: advanced

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


6773: @*/
6774: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6775: {

6781:   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6782:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6783:   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6784:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6785:   return(0);
6786: }

6788: /* ----------------------------------------------------------------*/
6791: /*@C
6792:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

6794:    Collective on Mat and Vecs

6796:    Input Parameters:
6797: +  mat - the factored matrix
6798: -  b - the right-hand-side vectors

6800:    Output Parameter:
6801: .  x - the result vectors

6803:    Notes:
6804:    The vectors b and x cannot be the same.  I.e., one cannot
6805:    call MatSolves(A,x,x).

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

6812:    Level: developer

6814:    Concepts: matrices^triangular solves

6816: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6817: @*/
6818: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
6819: {

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

6829:   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6830:   MatPreallocated(mat);
6831:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6832:   (*mat->ops->solves)(mat,b,x);
6833:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6834:   return(0);
6835: }

6839: /*@
6840:    MatIsSymmetric - Test whether a matrix is symmetric

6842:    Collective on Mat

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

6848:    Output Parameters:
6849: .  flg - the result

6851:    Level: intermediate

6853:    Concepts: matrix^symmetry

6855: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6856: @*/
6857: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6858: {

6864:   if (!A->symmetric_set) {
6865:     if (!A->ops->issymmetric) {
6866:       const MatType mattype;
6867:       MatGetType(A,&mattype);
6868:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6869:     }
6870:     (*A->ops->issymmetric)(A,tol,&A->symmetric);
6871:     A->symmetric_set = PETSC_TRUE;
6872:     if (A->symmetric) {
6873:       A->structurally_symmetric_set = PETSC_TRUE;
6874:       A->structurally_symmetric     = PETSC_TRUE;
6875:     }
6876:   }
6877:   *flg = A->symmetric;
6878:   return(0);
6879: }

6883: /*@
6884:    MatIsHermitian - Test whether a matrix is Hermitian

6886:    Collective on Mat

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

6892:    Output Parameters:
6893: .  flg - the result

6895:    Level: intermediate

6897:    Concepts: matrix^symmetry

6899: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6900: @*/
6901: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6902: {

6908:   if (!A->hermitian_set) {
6909:     if (!A->ops->ishermitian) {
6910:       const MatType mattype;
6911:       MatGetType(A,&mattype);
6912:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6913:     }
6914:     (*A->ops->ishermitian)(A,tol,&A->hermitian);
6915:     A->hermitian_set = PETSC_TRUE;
6916:     if (A->hermitian) {
6917:       A->structurally_symmetric_set = PETSC_TRUE;
6918:       A->structurally_symmetric     = PETSC_TRUE;
6919:     }
6920:   }
6921:   *flg = A->hermitian;
6922:   return(0);
6923: }

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

6930:    Collective on Mat

6932:    Input Parameter:
6933: .  A - the matrix to check

6935:    Output Parameters:
6936: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6937: -  flg - the result

6939:    Level: advanced

6941:    Concepts: matrix^symmetry

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

6946: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6947: @*/
6948: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6949: {
6954:   if (A->symmetric_set) {
6955:     *set = PETSC_TRUE;
6956:     *flg = A->symmetric;
6957:   } else {
6958:     *set = PETSC_FALSE;
6959:   }
6960:   return(0);
6961: }

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

6968:    Collective on Mat

6970:    Input Parameter:
6971: .  A - the matrix to check

6973:    Output Parameters:
6974: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6975: -  flg - the result

6977:    Level: advanced

6979:    Concepts: matrix^symmetry

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

6984: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6985: @*/
6986: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6987: {
6992:   if (A->hermitian_set) {
6993:     *set = PETSC_TRUE;
6994:     *flg = A->hermitian;
6995:   } else {
6996:     *set = PETSC_FALSE;
6997:   }
6998:   return(0);
6999: }

7003: /*@
7004:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

7006:    Collective on Mat

7008:    Input Parameter:
7009: .  A - the matrix to test

7011:    Output Parameters:
7012: .  flg - the result

7014:    Level: intermediate

7016:    Concepts: matrix^symmetry

7018: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7019: @*/
7020: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7021: {

7027:   if (!A->structurally_symmetric_set) {
7028:     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7029:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7030:     A->structurally_symmetric_set = PETSC_TRUE;
7031:   }
7032:   *flg = A->structurally_symmetric;
7033:   return(0);
7034: }

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

7043:     Not collective

7045:    Input Parameter:
7046: .   vec - the vector

7048:    Output Parameters:
7049: +   nstash   - the size of the stash
7050: .   reallocs - the number of additional mallocs incurred.
7051: .   bnstash   - the size of the block stash
7052: -   breallocs - the number of additional mallocs incurred.in the block stash
7053:  
7054:    Level: advanced

7056: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7057:   
7058: @*/
7059: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7060: {
7063:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7064:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7065:   return(0);
7066: }

7070: /*@C
7071:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
7072:      parallel layout
7073:    
7074:    Collective on Mat

7076:    Input Parameter:
7077: .  mat - the matrix

7079:    Output Parameter:
7080: +   right - (optional) vector that the matrix can be multiplied against
7081: -   left - (optional) vector that the matrix vector product can be stored in

7083:   Level: advanced

7085: .seealso: MatCreate()
7086: @*/
7087: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7088: {

7094:   MatPreallocated(mat);
7095:   if (mat->ops->getvecs) {
7096:     (*mat->ops->getvecs)(mat,right,left);
7097:   } else {
7098:     PetscMPIInt size;
7099:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
7100:     if (right) {
7101:       VecCreate(((PetscObject)mat)->comm,right);
7102:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7103:       VecSetBlockSize(*right,mat->rmap->bs);
7104:       if (size > 1) {
7105:         /* New vectors uses Mat cmap and does not create a new one */
7106:         PetscMapDestroy((*right)->map);
7107:         (*right)->map = mat->cmap;
7108:         mat->cmap->refcnt++;

7110:         VecSetType(*right,VECMPI);
7111:       } else {VecSetType(*right,VECSEQ);}
7112:     }
7113:     if (left) {
7114:       VecCreate(((PetscObject)mat)->comm,left);
7115:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7116:       VecSetBlockSize(*left,mat->rmap->bs);
7117:       if (size > 1) {
7118:         /* New vectors uses Mat rmap and does not create a new one */
7119:         PetscMapDestroy((*left)->map);
7120:         (*left)->map = mat->rmap;
7121:         mat->rmap->refcnt++;

7123:         VecSetType(*left,VECMPI);
7124:       } else {VecSetType(*left,VECSEQ);}
7125:     }
7126:   }
7127:   if (mat->mapping) {
7128:     if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7129:     if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7130:   }
7131:   if (mat->bmapping) {
7132:     if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7133:     if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7134:   }
7135:   return(0);
7136: }

7140: /*@C
7141:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7142:      with default values.

7144:    Not Collective

7146:    Input Parameters:
7147: .    info - the MatFactorInfo data structure


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

7153:    Level: developer

7155: .seealso: MatFactorInfo

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

7160: @*/

7162: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7163: {

7167:   PetscMemzero(info,sizeof(MatFactorInfo));
7168:   return(0);
7169: }

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

7176:    Collective on Mat

7178:    Input Parameters:
7179: +  A - the matrix
7180: .  P - the projection matrix
7181: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7182: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

7184:    Output Parameters:
7185: .  C - the product matrix

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

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

7193:    Level: intermediate

7195: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7196: @*/
7197: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7198: {

7204:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7205:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7208:   MatPreallocated(P);
7209:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7210:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7212:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7213:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7214:   MatPreallocated(A);

7216:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7217:   (*A->ops->ptap)(A,P,scall,fill,C);
7218:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);

7220:   return(0);
7221: }

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

7228:    Collective on Mat

7230:    Input Parameters:
7231: +  A - the matrix
7232: -  P - the projection matrix

7234:    Output Parameters:
7235: .  C - the product matrix

7237:    Notes:
7238:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7239:    the user using MatDeatroy().

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

7244:    Level: intermediate

7246: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7247: @*/
7248: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
7249: {

7255:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7256:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7259:   MatPreallocated(P);
7260:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7261:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7264:   MatPreallocated(C);
7265:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7266:   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7267:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7268:   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);
7269:   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7270:   MatPreallocated(A);

7272:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7273:   (*A->ops->ptapnumeric)(A,P,C);
7274:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7275:   return(0);
7276: }

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

7283:    Collective on Mat

7285:    Input Parameters:
7286: +  A - the matrix
7287: -  P - the projection matrix

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

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

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

7299:    Level: intermediate

7301: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7302: @*/
7303: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7304: {

7310:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7311:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7312:   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7315:   MatPreallocated(P);
7316:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7317:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7320:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7321:   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);
7322:   MatPreallocated(A);
7323:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7324:   (*A->ops->ptapsymbolic)(A,P,fill,C);
7325:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

7329:   return(0);
7330: }

7334: /*@
7335:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

7337:    Collective on Mat

7339:    Input Parameters:
7340: +  A - the left matrix
7341: .  B - the right matrix
7342: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7343: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7344:           if the result is a dense matrix this is irrelevent

7346:    Output Parameters:
7347: .  C - the product matrix

7349:    Notes:
7350:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

7362:    Level: intermediate

7364: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7365: @*/
7366: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7367: {
7369:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7370:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7371:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

7376:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7377:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7380:   MatPreallocated(B);
7381:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7382:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7384:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7385:   if (scall == MAT_REUSE_MATRIX){
7388:   }
7389:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7390:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7391:   MatPreallocated(A);

7393:   fA = A->ops->matmult;
7394:   fB = B->ops->matmult;
7395:   if (fB == fA) {
7396:     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7397:     mult = fB;
7398:   } else {
7399:     /* dispatch based on the type of A and B */
7400:     char  multname[256];
7401:     PetscStrcpy(multname,"MatMatMult_");
7402:     PetscStrcat(multname,((PetscObject)A)->type_name);
7403:     PetscStrcat(multname,"_");
7404:     PetscStrcat(multname,((PetscObject)B)->type_name);
7405:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7406:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7407:     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);
7408:   }
7409:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7410:   (*mult)(A,B,scall,fill,C);
7411:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7412:   return(0);
7413: }

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

7421:    Collective on Mat

7423:    Input Parameters:
7424: +  A - the left matrix
7425: .  B - the right matrix
7426: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7427:       if C is a dense matrix this is irrelevent
7428:  
7429:    Output Parameters:
7430: .  C - the product matrix

7432:    Notes:
7433:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

7438:    This routine is currently implemented for 
7439:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7440:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7441:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7443:    Level: intermediate

7445: .seealso: MatMatMult(), MatMatMultNumeric()
7446: @*/
7447: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7448: {
7450:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7451:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7452:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

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

7462:   MatPreallocated(B);
7463:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7464:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7467:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7468:   if (fill == PETSC_DEFAULT) fill = 2.0;
7469:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7470:   MatPreallocated(A);
7471: 
7472:   Asymbolic = A->ops->matmultsymbolic;
7473:   Bsymbolic = B->ops->matmultsymbolic;
7474:   if (Asymbolic == Bsymbolic){
7475:     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7476:     symbolic = Bsymbolic;
7477:   } else { /* dispatch based on the type of A and B */
7478:     char  symbolicname[256];
7479:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7480:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7481:     PetscStrcat(symbolicname,"_");
7482:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7483:     PetscStrcat(symbolicname,"_C");
7484:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7485:     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);
7486:   }
7487:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7488:   (*symbolic)(A,B,fill,C);
7489:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7490:   return(0);
7491: }

7495: /*@
7496:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7497:    Call this routine after first calling MatMatMultSymbolic().

7499:    Collective on Mat

7501:    Input Parameters:
7502: +  A - the left matrix
7503: -  B - the right matrix

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

7508:    Notes:
7509:    C must have been created with MatMatMultSymbolic().

7511:    This routine is currently implemented for 
7512:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7513:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7514:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7516:    Level: intermediate

7518: .seealso: MatMatMult(), MatMatMultSymbolic()
7519: @*/
7520: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
7521: {
7523:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7524:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7525:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

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

7535:   MatPreallocated(B);
7536:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7537:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7541:   MatPreallocated(C);
7542:   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7543:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7545:   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7546:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7547:   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7548:   MatPreallocated(A);

7550:   Anumeric = A->ops->matmultnumeric;
7551:   Bnumeric = B->ops->matmultnumeric;
7552:   if (Anumeric == Bnumeric){
7553:     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7554:     numeric = Bnumeric;
7555:   } else {
7556:     char  numericname[256];
7557:     PetscStrcpy(numericname,"MatMatMultNumeric_");
7558:     PetscStrcat(numericname,((PetscObject)A)->type_name);
7559:     PetscStrcat(numericname,"_");
7560:     PetscStrcat(numericname,((PetscObject)B)->type_name);
7561:     PetscStrcat(numericname,"_C");
7562:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7563:     if (!numeric)
7564:       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7565:   }
7566:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7567:   (*numeric)(A,B,C);
7568:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7569:   return(0);
7570: }

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

7577:    Collective on Mat

7579:    Input Parameters:
7580: +  A - the left matrix
7581: .  B - the right matrix
7582: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7583: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

7585:    Output Parameters:
7586: .  C - the product matrix

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

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

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

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

7599:    Level: intermediate

7601: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7602: @*/
7603: PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7604: {
7606:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7607:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

7612:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7613:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7616:   MatPreallocated(B);
7617:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7618:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7620:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7621:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7622:   MatPreallocated(A);

7624:   fA = A->ops->matmulttranspose;
7625:   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7626:   fB = B->ops->matmulttranspose;
7627:   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7628:   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);

7630:   PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7631:   (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7632:   PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7633: 
7634:   return(0);
7635: }

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

7642:    Collective on Mat

7644:    Input Parameters:
7645: +  mat - the matrix
7646: .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7647: .  subcomm - MPI communicator split from the communicator where mat resides in
7648: .  mlocal_red - number of local rows of the redundant matrix
7649: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7651:    Output Parameter:
7652: .  matredundant - redundant matrix

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

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

7661:    Only MPIAIJ matrix is supported. 
7662:    
7663:    Level: advanced

7665:    Concepts: subcommunicator
7666:    Concepts: duplicate matrix

7668: .seealso: MatDestroy()
7669: @*/
7670: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7671: {

7676:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7679:   }
7680:   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7681:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7682:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7683:   MatPreallocated(mat);

7685:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7686:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7687:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7688:   return(0);
7689: }