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 MatSetBlockSize(), 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:           MatSetBlockSize(), MatSetLocalToGlobalMapping()
1203: @*/
1204: PetscErrorCode  MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1205: {
1207:   PetscInt       j,i,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1208:   PetscInt       *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);

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

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

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

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

1251:    Not Collective

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


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

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

1269:    Concepts: matrices^putting entries in

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


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

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

1299:    Not Collective

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

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

1317:    Note that you must call MatSetBlockSize() when constructing this matrix (and before
1318:    preallocating it).

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

1323:    Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 
1324:    options cannot be mixed without intervening calls to the assembly
1325:    routines.

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

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

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

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

1356:    Level: intermediate

1358:    Concepts: matrices^putting entries in blocked

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

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

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

1419: /*@ 
1420:    MatGetValues - Gets a block of values from a matrix.

1422:    Not Collective; currently only returns a local block

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

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

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

1438:    MatGetValues() requires that the matrix has been assembled
1439:    with MatAssemblyBegin()/MatAssemblyEnd().  Thus, calls to
1440:    MatSetValues() and MatGetValues() CANNOT be made in succession
1441:    without intermediate matrix assembly.

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

1446:    Level: advanced

1448:    Concepts: matrices^accessing values

1450: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1451: @*/
1452: PetscErrorCode  MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1453: {

1462:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1463:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1464:   if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1465:   MatPreallocated(mat);

1467:   PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1468:   (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1469:   PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1470:   return(0);
1471: }

1475: /*@
1476:    MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1477:    the routine MatSetValuesLocal() to allow users to insert matrix entries
1478:    using a local (per-processor) numbering.

1480:    Not Collective

1482:    Input Parameters:
1483: +  x - the matrix
1484: -  mapping - mapping created with ISLocalToGlobalMappingCreate() 
1485:              or ISLocalToGlobalMappingCreateIS()

1487:    Level: intermediate

1489:    Concepts: matrices^local to global mapping
1490:    Concepts: local to global mapping^for matrices

1492: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1493: @*/
1494: PetscErrorCode  MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping)
1495: {
1501:   if (x->mapping) {
1502:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1503:   }
1504:   MatPreallocated(x);

1506:   if (x->ops->setlocaltoglobalmapping) {
1507:     (*x->ops->setlocaltoglobalmapping)(x,mapping);
1508:   } else {
1509:     PetscObjectReference((PetscObject)mapping);
1510:     if (x->mapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1511:     x->mapping = mapping;
1512:   }
1513:   return(0);
1514: }

1518: /*@
1519:    MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1520:    by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1521:    entries using a local (per-processor) numbering.

1523:    Not Collective

1525:    Input Parameters:
1526: +  x - the matrix
1527: -  mapping - mapping created with ISLocalToGlobalMappingCreate() or
1528:              ISLocalToGlobalMappingCreateIS()

1530:    Level: intermediate

1532:    Concepts: matrices^local to global mapping blocked
1533:    Concepts: local to global mapping^for matrices, blocked

1535: .seealso:  MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1536:            MatSetValuesBlocked(), MatSetValuesLocal()
1537: @*/
1538: PetscErrorCode  MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping)
1539: {
1545:   if (x->bmapping) {
1546:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix");
1547:   }
1548:   PetscObjectReference((PetscObject)mapping);
1549:   if (x->bmapping) { ISLocalToGlobalMappingDestroy(x->mapping); }
1550:   x->bmapping = mapping;
1551:   return(0);
1552: }

1556: /*@
1557:    MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1558:    using a local ordering of the nodes. 

1560:    Not Collective

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

1571:    Notes:
1572:    Before calling MatSetValuesLocal(), the user must first set the
1573:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

1575:    Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 
1576:    options cannot be mixed without intervening calls to the assembly
1577:    routines.

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

1582:    Level: intermediate

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

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

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

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

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

1638:    Not Collective

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

1649:    Notes:
1650:    Before calling MatSetValuesBlockedLocal(), the user must first set the
1651:    block size using MatSetBlockSize(), and the local-to-global mapping by
1652:    calling MatSetLocalToGlobalMappingBlock(), where the mapping MUST be
1653:    set for matrix blocks, not for matrix elements.

1655:    Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 
1656:    options cannot be mixed without intervening calls to the assembly
1657:    routines.

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

1662:    Level: intermediate

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

1666: .seealso:  MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
1667:            MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
1668: @*/
1669: PetscErrorCode  MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1670: {
1672:   PetscInt       irowm[2048],icolm[2048];

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

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

1733: /* --------------------------------------------------------*/
1736: /*@
1737:    MatMult - Computes the matrix-vector product, y = Ax.

1739:    Collective on Mat and Vec

1741:    Input Parameters:
1742: +  mat - the matrix
1743: -  x   - the vector to be multiplied

1745:    Output Parameters:
1746: .  y - the result

1748:    Notes:
1749:    The vectors x and y cannot be the same.  I.e., one cannot
1750:    call MatMult(A,y,y).

1752:    Level: beginner

1754:    Concepts: matrix-vector product

1756: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
1757: @*/
1758: PetscErrorCode  MatMult(Mat mat,Vec x,Vec y)
1759: {


1768:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1769:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1770:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1771: #ifndef PETSC_HAVE_CONSTRAINTS
1772:   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);
1773:   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);
1774:   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);
1775: #endif
1776:   MatPreallocated(mat);

1778:   if (mat->nullsp) {
1779:     MatNullSpaceRemove(mat->nullsp,x,&x);
1780:   }

1782:   if (!mat->ops->mult) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
1783:   PetscLogEventBegin(MAT_Mult,mat,x,y,0);
1784:   (*mat->ops->mult)(mat,x,y);
1785:   PetscLogEventEnd(MAT_Mult,mat,x,y,0);

1787:   if (mat->nullsp) {
1788:     MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);
1789:   }
1790:   PetscObjectStateIncrease((PetscObject)y);
1791:   return(0);
1792: }

1796: /*@
1797:    MatMultTranspose - Computes matrix transpose times a vector.

1799:    Collective on Mat and Vec

1801:    Input Parameters:
1802: +  mat - the matrix
1803: -  x   - the vector to be multilplied

1805:    Output Parameters:
1806: .  y - the result

1808:    Notes:
1809:    The vectors x and y cannot be the same.  I.e., one cannot
1810:    call MatMultTranspose(A,y,y).

1812:    Level: beginner

1814:    Concepts: matrix vector product^transpose

1816: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd()
1817: @*/
1818: PetscErrorCode  MatMultTranspose(Mat mat,Vec x,Vec y)
1819: {


1828:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1829:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1830:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1831: #ifndef PETSC_HAVE_CONSTRAINTS
1832:   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);
1833:   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);
1834: #endif
1835:   MatPreallocated(mat);

1837:   if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
1838:   PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
1839:   (*mat->ops->multtranspose)(mat,x,y);
1840:   PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
1841:   PetscObjectStateIncrease((PetscObject)y);
1842:   return(0);
1843: }

1847: /*@
1848:     MatMultAdd -  Computes v3 = v2 + A * v1.

1850:     Collective on Mat and Vec

1852:     Input Parameters:
1853: +   mat - the matrix
1854: -   v1, v2 - the vectors

1856:     Output Parameters:
1857: .   v3 - the result

1859:     Notes:
1860:     The vectors v1 and v3 cannot be the same.  I.e., one cannot
1861:     call MatMultAdd(A,v1,v2,v1).

1863:     Level: beginner

1865:     Concepts: matrix vector product^addition

1867: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
1868: @*/
1869: PetscErrorCode  MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1870: {


1880:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1881:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1882:   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);
1883:   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);
1884:   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);
1885:   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);
1886:   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);
1887:   if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
1888:   MatPreallocated(mat);

1890:   PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
1891:   (*mat->ops->multadd)(mat,v1,v2,v3);
1892:   PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
1893:   PetscObjectStateIncrease((PetscObject)v3);
1894:   return(0);
1895: }

1899: /*@
1900:    MatMultTransposeAdd - Computes v3 = v2 + A' * v1.

1902:    Collective on Mat and Vec

1904:    Input Parameters:
1905: +  mat - the matrix
1906: -  v1, v2 - the vectors

1908:    Output Parameters:
1909: .  v3 - the result

1911:    Notes:
1912:    The vectors v1 and v3 cannot be the same.  I.e., one cannot
1913:    call MatMultTransposeAdd(A,v1,v2,v1).

1915:    Level: beginner

1917:    Concepts: matrix vector product^transpose and addition

1919: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
1920: @*/
1921: PetscErrorCode  MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
1922: {


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

1941:   PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
1942:   (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
1943:   PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
1944:   PetscObjectStateIncrease((PetscObject)v3);
1945:   return(0);
1946: }

1950: /*@
1951:    MatMultConstrained - The inner multiplication routine for a
1952:    constrained matrix P^T A P.

1954:    Collective on Mat and Vec

1956:    Input Parameters:
1957: +  mat - the matrix
1958: -  x   - the vector to be multilplied

1960:    Output Parameters:
1961: .  y - the result

1963:    Notes:
1964:    The vectors x and y cannot be the same.  I.e., one cannot
1965:    call MatMult(A,y,y).

1967:    Level: beginner

1969: .keywords: matrix, multiply, matrix-vector product, constraint
1970: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
1971: @*/
1972: PetscErrorCode  MatMultConstrained(Mat mat,Vec x,Vec y)
1973: {

1980:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1981:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1982:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
1983:   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);
1984:   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);
1985:   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);

1987:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
1988:   (*mat->ops->multconstrained)(mat,x,y);
1989:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
1990:   PetscObjectStateIncrease((PetscObject)y);

1992:   return(0);
1993: }

1997: /*@
1998:    MatMultTransposeConstrained - The inner multiplication routine for a
1999:    constrained matrix P^T A^T P.

2001:    Collective on Mat and Vec

2003:    Input Parameters:
2004: +  mat - the matrix
2005: -  x   - the vector to be multilplied

2007:    Output Parameters:
2008: .  y - the result

2010:    Notes:
2011:    The vectors x and y cannot be the same.  I.e., one cannot
2012:    call MatMult(A,y,y).

2014:    Level: beginner

2016: .keywords: matrix, multiply, matrix-vector product, constraint
2017: .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd()
2018: @*/
2019: PetscErrorCode  MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2020: {

2027:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2028:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2029:   if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2030:   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);
2031:   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);

2033:   PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2034:   (*mat->ops->multtransposeconstrained)(mat,x,y);
2035:   PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2036:   PetscObjectStateIncrease((PetscObject)y);

2038:   return(0);
2039: }
2040: /* ------------------------------------------------------------*/
2043: /*@C
2044:    MatGetInfo - Returns information about matrix storage (number of
2045:    nonzeros, memory, etc.).

2047:    Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used
2048:    as the flag

2050:    Input Parameters:
2051: .  mat - the matrix

2053:    Output Parameters:
2054: +  flag - flag indicating the type of parameters to be returned
2055:    (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2056:    MAT_GLOBAL_SUM - sum over all processors)
2057: -  info - matrix information context

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

2068:    Example for C/C++ Users:
2069:    See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2070:    data within the MatInfo context.  For example, 
2071: .vb
2072:       MatInfo info;
2073:       Mat     A;
2074:       double  mal, nz_a, nz_u;

2076:       MatGetInfo(A,MAT_LOCAL,&info);
2077:       mal  = info.mallocs;
2078:       nz_a = info.nz_allocated;
2079: .ve

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

2092:       call MatGetInfo(A,MAT_LOCAL,info,ierr)
2093:       mal = info(MAT_INFO_MALLOCS)
2094:       nz_a = info(MAT_INFO_NZ_ALLOCATED)
2095: .ve

2097:     Level: intermediate

2099:     Concepts: matrices^getting information on
2100:     
2101:     Developer Note: fortran interface is not autogenerated as the f90
2102:     interface defintion cannot be generated correctly [due to MatInfo]
2103:  
2104: @*/
2105: PetscErrorCode  MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2106: {

2113:   if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2114:   MatPreallocated(mat);
2115:   (*mat->ops->getinfo)(mat,flag,info);
2116:   return(0);
2117: }

2119: /* ----------------------------------------------------------*/
2122: /*@C  
2123:    MatILUDTFactor - Performs a drop tolerance ILU factorization.

2125:    Collective on Mat

2127:    Input Parameters:
2128: +  mat - the matrix
2129: .  row - row permutation
2130: .  col - column permutation
2131: -  info - information about the factorization to be done

2133:    Output Parameters:
2134: .  fact - the factored matrix

2136:    Level: developer

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

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

2148:     Concepts: matrices^ILUDT factorization

2150: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2151: @*/
2152: PetscErrorCode  MatILUDTFactor(Mat mat,IS row,IS col,const MatFactorInfo *info,Mat *fact)
2153: {

2163:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2164:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2165:   if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2166:   MatPreallocated(mat);
2167:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2168:   (*mat->ops->iludtfactor)(mat,row,col,info,fact);
2169:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2170:   PetscObjectStateIncrease((PetscObject)*fact);

2172:   return(0);
2173: }

2177: /*@C
2178:    MatLUFactor - Performs in-place LU factorization of matrix.

2180:    Collective on Mat

2182:    Input Parameters:
2183: +  mat - the matrix
2184: .  row - row permutation
2185: .  col - column permutation
2186: -  info - options for factorization, includes 
2187: $          fill - expected fill as ratio of original fill.
2188: $          dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2189: $                   Run with the option -info to determine an optimal value to use

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

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

2199:    Level: developer

2201:    Concepts: matrices^LU factorization

2203: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2204:           MatGetOrdering(), MatSetUnfactored(), MatFactorInfo

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

2209: @*/
2210: PetscErrorCode  MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2211: {

2220:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2221:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2222:   if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2223:   MatPreallocated(mat);

2225:   PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2226:   (*mat->ops->lufactor)(mat,row,col,info);
2227:   PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2228:   PetscObjectStateIncrease((PetscObject)mat);
2229:   return(0);
2230: }

2234: /*@C
2235:    MatILUFactor - Performs in-place ILU factorization of matrix.

2237:    Collective on Mat

2239:    Input Parameters:
2240: +  mat - the matrix
2241: .  row - row permutation
2242: .  col - column permutation
2243: -  info - structure containing 
2244: $      levels - number of levels of fill.
2245: $      expected fill - as ratio of original fill.
2246: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2247:                 missing diagonal entries)

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

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

2257:    Level: developer

2259:    Concepts: matrices^ILU factorization

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

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

2266: @*/
2267: PetscErrorCode  MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2268: {

2277:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
2278:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2279:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2280:   if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2281:   MatPreallocated(mat);

2283:   PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2284:   (*mat->ops->ilufactor)(mat,row,col,info);
2285:   PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2286:   PetscObjectStateIncrease((PetscObject)mat);
2287:   return(0);
2288: }

2292: /*@C
2293:    MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2294:    Call this routine before calling MatLUFactorNumeric().

2296:    Collective on Mat

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


2308:    Notes:
2309:    See the users manual for additional information about
2310:    choosing the fill factor for better efficiency.

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

2316:    Level: developer

2318:    Concepts: matrices^LU symbolic factorization

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

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

2325: @*/
2326: PetscErrorCode  MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2327: {

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

2342:   PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2343:   (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2344:   PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2345:   PetscObjectStateIncrease((PetscObject)fact);
2346:   return(0);
2347: }

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

2355:    Collective on Mat

2357:    Input Parameters:
2358: +  fact - the factor matrix obtained with MatGetFactor()
2359: .  mat - the matrix
2360: -  info - options for factorization

2362:    Notes:
2363:    See MatLUFactor() for in-place factorization.  See 
2364:    MatCholeskyFactorNumeric() for the symmetric, positive definite case.  

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

2370:    Level: developer

2372:    Concepts: matrices^LU numeric factorization

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

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

2379: @*/
2380: PetscErrorCode  MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2381: {

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

2399:   MatView_Private(fact);
2400:   PetscObjectStateIncrease((PetscObject)fact);
2401:   return(0);
2402: }

2406: /*@C
2407:    MatCholeskyFactor - Performs in-place Cholesky factorization of a
2408:    symmetric matrix. 

2410:    Collective on Mat

2412:    Input Parameters:
2413: +  mat - the matrix
2414: .  perm - row and column permutations
2415: -  f - expected fill as ratio of original fill

2417:    Notes:
2418:    See MatLUFactor() for the nonsymmetric case.  See also
2419:    MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().

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

2425:    Level: developer

2427:    Concepts: matrices^Cholesky factorization

2429: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2430:           MatGetOrdering()

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

2435: @*/
2436: PetscErrorCode  MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2437: {

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

2451:   PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2452:   (*mat->ops->choleskyfactor)(mat,perm,info);
2453:   PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2454:   PetscObjectStateIncrease((PetscObject)mat);
2455:   return(0);
2456: }

2460: /*@C
2461:    MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2462:    of a symmetric matrix. 

2464:    Collective on Mat

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

2475:    Notes:
2476:    See MatLUFactorSymbolic() for the nonsymmetric case.  See also
2477:    MatCholeskyFactor() and MatCholeskyFactorNumeric().

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

2483:    Level: developer

2485:    Concepts: matrices^Cholesky symbolic factorization

2487: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2488:           MatGetOrdering()

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

2493: @*/
2494: PetscErrorCode  MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2495: {

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

2510:   PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2511:   (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
2512:   PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
2513:   PetscObjectStateIncrease((PetscObject)fact);
2514:   return(0);
2515: }

2519: /*@C
2520:    MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
2521:    of a symmetric matrix. Call this routine after first calling
2522:    MatCholeskyFactorSymbolic().

2524:    Collective on Mat

2526:    Input Parameters:
2527: +  fact - the factor matrix obtained with MatGetFactor()
2528: .  mat - the initial matrix
2529: .  info - options for factorization
2530: -  fact - the symbolic factor of mat


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

2538:    Level: developer

2540:    Concepts: matrices^Cholesky numeric factorization

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

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

2547: @*/
2548: PetscErrorCode  MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2549: {

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

2564:   PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
2565:   (fact->ops->choleskyfactornumeric)(fact,mat,info);
2566:   PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);

2568:   MatView_Private(fact);
2569:   PetscObjectStateIncrease((PetscObject)fact);
2570:   return(0);
2571: }

2573: /* ----------------------------------------------------------------*/
2576: /*@
2577:    MatSolve - Solves A x = b, given a factored matrix.

2579:    Collective on Mat and Vec

2581:    Input Parameters:
2582: +  mat - the factored matrix
2583: -  b - the right-hand-side vector

2585:    Output Parameter:
2586: .  x - the result vector

2588:    Notes:
2589:    The vectors b and x cannot be the same.  I.e., one cannot
2590:    call MatSolve(A,x,x).

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

2597:    Level: developer

2599:    Concepts: matrices^triangular solves

2601: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
2602: @*/
2603: PetscErrorCode  MatSolve(Mat mat,Vec b,Vec x)
2604: {

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

2623:   PetscLogEventBegin(MAT_Solve,mat,b,x,0);
2624:   (*mat->ops->solve)(mat,b,x);
2625:   PetscLogEventEnd(MAT_Solve,mat,b,x,0);
2626:   PetscObjectStateIncrease((PetscObject)x);
2627:   return(0);
2628: }

2632: PetscErrorCode  MatMatSolve_Basic(Mat A,Mat B,Mat X)
2633: {
2635:   Vec            b,x;
2636:   PetscInt       m,N,i;
2637:   PetscScalar    *bb,*xx;

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

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

2665:    Collective on Mat 

2667:    Input Parameters:
2668: +  mat - the factored matrix
2669: -  B - the right-hand-side matrix  (dense matrix)

2671:    Output Parameter:
2672: .  X - the result matrix (dense matrix)

2674:    Notes:
2675:    The matrices b and x cannot be the same.  I.e., one cannot
2676:    call MatMatSolve(A,x,x).

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

2684:    Level: developer

2686:    Concepts: matrices^triangular solves

2688: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
2689: @*/
2690: PetscErrorCode  MatMatSolve(Mat A,Mat B,Mat X)
2691: {

2701:   if (X == B) SETERRQ(PETSC_ERR_ARG_IDN,"X and B must be different matrices");
2702:   if (!A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2703:   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);
2704:   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);
2705:   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);
2706:   if (!A->rmap->N && !A->cmap->N) return(0);
2707:   MatPreallocated(A);

2709:   PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
2710:   if (!A->ops->matsolve) {
2711:     PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
2712:     MatMatSolve_Basic(A,B,X);
2713:   } else {
2714:     (*A->ops->matsolve)(A,B,X);
2715:   }
2716:   PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
2717:   PetscObjectStateIncrease((PetscObject)X);
2718:   return(0);
2719: }


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

2728:    Collective on Mat and Vec

2730:    Input Parameters:
2731: +  mat - the factored matrix
2732: -  b - the right-hand-side vector

2734:    Output Parameter:
2735: .  x - the result vector

2737:    Notes:
2738:    MatSolve() should be used for most applications, as it performs
2739:    a forward solve followed by a backward solve.

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

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

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

2754:    Level: developer

2756:    Concepts: matrices^forward solves

2758: .seealso: MatSolve(), MatBackwardSolve()
2759: @*/
2760: PetscErrorCode  MatForwardSolve(Mat mat,Vec b,Vec x)
2761: {

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

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

2791:    Collective on Mat and Vec

2793:    Input Parameters:
2794: +  mat - the factored matrix
2795: -  b - the right-hand-side vector

2797:    Output Parameter:
2798: .  x - the result vector

2800:    Notes:
2801:    MatSolve() should be used for most applications, as it performs
2802:    a forward solve followed by a backward solve.

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

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

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

2817:    Level: developer

2819:    Concepts: matrices^backward solves

2821: .seealso: MatSolve(), MatForwardSolve()
2822: @*/
2823: PetscErrorCode  MatBackwardSolve(Mat mat,Vec b,Vec x)
2824: {

2834:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2835:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2836:   if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2837:   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);
2838:   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);
2839:   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);
2840:   MatPreallocated(mat);

2842:   PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
2843:   (*mat->ops->backwardsolve)(mat,b,x);
2844:   PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
2845:   PetscObjectStateIncrease((PetscObject)x);
2846:   return(0);
2847: }

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

2854:    Collective on Mat and Vec

2856:    Input Parameters:
2857: +  mat - the factored matrix
2858: .  b - the right-hand-side vector
2859: -  y - the vector to be added to 

2861:    Output Parameter:
2862: .  x - the result vector

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

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

2872:    Level: developer

2874:    Concepts: matrices^triangular solves

2876: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
2877: @*/
2878: PetscErrorCode  MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
2879: {
2880:   PetscScalar    one = 1.0;
2881:   Vec            tmp;

2893:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
2894:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
2895:   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);
2896:   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);
2897:   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);
2898:   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);
2899:   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);
2900:   MatPreallocated(mat);

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

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

2929:    Collective on Mat and Vec

2931:    Input Parameters:
2932: +  mat - the factored matrix
2933: -  b - the right-hand-side vector

2935:    Output Parameter:
2936: .  x - the result vector

2938:    Notes:
2939:    The vectors b and x cannot be the same.  I.e., one cannot
2940:    call MatSolveTranspose(A,x,x).

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

2946:    Level: developer

2948:    Concepts: matrices^triangular solves

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

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

2978: /*@
2979:    MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 
2980:                       factored matrix. 

2982:    Collective on Mat and Vec

2984:    Input Parameters:
2985: +  mat - the factored matrix
2986: .  b - the right-hand-side vector
2987: -  y - the vector to be added to 

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

2992:    Notes:
2993:    The vectors b and x cannot be the same.  I.e., one cannot
2994:    call MatSolveTransposeAdd(A,x,y,x).

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

3000:    Level: developer

3002:    Concepts: matrices^triangular solves

3004: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3005: @*/
3006: PetscErrorCode  MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3007: {
3008:   PetscScalar    one = 1.0;
3010:   Vec            tmp;

3021:   if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3022:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3023:   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);
3024:   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);
3025:   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);
3026:   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);
3027:   MatPreallocated(mat);

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

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

3057:    Collective on Mat and Vec

3059:    Input Parameters:
3060: +  mat - the matrix
3061: .  b - the right hand side
3062: .  omega - the relaxation factor
3063: .  flag - flag indicating the type of SOR (see below)
3064: .  shift -  diagonal shift
3065: .  its - the number of iterations
3066: -  lits - the number of local iterations 

3068:    Output Parameters:
3069: .  x - the solution (can contain an initial guess)

3071:    SOR Flags:
3072: .     SOR_FORWARD_SWEEP - forward SOR
3073: .     SOR_BACKWARD_SWEEP - backward SOR
3074: .     SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3075: .     SOR_LOCAL_FORWARD_SWEEP - local forward SOR 
3076: .     SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 
3077: .     SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3078: .     SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 
3079:          upper/lower triangular part of matrix to
3080:          vector (with omega)
3081: .     SOR_ZERO_INITIAL_GUESS - zero initial guess

3083:    Notes:
3084:    SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3085:    SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3086:    on each processor. 

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

3091:    Notes for Advanced Users:
3092:    The flags are implemented as bitwise inclusive or operations.
3093:    For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3094:    to specify a zero initial guess for SSOR.

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

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

3103:    Level: developer

3105:    Concepts: matrices^relaxation
3106:    Concepts: matrices^SOR
3107:    Concepts: matrices^Gauss-Seidel

3109: @*/
3110: PetscErrorCode  MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3111: {

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

3130:   MatPreallocated(mat);
3131:   PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3132:   if (mat->ops->relax) {
3133:     ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);
3134:   } else {
3135:     ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3136:   }
3137:   PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3138:   PetscObjectStateIncrease((PetscObject)x);
3139:   return(0);
3140: }

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

3147:    Collective on Mat and Vec

3149:    See MatRelax() for usage

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

3156:    Level: developer

3158: @*/
3159: PetscErrorCode  MatPBRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3160: {

3170:   if (!mat->ops->pbrelax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3171:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3172:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3173:   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);
3174:   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);
3175:   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);
3176:   MatPreallocated(mat);

3178:   PetscLogEventBegin(MAT_Relax,mat,b,x,0);
3179:   ierr =(*mat->ops->pbrelax)(mat,b,omega,flag,shift,its,lits,x);
3180:   PetscLogEventEnd(MAT_Relax,mat,b,x,0);
3181:   PetscObjectStateIncrease((PetscObject)x);
3182:   return(0);
3183: }

3187: /*
3188:       Default matrix copy routine.
3189: */
3190: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3191: {
3192:   PetscErrorCode    ierr;
3193:   PetscInt          i,rstart,rend,nz;
3194:   const PetscInt    *cwork;
3195:   const PetscScalar *vwork;

3198:   if (B->assembled) {
3199:     MatZeroEntries(B);
3200:   }
3201:   MatGetOwnershipRange(A,&rstart,&rend);
3202:   for (i=rstart; i<rend; i++) {
3203:     MatGetRow(A,i,&nz,&cwork,&vwork);
3204:     MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3205:     MatRestoreRow(A,i,&nz,&cwork,&vwork);
3206:   }
3207:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3208:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3209:   PetscObjectStateIncrease((PetscObject)B);
3210:   return(0);
3211: }

3215: /*@
3216:    MatCopy - Copys a matrix to another matrix.

3218:    Collective on Mat

3220:    Input Parameters:
3221: +  A - the matrix
3222: -  str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN

3224:    Output Parameter:
3225: .  B - where the copy is put

3227:    Notes:
3228:    If you use SAME_NONZERO_PATTERN then the two matrices had better have the 
3229:    same nonzero pattern or the routine will crash.

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

3235:    Level: intermediate
3236:    
3237:    Concepts: matrices^copying

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

3241: @*/
3242: PetscErrorCode  MatCopy(Mat A,Mat B,MatStructure str)
3243: {
3245:   PetscInt       i;

3253:   MatPreallocated(B);
3254:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3255:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3256:   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);
3257:   MatPreallocated(A);

3259:   PetscLogEventBegin(MAT_Copy,A,B,0,0);
3260:   if (A->ops->copy) {
3261:     (*A->ops->copy)(A,B,str);
3262:   } else { /* generic conversion */
3263:     MatCopy_Basic(A,B,str);
3264:   }
3265:   if (A->mapping) {
3266:     if (B->mapping) {ISLocalToGlobalMappingDestroy(B->mapping);B->mapping = 0;}
3267:     MatSetLocalToGlobalMapping(B,A->mapping);
3268:   }
3269:   if (A->bmapping) {
3270:     if (B->bmapping) {ISLocalToGlobalMappingDestroy(B->bmapping);B->bmapping = 0;}
3271:     MatSetLocalToGlobalMappingBlock(B,A->mapping);
3272:   }

3274:   B->stencil.dim = A->stencil.dim;
3275:   B->stencil.noc = A->stencil.noc;
3276:   for (i=0; i<=A->stencil.dim; i++) {
3277:     B->stencil.dims[i]   = A->stencil.dims[i];
3278:     B->stencil.starts[i] = A->stencil.starts[i];
3279:   }

3281:   PetscLogEventEnd(MAT_Copy,A,B,0,0);
3282:   PetscObjectStateIncrease((PetscObject)B);
3283:   return(0);
3284: }

3288: /*@C  
3289:    MatConvert - Converts a matrix to another matrix, either of the same
3290:    or different type.

3292:    Collective on Mat

3294:    Input Parameters:
3295: +  mat - the matrix
3296: .  newtype - new matrix type.  Use MATSAME to create a new matrix of the
3297:    same type as the original matrix.
3298: -  reuse - denotes if the destination matrix is to be created or reused.  Currently
3299:    MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3300:    MAT_INITIAL_MATRIX.

3302:    Output Parameter:
3303: .  M - pointer to place new matrix

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

3310:    Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3311:    the MPI communicator of the generated matrix is always the same as the communicator
3312:    of the input matrix.

3314:    Level: intermediate

3316:    Concepts: matrices^converting between storage formats

3318: .seealso: MatCopy(), MatDuplicate()
3319: @*/
3320: PetscErrorCode  MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M)
3321: {
3322:   PetscErrorCode         ierr;
3323:   PetscTruth             sametype,issame,flg;
3324:   char                   convname[256],mtype[256];
3325:   Mat                    B;

3331:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3332:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3333:   MatPreallocated(mat);

3335:   PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3336:   if (flg) {
3337:     newtype = mtype;
3338:   }
3339:   PetscTypeCompare((PetscObject)mat,newtype,&sametype);
3340:   PetscStrcmp(newtype,"same",&issame);
3341:   if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) {
3342:     SETERRQ(PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3343:   }

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

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

3393:     /* 3) See if a good general converter is registered for the desired class */
3394:     conv = B->ops->convertfrom;
3395:     MatDestroy(B);
3396:     if (conv) goto foundconv;

3398:     /* 4) See if a good general converter is known for the current matrix */
3399:     if (mat->ops->convert) {
3400:       conv = mat->ops->convert;
3401:     }
3402:     if (conv) goto foundconv;

3404:     /* 5) Use a really basic converter. */
3405:     conv = MatConvert_Basic;

3407:     foundconv:
3408:     PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3409:     (*conv)(mat,newtype,reuse,M);
3410:     PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3411:   }
3412:   PetscObjectStateIncrease((PetscObject)*M);
3413:   return(0);
3414: }

3418: /*@C  
3419:    MatFactorGetSolverPackage - Returns name of the package providing the factorization routines

3421:    Not Collective

3423:    Input Parameter:
3424: .  mat - the matrix, must be a factored matrix

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

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

3433:    Level: intermediate

3435: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3436: @*/
3437: PetscErrorCode  MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3438: {
3439:   PetscErrorCode         ierr;
3440:   PetscErrorCode         (*conv)(Mat,const MatSolverPackage*);

3445:   if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3446:   PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);
3447:   if (!conv) {
3448:     *type = MAT_SOLVER_PETSC;
3449:   } else {
3450:     (*conv)(mat,type);
3451:   }
3452:   return(0);
3453: }

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

3460:    Collective on Mat

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

3467:    Output Parameters:
3468: .  f - the factor matrix used with MatXXFactorSymbolic() calls 

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

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

3476:    Level: intermediate

3478: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3479: @*/
3480: PetscErrorCode  MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3481: {
3482:   PetscErrorCode         ierr;
3483:   char                   convname[256];
3484:   PetscErrorCode         (*conv)(Mat,MatFactorType,Mat*);


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

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

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

3517:    Collective on Mat

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

3524:    Output Parameter:
3525: .    flg - PETSC_TRUE if the factorization is available

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

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

3533:    Level: intermediate

3535: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3536: @*/
3537: PetscErrorCode  MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscTruth *flg)
3538: {
3539:   PetscErrorCode         ierr;
3540:   char                   convname[256];
3541:   PetscErrorCode         (*conv)(Mat,MatFactorType,PetscTruth*);


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

3550:   PetscStrcpy(convname,"MatGetFactorAvailable_");
3551:   PetscStrcat(convname,((PetscObject)mat)->type_name);
3552:   PetscStrcat(convname,"_");
3553:   PetscStrcat(convname,type);
3554:   PetscStrcat(convname,"_C");
3555:   PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);
3556:   if (!conv) {
3557:     *flg = PETSC_FALSE;
3558:   } else {
3559:     (*conv)(mat,ftype,flg);
3560:   }
3561:   return(0);
3562: }


3567: /*@
3568:    MatDuplicate - Duplicates a matrix including the non-zero structure.

3570:    Collective on Mat

3572:    Input Parameters:
3573: +  mat - the matrix
3574: -  op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero
3575:         values as well or not

3577:    Output Parameter:
3578: .  M - pointer to place new matrix

3580:    Level: intermediate

3582:    Concepts: matrices^duplicating

3584: .seealso: MatCopy(), MatConvert()
3585: @*/
3586: PetscErrorCode  MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
3587: {
3589:   Mat            B;
3590:   PetscInt       i;

3596:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3597:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3598:   MatPreallocated(mat);

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

3623:   PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3624:   PetscObjectStateIncrease((PetscObject)B);
3625:   return(0);
3626: }

3630: /*@ 
3631:    MatGetDiagonal - Gets the diagonal of a matrix.

3633:    Collective on Mat and Vec

3635:    Input Parameters:
3636: +  mat - the matrix
3637: -  v - the vector for storing the diagonal

3639:    Output Parameter:
3640: .  v - the diagonal of the matrix

3642:    Level: intermediate

3644:    Concepts: matrices^accessing diagonals

3646: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
3647: @*/
3648: PetscErrorCode  MatGetDiagonal(Mat mat,Vec v)
3649: {

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

3660:   (*mat->ops->getdiagonal)(mat,v);
3661:   PetscObjectStateIncrease((PetscObject)v);
3662:   return(0);
3663: }

3667: /*@ 
3668:    MatGetRowMin - Gets the minimum value (of the real part) of each
3669:         row of the matrix

3671:    Collective on Mat and Vec

3673:    Input Parameters:
3674: .  mat - the matrix

3676:    Output Parameter:
3677: +  v - the vector for storing the maximums
3678: -  idx - the indices of the column found for each row (optional)

3680:    Level: intermediate

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

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

3687:    Concepts: matrices^getting row maximums

3689: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
3690:           MatGetRowMax()
3691: @*/
3692: PetscErrorCode  MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
3693: {

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

3704:   (*mat->ops->getrowmin)(mat,v,idx);
3705:   PetscObjectStateIncrease((PetscObject)v);
3706:   return(0);
3707: }

3711: /*@ 
3712:    MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
3713:         row of the matrix

3715:    Collective on Mat and Vec

3717:    Input Parameters:
3718: .  mat - the matrix

3720:    Output Parameter:
3721: +  v - the vector for storing the minimums
3722: -  idx - the indices of the column found for each row (optional)

3724:    Level: intermediate

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

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

3731:    Concepts: matrices^getting row maximums

3733: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
3734: @*/
3735: PetscErrorCode  MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
3736: {

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

3748:   (*mat->ops->getrowminabs)(mat,v,idx);
3749:   PetscObjectStateIncrease((PetscObject)v);
3750:   return(0);
3751: }

3755: /*@ 
3756:    MatGetRowMax - Gets the maximum value (of the real part) of each
3757:         row of the matrix

3759:    Collective on Mat and Vec

3761:    Input Parameters:
3762: .  mat - the matrix

3764:    Output Parameter:
3765: +  v - the vector for storing the maximums
3766: -  idx - the indices of the column found for each row (optional)

3768:    Level: intermediate

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

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

3775:    Concepts: matrices^getting row maximums

3777: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
3778: @*/
3779: PetscErrorCode  MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
3780: {

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

3791:   (*mat->ops->getrowmax)(mat,v,idx);
3792:   PetscObjectStateIncrease((PetscObject)v);
3793:   return(0);
3794: }

3798: /*@ 
3799:    MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
3800:         row of the matrix

3802:    Collective on Mat and Vec

3804:    Input Parameters:
3805: .  mat - the matrix

3807:    Output Parameter:
3808: +  v - the vector for storing the maximums
3809: -  idx - the indices of the column found for each row (optional)

3811:    Level: intermediate

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

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

3818:    Concepts: matrices^getting row maximums

3820: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3821: @*/
3822: PetscErrorCode  MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
3823: {

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

3835:   (*mat->ops->getrowmaxabs)(mat,v,idx);
3836:   PetscObjectStateIncrease((PetscObject)v);
3837:   return(0);
3838: }

3842: /*@ 
3843:    MatGetRowSum - Gets the sum of each row of the matrix

3845:    Collective on Mat and Vec

3847:    Input Parameters:
3848: .  mat - the matrix

3850:    Output Parameter:
3851: .  v - the vector for storing the maximums

3853:    Level: intermediate

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

3857:    Concepts: matrices^getting row sums

3859: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
3860: @*/
3861: PetscErrorCode  MatGetRowSum(Mat mat, Vec v)
3862: {
3863:   PetscInt       start, end, row;
3864:   PetscScalar   *array;

3871:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3872:   MatPreallocated(mat);
3873:   MatGetOwnershipRange(mat, &start, &end);
3874:   VecGetArray(v, &array);
3875:   for(row = start; row < end; ++row) {
3876:     PetscInt           ncols, col;
3877:     const PetscInt    *cols;
3878:     const PetscScalar *vals;

3880:     array[row - start] = 0.0;
3881:     MatGetRow(mat, row, &ncols, &cols, &vals);
3882:     for(col = 0; col < ncols; col++) {
3883:       array[row - start] += vals[col];
3884:     }
3885:     MatRestoreRow(mat, row, &ncols, &cols, &vals);
3886:   }
3887:   VecRestoreArray(v, &array);
3888:   PetscObjectStateIncrease((PetscObject) v);
3889:   return(0);
3890: }

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

3897:    Collective on Mat

3899:    Input Parameter:
3900: +  mat - the matrix to transpose
3901: -  reuse - store the transpose matrix in the provided B

3903:    Output Parameters:
3904: .  B - the transpose 

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

3909:    Level: intermediate

3911:    Concepts: matrices^transposing

3913: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose()
3914: @*/
3915: PetscErrorCode  MatTranspose(Mat mat,MatReuse reuse,Mat *B)
3916: {

3922:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3923:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3924:   if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3925:   MatPreallocated(mat);

3927:   PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
3928:   (*mat->ops->transpose)(mat,reuse,B);
3929:   PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
3930:   if (B) {PetscObjectStateIncrease((PetscObject)*B);}
3931:   return(0);
3932: }

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

3940:    Collective on Mat

3942:    Input Parameter:
3943: +  A - the matrix to test
3944: -  B - the matrix to test against, this can equal the first parameter

3946:    Output Parameters:
3947: .  flg - the result

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

3954:    Level: intermediate

3956:    Concepts: matrices^transposing, matrix^symmetry

3958: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
3959: @*/
3960: PetscErrorCode  MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
3961: {
3962:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

3968:   PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);
3969:   PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);
3970:   if (f && g) {
3971:     if (f==g) {
3972:       (*f)(A,B,tol,flg);
3973:     } else {
3974:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
3975:     }
3976:   }
3977:   return(0);
3978: }

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

3985:    Collective on Mat

3987:    Input Parameter:
3988: +  A - the matrix to test
3989: -  B - the matrix to test against, this can equal the first parameter

3991:    Output Parameters:
3992: .  flg - the result

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

3999:    Level: intermediate

4001:    Concepts: matrices^transposing, matrix^symmetry

4003: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4004: @*/
4005: PetscErrorCode  MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscTruth *flg)
4006: {
4007:   PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscTruth*),(*g)(Mat,Mat,PetscReal,PetscTruth*);

4013:   PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);
4014:   PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);
4015:   if (f && g) {
4016:     if (f==g) {
4017:       (*f)(A,B,tol,flg);
4018:     } else {
4019:       SETERRQ(PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4020:     }
4021:   }
4022:   return(0);
4023: }

4027: /*@
4028:    MatPermute - Creates a new matrix with rows and columns permuted from the 
4029:    original.

4031:    Collective on Mat

4033:    Input Parameters:
4034: +  mat - the matrix to permute
4035: .  row - row permutation, each processor supplies only the permutation for its rows
4036: -  col - column permutation, each processor needs the entire column permutation, that is
4037:          this is the same size as the total number of columns in the matrix

4039:    Output Parameters:
4040: .  B - the permuted matrix

4042:    Level: advanced

4044:    Concepts: matrices^permuting

4046: .seealso: MatGetOrdering()
4047: @*/
4048: PetscErrorCode  MatPermute(Mat mat,IS row,IS col,Mat *B)
4049: {

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

4063:   (*mat->ops->permute)(mat,row,col,B);
4064:   PetscObjectStateIncrease((PetscObject)*B);
4065:   return(0);
4066: }

4070: /*@
4071:   MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the 
4072:   original and sparsified to the prescribed tolerance.

4074:   Collective on Mat

4076:   Input Parameters:
4077: + A    - The matrix to permute
4078: . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE
4079: . frac - The half-bandwidth as a fraction of the total size, or 0.0
4080: . tol  - The drop tolerance
4081: . rowp - The row permutation
4082: - colp - The column permutation

4084:   Output Parameter:
4085: . B    - The permuted, sparsified matrix

4087:   Level: advanced

4089:   Note:
4090:   The default behavior (band = PETSC_DECIDE and frac = 0.0) is to
4091:   restrict the half-bandwidth of the resulting matrix to 5% of the
4092:   total matrix size.

4094: .keywords: matrix, permute, sparsify

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

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

4133:     /* Setup bandwidth to include */
4134:     if (band == PETSC_DECIDE) {
4135:       if (frac <= 0.0)
4136:         bw = (PetscInt) (M * 0.05);
4137:       else
4138:         bw = (PetscInt) (M * frac);
4139:     } else {
4140:       if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer");
4141:       bw = band;
4142:     }

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

4177: /*@
4178:    MatEqual - Compares two matrices.

4180:    Collective on Mat

4182:    Input Parameters:
4183: +  A - the first matrix
4184: -  B - the second matrix

4186:    Output Parameter:
4187: .  flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.

4189:    Level: intermediate

4191:    Concepts: matrices^equality between
4192: @*/
4193: PetscErrorCode  MatEqual(Mat A,Mat B,PetscTruth *flg)
4194: {

4204:   MatPreallocated(B);
4205:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4206:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4207:   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);
4208:   if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4209:   if (!B->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4210:   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);
4211:   MatPreallocated(A);

4213:   (*A->ops->equal)(A,B,flg);
4214:   return(0);
4215: }

4219: /*@
4220:    MatDiagonalScale - Scales a matrix on the left and right by diagonal
4221:    matrices that are stored as vectors.  Either of the two scaling
4222:    matrices can be PETSC_NULL.

4224:    Collective on Mat

4226:    Input Parameters:
4227: +  mat - the matrix to be scaled
4228: .  l - the left scaling vector (or PETSC_NULL)
4229: -  r - the right scaling vector (or PETSC_NULL)

4231:    Notes:
4232:    MatDiagonalScale() computes A = LAR, where
4233:    L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)

4235:    Level: intermediate

4237:    Concepts: matrices^diagonal scaling
4238:    Concepts: diagonal scaling of matrices

4240: .seealso: MatScale()
4241: @*/
4242: PetscErrorCode  MatDiagonalScale(Mat mat,Vec l,Vec r)
4243: {

4249:   if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4252:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4253:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4254:   MatPreallocated(mat);

4256:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4257:   (*mat->ops->diagonalscale)(mat,l,r);
4258:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4259:   PetscObjectStateIncrease((PetscObject)mat);
4260:   return(0);
4261: }

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

4268:     Collective on Mat

4270:     Input Parameters:
4271: +   mat - the matrix to be scaled
4272: -   a  - the scaling value

4274:     Output Parameter:
4275: .   mat - the scaled matrix

4277:     Level: intermediate

4279:     Concepts: matrices^scaling all entries

4281: .seealso: MatDiagonalScale()
4282: @*/
4283: PetscErrorCode  MatScale(Mat mat,PetscScalar a)
4284: {

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

4295:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4296:   if (a != 1.0) {
4297:     (*mat->ops->scale)(mat,a);
4298:     PetscObjectStateIncrease((PetscObject)mat);
4299:   }
4300:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4301:   return(0);
4302: }

4306: /*@ 
4307:    MatNorm - Calculates various norms of a matrix.

4309:    Collective on Mat

4311:    Input Parameters:
4312: +  mat - the matrix
4313: -  type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY

4315:    Output Parameters:
4316: .  nrm - the resulting norm 

4318:    Level: intermediate

4320:    Concepts: matrices^norm
4321:    Concepts: norm^of matrix
4322: @*/
4323: PetscErrorCode  MatNorm(Mat mat,NormType type,PetscReal *nrm)
4324: {


4332:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4333:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4334:   if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4335:   MatPreallocated(mat);

4337:   (*mat->ops->norm)(mat,type,nrm);
4338:   return(0);
4339: }

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

4352:    Collective on Mat

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

4365:    Level: beginner

4367:    Concepts: matrices^assembling

4369: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4370: @*/
4371: PetscErrorCode  MatAssemblyBegin(Mat mat,MatAssemblyType type)
4372: {

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

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

4400:    Collective on Mat

4402:    Input Parameter:
4403: .  mat - the matrix 

4405:    Output Parameter:
4406: .  assembled - PETSC_TRUE or PETSC_FALSE

4408:    Level: advanced

4410:    Concepts: matrices^assembled?

4412: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4413: @*/
4414: PetscErrorCode  MatAssembled(Mat mat,PetscTruth *assembled)
4415: {
4420:   *assembled = mat->assembled;
4421:   return(0);
4422: }

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

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

4454:   if (flg1) {
4455:     PetscViewer viewer;

4457:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4458:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
4459:     MatView(mat,viewer);
4460:     PetscViewerPopFormat(viewer);
4461:   }
4462:   if (flg2) {
4463:     PetscViewer viewer;

4465:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4466:     PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);
4467:     MatView(mat,viewer);
4468:     PetscViewerPopFormat(viewer);
4469:   }
4470:   if (flg3) {
4471:     PetscViewer viewer;

4473:     PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);
4474:     MatView(mat,viewer);
4475:   }
4476:   if (flg4) {
4477:     PetscViewer viewer;

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

4511: /*@
4512:    MatAssemblyEnd - Completes assembling the matrix.  This routine should
4513:    be called after MatAssemblyBegin().

4515:    Collective on Mat

4517:    Input Parameters:
4518: +  mat - the matrix 
4519: -  type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY

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

4535:    Notes: 
4536:    MatSetValues() generally caches the values.  The matrix is ready to
4537:    use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4538:    Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4539:    in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4540:    using the matrix.

4542:    Level: beginner

4544: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4545: @*/
4546: PetscErrorCode  MatAssemblyEnd(Mat mat,MatAssemblyType type)
4547: {
4548:   PetscErrorCode  ierr;
4549:   static PetscInt inassm = 0;
4550:   PetscTruth      flg;


4556:   inassm++;
4557:   MatAssemblyEnd_InUse++;
4558:   if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4559:     PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4560:     if (mat->ops->assemblyend) {
4561:       (*mat->ops->assemblyend)(mat,type);
4562:     }
4563:     PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4564:   } else {
4565:     if (mat->ops->assemblyend) {
4566:       (*mat->ops->assemblyend)(mat,type);
4567:     }
4568:   }

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


4603: /*@
4604:    MatCompress - Tries to store the matrix in as little space as 
4605:    possible.  May fail if memory is already fully used, since it
4606:    tries to allocate new space.

4608:    Collective on Mat

4610:    Input Parameters:
4611: .  mat - the matrix 

4613:    Level: advanced

4615: @*/
4616: PetscErrorCode  MatCompress(Mat mat)
4617: {

4623:   MatPreallocated(mat);
4624:   if (mat->ops->compress) {(*mat->ops->compress)(mat);}
4625:   return(0);
4626: }

4630: /*@
4631:    MatSetOption - Sets a parameter option for a matrix. Some options
4632:    may be specific to certain storage formats.  Some options
4633:    determine how values will be inserted (or added). Sorted, 
4634:    row-oriented input will generally assemble the fastest. The default
4635:    is row-oriented, nonsorted input. 

4637:    Collective on Mat

4639:    Input Parameters:
4640: +  mat - the matrix 
4641: .  option - the option, one of those listed below (and possibly others),
4642: -  flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)

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


4655:    Options For Use with MatSetValues():
4656:    Insert a logically dense subblock, which can be
4657: .    MAT_ROW_ORIENTED - row-oriented (default)

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

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

4672:    Notes:
4673:    Some options are relevant only for particular matrix types and
4674:    are thus ignored by others.  Other options are not supported by
4675:    certain matrix types and will generate an error message if set.

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

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

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

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

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

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

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

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

4723:    Level: intermediate

4725:    Concepts: matrices^setting options

4727: @*/
4728: PetscErrorCode  MatSetOption(Mat mat,MatOption op,PetscTruth flg)
4729: {

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

4768: /*@
4769:    MatZeroEntries - Zeros all entries of a matrix.  For sparse matrices
4770:    this routine retains the old nonzero structure.

4772:    Collective on Mat

4774:    Input Parameters:
4775: .  mat - the matrix 

4777:    Level: intermediate

4779:    Concepts: matrices^zeroing

4781: .seealso: MatZeroRows()
4782: @*/
4783: PetscErrorCode  MatZeroEntries(Mat mat)
4784: {

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

4795:   PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
4796:   (*mat->ops->zeroentries)(mat);
4797:   PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
4798:   PetscObjectStateIncrease((PetscObject)mat);
4799:   return(0);
4800: }

4804: /*@C
4805:    MatZeroRows - Zeros all entries (except possibly the main diagonal)
4806:    of a set of rows of a matrix.

4808:    Collective on Mat

4810:    Input Parameters:
4811: +  mat - the matrix
4812: .  numRows - the number of rows to remove
4813: .  rows - the global row indices
4814: -  diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)

4816:    Notes:
4817:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4818:    but does not release memory.  For the dense and block diagonal
4819:    formats this does not alter the nonzero structure.

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

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

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

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

4837:    Level: intermediate

4839:    Concepts: matrices^zeroing rows

4841: .seealso: MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4842: @*/
4843: PetscErrorCode  MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4844: {

4851:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4852:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4853:   if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4854:   MatPreallocated(mat);

4856:   (*mat->ops->zerorows)(mat,numRows,rows,diag);
4857:   MatView_Private(mat);
4858:   PetscObjectStateIncrease((PetscObject)mat);
4859:   return(0);
4860: }

4864: /*@C
4865:    MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
4866:    of a set of rows of a matrix.

4868:    Collective on Mat

4870:    Input Parameters:
4871: +  mat - the matrix
4872: .  is - index set of rows to remove
4873: -  diag - value put in all diagonals of eliminated rows

4875:    Notes:
4876:    For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
4877:    but does not release memory.  For the dense and block diagonal
4878:    formats this does not alter the nonzero structure.

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

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

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

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

4895:    Level: intermediate

4897:    Concepts: matrices^zeroing rows

4899: .seealso: MatZeroRows(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
4900: @*/
4901: PetscErrorCode  MatZeroRowsIS(Mat mat,IS is,PetscScalar diag)
4902: {
4903:   PetscInt       numRows;
4904:   const PetscInt *rows;

4911:   ISGetLocalSize(is,&numRows);
4912:   ISGetIndices(is,&rows);
4913:   MatZeroRows(mat,numRows,rows,diag);
4914:   ISRestoreIndices(is,&rows);
4915:   return(0);
4916: }

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

4924:    Collective on Mat

4926:    Input Parameters:
4927: +  mat - the matrix
4928: .  numRows - the number of rows to remove
4929: .  rows - the global row indices
4930: -  diag - value put in all diagonals of eliminated rows

4932:    Notes:
4933:    Before calling MatZeroRowsLocal(), the user must first set the
4934:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

4936:    For the AIJ matrix formats this removes the old nonzero structure,
4937:    but does not release memory.  For the dense and block diagonal
4938:    formats this does not alter the nonzero structure.

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

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

4948:    Level: intermediate

4950:    Concepts: matrices^zeroing

4952: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
4953: @*/
4954: PetscErrorCode  MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag)
4955: {

4962:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4963:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4964:   MatPreallocated(mat);

4966:   if (mat->ops->zerorowslocal) {
4967:     (*mat->ops->zerorowslocal)(mat,numRows,rows,diag);
4968:   } else {
4969:     IS             is, newis;
4970:     const PetscInt *newRows;

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

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

4991:    Collective on Mat

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

4998:    Notes:
4999:    Before calling MatZeroRowsLocalIS(), the user must first set the
5000:    local-to-global mapping by calling MatSetLocalToGlobalMapping().

5002:    For the AIJ matrix formats this removes the old nonzero structure,
5003:    but does not release memory.  For the dense and block diagonal
5004:    formats this does not alter the nonzero structure.

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

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

5014:    Level: intermediate

5016:    Concepts: matrices^zeroing

5018: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5019: @*/
5020: PetscErrorCode  MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag)
5021: {
5023:   PetscInt       numRows;
5024:   const PetscInt *rows;

5030:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5031:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5032:   MatPreallocated(mat);

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

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

5046:    Not Collective

5048:    Input Parameter:
5049: .  mat - the matrix

5051:    Output Parameters:
5052: +  m - the number of global rows
5053: -  n - the number of global columns

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

5057:    Level: beginner

5059:    Concepts: matrices^size

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

5074: /*@
5075:    MatGetLocalSize - Returns the number of rows and columns in a matrix
5076:    stored locally.  This information may be implementation dependent, so
5077:    use with care.

5079:    Not Collective

5081:    Input Parameters:
5082: .  mat - the matrix

5084:    Output Parameters:
5085: +  m - the number of local rows
5086: -  n - the number of local columns

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

5090:    Level: beginner

5092:    Concepts: matrices^local size

5094: .seealso: MatGetSize()
5095: @*/
5096: PetscErrorCode  MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n)
5097: {
5102:   if (m) *m = mat->rmap->n;
5103:   if (n) *n = mat->cmap->n;
5104:   return(0);
5105: }

5109: /*@
5110:    MatGetOwnershipRangeColumn - Returns the range of matrix columns owned by
5111:    this processor.

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

5115:    Input Parameters:
5116: .  mat - the matrix

5118:    Output Parameters:
5119: +  m - the global index of the first local column
5120: -  n - one more than the global index of the last local column

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

5124:    Level: developer

5126:    Concepts: matrices^column ownership

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

5130: @*/
5131: PetscErrorCode  MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n)
5132: {

5140:   MatPreallocated(mat);
5141:   if (m) *m = mat->cmap->rstart;
5142:   if (n) *n = mat->cmap->rend;
5143:   return(0);
5144: }

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

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

5156:    Input Parameters:
5157: .  mat - the matrix

5159:    Output Parameters:
5160: +  m - the global index of the first local row
5161: -  n - one more than the global index of the last local row

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

5165:    Level: beginner

5167:    Concepts: matrices^row ownership

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

5171: @*/
5172: PetscErrorCode  MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n)
5173: {

5181:   MatPreallocated(mat);
5182:   if (m) *m = mat->rmap->rstart;
5183:   if (n) *n = mat->rmap->rend;
5184:   return(0);
5185: }

5189: /*@C
5190:    MatGetOwnershipRanges - Returns the range of matrix rows owned by
5191:    each process

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

5195:    Input Parameters:
5196: .  mat - the matrix

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

5201:    Level: beginner

5203:    Concepts: matrices^row ownership

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

5207: @*/
5208: PetscErrorCode  MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
5209: {

5215:   MatPreallocated(mat);
5216:   PetscMapGetRanges(mat->rmap,ranges);
5217:   return(0);
5218: }

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

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

5227:    Input Parameters:
5228: .  mat - the matrix

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

5233:    Level: beginner

5235:    Concepts: matrices^column ownership

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

5239: @*/
5240: PetscErrorCode  MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
5241: {

5247:   MatPreallocated(mat);
5248:   PetscMapGetRanges(mat->cmap,ranges);
5249:   return(0);
5250: }

5254: /*@C
5255:    MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
5256:    Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 
5257:    to complete the factorization.

5259:    Collective on Mat

5261:    Input Parameters:
5262: +  mat - the matrix
5263: .  row - row permutation
5264: .  column - column permutation
5265: -  info - structure containing 
5266: $      levels - number of levels of fill.
5267: $      expected fill - as ratio of original fill.
5268: $      1 or 0 - indicating force fill on diagonal (improves robustness for matrices
5269:                 missing diagonal entries)

5271:    Output Parameters:
5272: .  fact - new matrix that has been symbolically factored

5274:    Notes:
5275:    See the users manual for additional information about
5276:    choosing the fill factor for better efficiency.

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

5282:    Level: developer

5284:   Concepts: matrices^symbolic LU factorization
5285:   Concepts: matrices^factorization
5286:   Concepts: LU^symbolic factorization

5288: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
5289:           MatGetOrdering(), MatFactorInfo

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

5294: @*/
5295: PetscErrorCode  MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
5296: {

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

5313:   PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
5314:   (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
5315:   PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
5316:   return(0);
5317: }

5321: /*@C
5322:    MatICCFactorSymbolic - Performs symbolic incomplete
5323:    Cholesky factorization for a symmetric matrix.  Use 
5324:    MatCholeskyFactorNumeric() to complete the factorization.

5326:    Collective on Mat

5328:    Input Parameters:
5329: +  mat - the matrix
5330: .  perm - row and column permutation
5331: -  info - structure containing 
5332: $      levels - number of levels of fill.
5333: $      expected fill - as ratio of original fill.

5335:    Output Parameter:
5336: .  fact - the factored matrix

5338:    Notes:
5339:    Most users should employ the KSP interface for linear solvers
5340:    instead of working directly with matrix algebra routines such as this.
5341:    See, e.g., KSPCreate().

5343:    Level: developer

5345:   Concepts: matrices^symbolic incomplete Cholesky factorization
5346:   Concepts: matrices^factorization
5347:   Concepts: Cholsky^symbolic factorization

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

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

5354: @*/
5355: PetscErrorCode  MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
5356: {

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

5372:   PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
5373:   (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
5374:   PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
5375:   return(0);
5376: }

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

5386:    Not Collective

5388:    Input Parameter:
5389: .  mat - the matrix

5391:    Output Parameter:
5392: .  v - the location of the values


5395:    Fortran Note:
5396:    This routine is used differently from Fortran, e.g.,
5397: .vb
5398:         Mat         mat
5399:         PetscScalar mat_array(1)
5400:         PetscOffset i_mat
5401:         PetscErrorCode ierr
5402:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5408:         [... other code ...]
5409:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5410: .ve

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

5415:    Level: advanced

5417:    Concepts: matrices^access array

5419: .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ()
5420: @*/
5421: PetscErrorCode  MatGetArray(Mat mat,PetscScalar *v[])
5422: {

5429:   if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5430:   MatPreallocated(mat);
5431:   (*mat->ops->getarray)(mat,v);
5432:   CHKMEMQ;
5433:   return(0);
5434: }

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

5441:    Not Collective

5443:    Input Parameter:
5444: +  mat - the matrix
5445: -  v - the location of the values

5447:    Fortran Note:
5448:    This routine is used differently from Fortran, e.g.,
5449: .vb
5450:         Mat         mat
5451:         PetscScalar mat_array(1)
5452:         PetscOffset i_mat
5453:         PetscErrorCode ierr
5454:         call MatGetArray(mat,mat_array,i_mat,ierr)

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

5460:         [... other code ...]
5461:         call MatRestoreArray(mat,mat_array,i_mat,ierr)
5462: .ve

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

5467:    Level: advanced

5469: .seealso: MatGetArray(), MatRestoreArrayF90()
5470: @*/
5471: PetscErrorCode  MatRestoreArray(Mat mat,PetscScalar *v[])
5472: {

5479: #if defined(PETSC_USE_DEBUG)
5480:   CHKMEMQ;
5481: #endif
5482:   if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5483:   (*mat->ops->restorearray)(mat,v);
5484:   PetscObjectStateIncrease((PetscObject)mat);
5485:   return(0);
5486: }

5490: /*@C
5491:    MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
5492:    points to an array of valid matrices, they may be reused to store the new
5493:    submatrices.

5495:    Collective on Mat

5497:    Input Parameters:
5498: +  mat - the matrix
5499: .  n   - the number of submatrixes to be extracted (on this processor, may be zero)
5500: .  irow, icol - index sets of rows and columns to extract
5501: -  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

5503:    Output Parameter:
5504: .  submat - the array of submatrices

5506:    Notes:
5507:    MatGetSubMatrices() can extract ONLY sequential submatrices
5508:    (from both sequential and parallel matrices). Use MatGetSubMatrix()
5509:    to extract a parallel submatrix.

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

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

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

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

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

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

5533:    Level: advanced

5535:    Concepts: matrices^accessing submatrices
5536:    Concepts: submatrices

5538: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
5539: @*/
5540: PetscErrorCode  MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
5541: {
5543:   PetscInt        i;
5544:   PetscTruth      eq;

5549:   if (n) {
5554:   }
5556:   if (n && scall == MAT_REUSE_MATRIX) {
5559:   }
5560:   if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5561:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5562:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5563:   MatPreallocated(mat);

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

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

5590:    Collective on Mat

5592:    Input Parameters:
5593: +  n - the number of local matrices
5594: -  mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
5595:                        sequence of MatGetSubMatrices())

5597:    Level: advanced

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

5602: .seealso: MatGetSubMatrices()
5603: @*/
5604: PetscErrorCode  MatDestroyMatrices(PetscInt n,Mat *mat[])
5605: {
5607:   PetscInt       i;

5610:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
5612:   for (i=0; i<n; i++) {
5613:     MatDestroy((*mat)[i]);
5614:   }
5615:   /* memory is allocated even if n = 0 */
5616:   PetscFree(*mat);
5617:   return(0);
5618: }

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

5625:    Collective on Mat

5627:    Input Parameters:
5628: .  mat - the matrix

5630:    Output Parameter:
5631: .  matstruct - the sequential matrix with the nonzero structure of mat

5633:   Level: intermediate

5635: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
5636: @*/
5637: PetscErrorCode  MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct[])
5638: {

5644: 
5646:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5647:   MatPreallocated(mat);

5649:   PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5650:   (*mat->ops->getseqnonzerostructure)(mat,matstruct);
5651:   PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
5652:   return(0);
5653: }

5657: /*@C
5658:    MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().

5660:    Collective on Mat

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

5666:    Level: advanced

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

5670: .seealso: MatGetSeqNonzeroStructure()
5671: @*/
5672: PetscErrorCode  MatDestroySeqNonzeroStructure(Mat *mat[])
5673: {

5678:   MatDestroyMatrices(1,mat);
5679:   return(0);
5680: }

5684: /*@
5685:    MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
5686:    replaces the index sets by larger ones that represent submatrices with
5687:    additional overlap.

5689:    Collective on Mat

5691:    Input Parameters:
5692: +  mat - the matrix
5693: .  n   - the number of index sets
5694: .  is  - the array of index sets (these index sets will changed during the call)
5695: -  ov  - the additional overlap requested

5697:    Level: developer

5699:    Concepts: overlap
5700:    Concepts: ASM^computing overlap

5702: .seealso: MatGetSubMatrices()
5703: @*/
5704: PetscErrorCode  MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
5705: {

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

5720:   if (!ov) return(0);
5721:   if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5722:   PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
5723:   (*mat->ops->increaseoverlap)(mat,n,is,ov);
5724:   PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
5725:   return(0);
5726: }

5730: /*@
5731:    MatGetBlockSize - Returns the matrix block size; useful especially for the
5732:    block row and block diagonal formats.
5733:    
5734:    Not Collective

5736:    Input Parameter:
5737: .  mat - the matrix

5739:    Output Parameter:
5740: .  bs - block size

5742:    Notes:
5743:    Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ

5745:    Level: intermediate

5747:    Concepts: matrices^block size

5749: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ()
5750: @*/
5751: PetscErrorCode  MatGetBlockSize(Mat mat,PetscInt *bs)
5752: {

5759:   MatPreallocated(mat);
5760:   *bs = mat->rmap->bs;
5761:   return(0);
5762: }

5766: /*@
5767:    MatSetBlockSize - Sets the matrix block size; for many matrix types you 
5768:      cannot use this and MUST set the blocksize when you preallocate the matrix
5769:    
5770:    Collective on Mat

5772:    Input Parameters:
5773: +  mat - the matrix
5774: -  bs - block size

5776:    Notes:
5777:      Only works for shell and AIJ matrices

5779:    Level: intermediate

5781:    Concepts: matrices^block size

5783: .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatGetBlockSize()
5784: @*/
5785: PetscErrorCode  MatSetBlockSize(Mat mat,PetscInt bs)
5786: {

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

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

5809:    Collective on Mat

5811:     Input Parameters:
5812: +   mat - the matrix
5813: .   shift -  0 or 1 indicating we want the indices starting at 0 or 1
5814: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5815:                 symmetrized
5816: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5817:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5818:                  nonzero structure which is different than the full nonzero structure]

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

5827:     Level: developer

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

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

5833:     Fortran Node

5835:            In Fortran use
5836: $           PetscInt ia(1), ja(1)
5837: $           PetscOffset iia, jja
5838: $      call MatGetRowIJ(mat,shift,symmetric,blockcompressed,n,ia,iia,ja,jja,done,ierr)
5839:  
5840:        Acess the ith and jth entries via ia(iia + i) and ja(jja + j)

5842: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray()
5843: @*/
5844: PetscErrorCode  MatGetRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5845: {

5855:   MatPreallocated(mat);
5856:   if (!mat->ops->getrowij) *done = PETSC_FALSE;
5857:   else {
5858:     *done = PETSC_TRUE;
5859:     PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
5860:     (*mat->ops->getrowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5861:     PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
5862:   }
5863:   return(0);
5864: }

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

5871:     Collective on Mat

5873:     Input Parameters:
5874: +   mat - the matrix
5875: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5876: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5877:                 symmetrized
5878: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5879:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5880:                  nonzero structure which is different than the full nonzero structure]

5882:     Output Parameters:
5883: +   n - number of columns in the (possibly compressed) matrix
5884: .   ia - the column pointers
5885: .   ja - the row indices
5886: -   done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned

5888:     Level: developer

5890: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5891: @*/
5892: PetscErrorCode  MatGetColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5893: {

5903:   MatPreallocated(mat);
5904:   if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
5905:   else {
5906:     *done = PETSC_TRUE;
5907:     (*mat->ops->getcolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5908:   }
5909:   return(0);
5910: }

5914: /*@C
5915:     MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
5916:     MatGetRowIJ().

5918:     Collective on Mat

5920:     Input Parameters:
5921: +   mat - the matrix
5922: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5923: .   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5924:                 symmetrized
5925: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5926:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5927:                  nonzero structure which is different than the full nonzero structure]

5929:     Output Parameters:
5930: +   n - size of (possibly compressed) matrix
5931: .   ia - the row pointers
5932: .   ja - the column indices
5933: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

5935:     Level: developer

5937: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
5938: @*/
5939: PetscErrorCode  MatRestoreRowIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5940: {

5949:   MatPreallocated(mat);

5951:   if (!mat->ops->restorerowij) *done = PETSC_FALSE;
5952:   else {
5953:     *done = PETSC_TRUE;
5954:     (*mat->ops->restorerowij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
5955:   }
5956:   return(0);
5957: }

5961: /*@C
5962:     MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
5963:     MatGetColumnIJ().

5965:     Collective on Mat

5967:     Input Parameters:
5968: +   mat - the matrix
5969: .   shift - 1 or zero indicating we want the indices starting at 0 or 1
5970: -   symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
5971:                 symmetrized
5972: -   blockcompressed - PETSC_TRUE or PETSC_FALSE  indicating if the nonzero structure of the
5973:                  blockcompressed matrix is desired or not [inode, baij have blockcompressed 
5974:                  nonzero structure which is different than the full nonzero structure]

5976:     Output Parameters:
5977: +   n - size of (possibly compressed) matrix
5978: .   ia - the column pointers
5979: .   ja - the row indices
5980: -   done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned

5982:     Level: developer

5984: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
5985: @*/
5986: PetscErrorCode  MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscTruth symmetric,PetscTruth blockcompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscTruth *done)
5987: {

5996:   MatPreallocated(mat);

5998:   if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
5999:   else {
6000:     *done = PETSC_TRUE;
6001:     (*mat->ops->restorecolumnij)(mat,shift,symmetric,blockcompressed,n,ia,ja,done);
6002:   }
6003:   return(0);
6004: }

6008: /*@C
6009:     MatColoringPatch -Used inside matrix coloring routines that 
6010:     use MatGetRowIJ() and/or MatGetColumnIJ().

6012:     Collective on Mat

6014:     Input Parameters:
6015: +   mat - the matrix
6016: .   ncolors - max color value
6017: .   n   - number of entries in colorarray
6018: -   colorarray - array indicating color for each column

6020:     Output Parameters:
6021: .   iscoloring - coloring generated using colorarray information

6023:     Level: developer

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

6027: @*/
6028: PetscErrorCode  MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6029: {

6037:   MatPreallocated(mat);

6039:   if (!mat->ops->coloringpatch){
6040:     ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);
6041:   } else {
6042:     (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6043:   }
6044:   return(0);
6045: }


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

6053:    Collective on Mat

6055:    Input Parameter:
6056: .  mat - the factored matrix to be reset

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

6065:    Note that one can specify in-place ILU(0) factorization by calling 
6066: .vb
6067:      PCType(pc,PCILU);
6068:      PCFactorSeUseInPlace(pc);
6069: .ve
6070:    or by using the options -pc_type ilu -pc_factor_in_place

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

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

6082:    Level: developer

6084: .seealso: PCFactorSetUseInPlace()

6086:    Concepts: matrices^unfactored

6088: @*/
6089: PetscErrorCode  MatSetUnfactored(Mat mat)
6090: {

6096:   MatPreallocated(mat);
6097:   mat->factor = MAT_FACTOR_NONE;
6098:   if (!mat->ops->setunfactored) return(0);
6099:   (*mat->ops->setunfactored)(mat);
6100:   return(0);
6101: }

6103: /*MC
6104:     MatGetArrayF90 - Accesses a matrix array from Fortran90.

6106:     Synopsis:
6107:     MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6109:     Not collective

6111:     Input Parameter:
6112: .   x - matrix

6114:     Output Parameters:
6115: +   xx_v - the Fortran90 pointer to the array
6116: -   ierr - error code

6118:     Example of Usage: 
6119: .vb
6120:       PetscScalar, pointer xx_v(:)
6121:       ....
6122:       call MatGetArrayF90(x,xx_v,ierr)
6123:       a = xx_v(3)
6124:       call MatRestoreArrayF90(x,xx_v,ierr)
6125: .ve

6127:     Notes:
6128:     Not yet supported for all F90 compilers

6130:     Level: advanced

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

6134:     Concepts: matrices^accessing array

6136: M*/

6138: /*MC
6139:     MatRestoreArrayF90 - Restores a matrix array that has been
6140:     accessed with MatGetArrayF90().

6142:     Synopsis:
6143:     MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)

6145:     Not collective

6147:     Input Parameters:
6148: +   x - matrix
6149: -   xx_v - the Fortran90 pointer to the array

6151:     Output Parameter:
6152: .   ierr - error code

6154:     Example of Usage: 
6155: .vb
6156:        PetscScalar, pointer xx_v(:)
6157:        ....
6158:        call MatGetArrayF90(x,xx_v,ierr)
6159:        a = xx_v(3)
6160:        call MatRestoreArrayF90(x,xx_v,ierr)
6161: .ve
6162:    
6163:     Notes:
6164:     Not yet supported for all F90 compilers

6166:     Level: advanced

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

6170: M*/


6175: /*@
6176:     MatGetSubMatrix - Gets a single submatrix on the same number of processors
6177:                       as the original matrix.

6179:     Collective on Mat

6181:     Input Parameters:
6182: +   mat - the original matrix
6183: .   isrow - rows this processor should obtain
6184: .   iscol - columns for all processors you wish to keep
6185: .   csize - number of columns "local" to this processor (does nothing for sequential 
6186:             matrices). This should match the result from VecGetLocalSize(x,...) if you 
6187:             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6188: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6190:     Output Parameter:
6191: .   newmat - the new submatrix, of the same type as the old

6193:     Level: advanced

6195:     Notes: the iscol argument MUST be the same on each processor. You might be 
6196:     able to create the iscol argument with ISAllGather(). The rows is isrow will be
6197:     sorted into the same order as the original matrix.

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

6205:     The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
6206:     the input matrix.

6208:     If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran), you should
6209:     use csize = PETSC_DECIDE also in this case.

6211:     Concepts: matrices^submatrices

6213: .seealso: MatGetSubMatrices(), ISAllGather()
6214: @*/
6215: PetscErrorCode  MatGetSubMatrix(Mat mat,IS isrow,IS iscol,PetscInt csize,MatReuse cll,Mat *newmat)
6216: {
6218:   PetscMPIInt    size;
6219:   Mat            *local;
6220:   IS             iscoltmp;

6229:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6230:   MatPreallocated(mat);
6231:   MPI_Comm_size(((PetscObject)mat)->comm,&size);

6233:   if (!iscol) {
6234:     if (csize == PETSC_DECIDE) csize = mat->cmap->n;
6235:     ISCreateStride(((PetscObject)mat)->comm,mat->cmap->N,0,1,&iscoltmp);
6236:   } else {
6237:     iscoltmp = iscol;
6238:   }

6240:   /* if original matrix is on just one processor then use submatrix generated */
6241:   if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
6242:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
6243:     if (!iscol) {ISDestroy(iscoltmp);}
6244:     return(0);
6245:   } else if (!mat->ops->getsubmatrix && size == 1) {
6246:     MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
6247:     *newmat = *local;
6248:     PetscFree(local);
6249:     if (!iscol) {ISDestroy(iscoltmp);}
6250:     return(0);
6251:   }

6253:   if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6254:   (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,csize,cll,newmat);
6255:   if (!iscol) {ISDestroy(iscoltmp);}
6256:   PetscObjectStateIncrease((PetscObject)*newmat);
6257:   return(0);
6258: }

6262: /*@
6263:     MatGetSubMatrixRaw - Gets a single submatrix on the same number of processors
6264:                          as the original matrix.

6266:     Collective on Mat

6268:     Input Parameters:
6269: +   mat - the original matrix
6270: .   nrows - the number of rows this processor should obtain
6271: .   rows - rows this processor should obtain
6272: .   ncols - the number of columns for all processors you wish to keep
6273: .   cols - columns for all processors you wish to keep
6274: .   csize - number of columns "local" to this processor (does nothing for sequential 
6275:             matrices). This should match the result from VecGetLocalSize(x,...) if you 
6276:             plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE
6277: -   cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

6279:     Output Parameter:
6280: .   newmat - the new submatrix, of the same type as the old

6282:     Level: advanced

6284:     Notes: the iscol argument MUST be the same on each processor. You might be 
6285:     able to create the iscol argument with ISAllGather().

6287:       The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
6288:    the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
6289:    to this routine with a mat of the same nonzero structure and with a cll of MAT_REUSE_MATRIX  
6290:    will reuse the matrix generated the first time.

6292:     Concepts: matrices^submatrices

6294: .seealso: MatGetSubMatrices(), ISAllGather()
6295: @*/
6296: PetscErrorCode  MatGetSubMatrixRaw(Mat mat,PetscInt nrows,const PetscInt rows[],PetscInt ncols,const PetscInt cols[],PetscInt csize,MatReuse cll,Mat *newmat)
6297: {
6298:   IS             isrow, iscol;

6308:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6309:   MatPreallocated(mat);
6310:   ISCreateGeneralWithArray(PETSC_COMM_SELF, nrows, (PetscInt *) rows, &isrow);
6311:   ISCreateGeneralWithArray(PETSC_COMM_SELF, ncols, (PetscInt *) cols, &iscol);
6312:   MatGetSubMatrix(mat, isrow, iscol, csize, cll, newmat);
6313:   ISDestroy(isrow);
6314:   ISDestroy(iscol);
6315:   return(0);
6316: }

6320: /*@
6321:    MatStashSetInitialSize - sets the sizes of the matrix stash, that is
6322:    used during the assembly process to store values that belong to 
6323:    other processors.

6325:    Not Collective

6327:    Input Parameters:
6328: +  mat   - the matrix
6329: .  size  - the initial size of the stash.
6330: -  bsize - the initial size of the block-stash(if used).

6332:    Options Database Keys:
6333: +   -matstash_initial_size <size> or <size0,size1,...sizep-1>
6334: -   -matstash_block_initial_size <bsize>  or <bsize0,bsize1,...bsizep-1>

6336:    Level: intermediate

6338:    Notes: 
6339:      The block-stash is used for values set with MatSetValuesBlocked() while
6340:      the stash is used for values set with MatSetValues()

6342:      Run with the option -info and look for output of the form
6343:      MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
6344:      to determine the appropriate value, MM, to use for size and 
6345:      MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
6346:      to determine the value, BMM to use for bsize

6348:    Concepts: stash^setting matrix size
6349:    Concepts: matrices^stash

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

6353: @*/
6354: PetscErrorCode  MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
6355: {

6361:   MatStashSetInitialSize_Private(&mat->stash,size);
6362:   MatStashSetInitialSize_Private(&mat->bstash,bsize);
6363:   return(0);
6364: }

6368: /*@
6369:    MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 
6370:      the matrix

6372:    Collective on Mat

6374:    Input Parameters:
6375: +  mat   - the matrix
6376: .  x,y - the vectors
6377: -  w - where the result is stored

6379:    Level: intermediate

6381:    Notes: 
6382:     w may be the same vector as y. 

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

6387:     Concepts: interpolation

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

6391: @*/
6392: PetscErrorCode  MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
6393: {
6395:   PetscInt       M,N;

6403:   MatPreallocated(A);
6404:   MatGetSize(A,&M,&N);
6405:   if (N > M) {
6406:     MatMultTransposeAdd(A,x,y,w);
6407:   } else {
6408:     MatMultAdd(A,x,y,w);
6409:   }
6410:   return(0);
6411: }

6415: /*@
6416:    MatInterpolate - y = A*x or A'*x depending on the shape of 
6417:      the matrix

6419:    Collective on Mat

6421:    Input Parameters:
6422: +  mat   - the matrix
6423: -  x,y - the vectors

6425:    Level: intermediate

6427:    Notes: 
6428:     This allows one to use either the restriction or interpolation (its transpose)
6429:     matrix to do the interpolation

6431:    Concepts: matrices^interpolation

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

6435: @*/
6436: PetscErrorCode  MatInterpolate(Mat A,Vec x,Vec y)
6437: {
6439:   PetscInt       M,N;

6446:   MatPreallocated(A);
6447:   MatGetSize(A,&M,&N);
6448:   if (N > M) {
6449:     MatMultTranspose(A,x,y);
6450:   } else {
6451:     MatMult(A,x,y);
6452:   }
6453:   return(0);
6454: }

6458: /*@
6459:    MatRestrict - y = A*x or A'*x

6461:    Collective on Mat

6463:    Input Parameters:
6464: +  mat   - the matrix
6465: -  x,y - the vectors

6467:    Level: intermediate

6469:    Notes: 
6470:     This allows one to use either the restriction or interpolation (its transpose)
6471:     matrix to do the restriction

6473:    Concepts: matrices^restriction

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

6477: @*/
6478: PetscErrorCode  MatRestrict(Mat A,Vec x,Vec y)
6479: {
6481:   PetscInt       M,N;

6488:   MatPreallocated(A);

6490:   MatGetSize(A,&M,&N);
6491:   if (N > M) {
6492:     MatMult(A,x,y);
6493:   } else {
6494:     MatMultTranspose(A,x,y);
6495:   }
6496:   return(0);
6497: }

6501: /*@
6502:    MatNullSpaceAttach - attaches a null space to a matrix.
6503:         This null space will be removed from the resulting vector whenever
6504:         MatMult() is called

6506:    Collective on Mat

6508:    Input Parameters:
6509: +  mat - the matrix
6510: -  nullsp - the null space object

6512:    Level: developer

6514:    Notes:
6515:       Overwrites any previous null space that may have been attached

6517:    Concepts: null space^attaching to matrix

6519: .seealso: MatCreate(), MatNullSpaceCreate()
6520: @*/
6521: PetscErrorCode  MatNullSpaceAttach(Mat mat,MatNullSpace nullsp)
6522: {

6529:   MatPreallocated(mat);
6530:   PetscObjectReference((PetscObject)nullsp);
6531:   if (mat->nullsp) { MatNullSpaceDestroy(mat->nullsp); }
6532:   mat->nullsp = nullsp;
6533:   return(0);
6534: }

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

6541:    Collective on Mat

6543:    Input Parameters:
6544: +  mat - the matrix
6545: .  row - row/column permutation
6546: .  fill - expected fill factor >= 1.0
6547: -  level - level of fill, for ICC(k)

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

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

6557:    Level: developer

6559:    Concepts: matrices^incomplete Cholesky factorization
6560:    Concepts: Cholesky factorization

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

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

6567: @*/
6568: PetscErrorCode  MatICCFactor(Mat mat,IS row,const MatFactorInfo* info)
6569: {

6577:   if (mat->rmap->N != mat->cmap->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square");
6578:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6579:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6580:   if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6581:   MatPreallocated(mat);
6582:   (*mat->ops->iccfactor)(mat,row,info);
6583:   PetscObjectStateIncrease((PetscObject)mat);
6584:   return(0);
6585: }

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

6592:    Not Collective

6594:    Input Parameters:
6595: +  mat - the matrix
6596: -  v - the values compute with ADIC

6598:    Level: developer

6600:    Notes:
6601:      Must call MatSetColoring() before using this routine. Also this matrix must already
6602:      have its nonzero pattern determined.

6604: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6605:           MatSetValues(), MatSetColoring(), MatSetValuesAdifor()
6606: @*/
6607: PetscErrorCode  MatSetValuesAdic(Mat mat,void *v)
6608: {


6616:   if (!mat->assembled) {
6617:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6618:   }
6619:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6620:   if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6621:   (*mat->ops->setvaluesadic)(mat,v);
6622:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6623:   MatView_Private(mat);
6624:   PetscObjectStateIncrease((PetscObject)mat);
6625:   return(0);
6626: }


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

6634:    Not Collective

6636:    Input Parameters:
6637: +  mat - the matrix
6638: -  coloring - the coloring

6640:    Level: developer

6642: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6643:           MatSetValues(), MatSetValuesAdic()
6644: @*/
6645: PetscErrorCode  MatSetColoring(Mat mat,ISColoring coloring)
6646: {


6654:   if (!mat->assembled) {
6655:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6656:   }
6657:   if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6658:   (*mat->ops->setcoloring)(mat,coloring);
6659:   return(0);
6660: }

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

6667:    Not Collective

6669:    Input Parameters:
6670: +  mat - the matrix
6671: .  nl - leading dimension of v
6672: -  v - the values compute with ADIFOR

6674:    Level: developer

6676:    Notes:
6677:      Must call MatSetColoring() before using this routine. Also this matrix must already
6678:      have its nonzero pattern determined.

6680: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
6681:           MatSetValues(), MatSetColoring()
6682: @*/
6683: PetscErrorCode  MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
6684: {


6692:   if (!mat->assembled) {
6693:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6694:   }
6695:   PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
6696:   if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6697:   (*mat->ops->setvaluesadifor)(mat,nl,v);
6698:   PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
6699:   PetscObjectStateIncrease((PetscObject)mat);
6700:   return(0);
6701: }

6705: /*@ 
6706:    MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 
6707:          ghosted ones.

6709:    Not Collective

6711:    Input Parameters:
6712: +  mat - the matrix
6713: -  diag = the diagonal values, including ghost ones

6715:    Level: developer

6717:    Notes: Works only for MPIAIJ and MPIBAIJ matrices
6718:       
6719: .seealso: MatDiagonalScale()
6720: @*/
6721: PetscErrorCode  MatDiagonalScaleLocal(Mat mat,Vec diag)
6722: {
6724:   PetscMPIInt    size;


6731:   if (!mat->assembled) {
6732:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
6733:   }
6734:   PetscLogEventBegin(MAT_Scale,mat,0,0,0);
6735:   MPI_Comm_size(((PetscObject)mat)->comm,&size);
6736:   if (size == 1) {
6737:     PetscInt n,m;
6738:     VecGetSize(diag,&n);
6739:     MatGetSize(mat,0,&m);
6740:     if (m == n) {
6741:       MatDiagonalScale(mat,0,diag);
6742:     } else {
6743:       SETERRQ(PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
6744:     }
6745:   } else {
6746:     PetscErrorCode (*f)(Mat,Vec);
6747:     PetscObjectQueryFunction((PetscObject)mat,"MatDiagonalScaleLocal_C",(void (**)(void))&f);
6748:     if (f) {
6749:       (*f)(mat,diag);
6750:     } else {
6751:       SETERRQ(PETSC_ERR_SUP,"Only supported for MPIAIJ and MPIBAIJ parallel matrices");
6752:     }
6753:   }
6754:   PetscLogEventEnd(MAT_Scale,mat,0,0,0);
6755:   PetscObjectStateIncrease((PetscObject)mat);
6756:   return(0);
6757: }

6761: /*@ 
6762:    MatGetInertia - Gets the inertia from a factored matrix

6764:    Collective on Mat

6766:    Input Parameter:
6767: .  mat - the matrix

6769:    Output Parameters:
6770: +   nneg - number of negative eigenvalues
6771: .   nzero - number of zero eigenvalues
6772: -   npos - number of positive eigenvalues

6774:    Level: advanced

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


6779: @*/
6780: PetscErrorCode  MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
6781: {

6787:   if (!mat->factor)    SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
6788:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
6789:   if (!mat->ops->getinertia) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6790:   (*mat->ops->getinertia)(mat,nneg,nzero,npos);
6791:   return(0);
6792: }

6794: /* ----------------------------------------------------------------*/
6797: /*@C
6798:    MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors

6800:    Collective on Mat and Vecs

6802:    Input Parameters:
6803: +  mat - the factored matrix
6804: -  b - the right-hand-side vectors

6806:    Output Parameter:
6807: .  x - the result vectors

6809:    Notes:
6810:    The vectors b and x cannot be the same.  I.e., one cannot
6811:    call MatSolves(A,x,x).

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

6818:    Level: developer

6820:    Concepts: matrices^triangular solves

6822: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
6823: @*/
6824: PetscErrorCode  MatSolves(Mat mat,Vecs b,Vecs x)
6825: {

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

6835:   if (!mat->ops->solves) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6836:   MatPreallocated(mat);
6837:   PetscLogEventBegin(MAT_Solves,mat,0,0,0);
6838:   (*mat->ops->solves)(mat,b,x);
6839:   PetscLogEventEnd(MAT_Solves,mat,0,0,0);
6840:   return(0);
6841: }

6845: /*@
6846:    MatIsSymmetric - Test whether a matrix is symmetric

6848:    Collective on Mat

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

6854:    Output Parameters:
6855: .  flg - the result

6857:    Level: intermediate

6859:    Concepts: matrix^symmetry

6861: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6862: @*/
6863: PetscErrorCode  MatIsSymmetric(Mat A,PetscReal tol,PetscTruth *flg)
6864: {

6870:   if (!A->symmetric_set) {
6871:     if (!A->ops->issymmetric) {
6872:       const MatType mattype;
6873:       MatGetType(A,&mattype);
6874:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
6875:     }
6876:     (*A->ops->issymmetric)(A,tol,&A->symmetric);
6877:     A->symmetric_set = PETSC_TRUE;
6878:     if (A->symmetric) {
6879:       A->structurally_symmetric_set = PETSC_TRUE;
6880:       A->structurally_symmetric     = PETSC_TRUE;
6881:     }
6882:   }
6883:   *flg = A->symmetric;
6884:   return(0);
6885: }

6889: /*@
6890:    MatIsHermitian - Test whether a matrix is Hermitian

6892:    Collective on Mat

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

6898:    Output Parameters:
6899: .  flg - the result

6901:    Level: intermediate

6903:    Concepts: matrix^symmetry

6905: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
6906: @*/
6907: PetscErrorCode  MatIsHermitian(Mat A,PetscReal tol,PetscTruth *flg)
6908: {

6914:   if (!A->hermitian_set) {
6915:     if (!A->ops->ishermitian) {
6916:       const MatType mattype;
6917:       MatGetType(A,&mattype);
6918:       SETERRQ1(PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for Hermitian",mattype);
6919:     }
6920:     (*A->ops->ishermitian)(A,tol,&A->hermitian);
6921:     A->hermitian_set = PETSC_TRUE;
6922:     if (A->hermitian) {
6923:       A->structurally_symmetric_set = PETSC_TRUE;
6924:       A->structurally_symmetric     = PETSC_TRUE;
6925:     }
6926:   }
6927:   *flg = A->hermitian;
6928:   return(0);
6929: }

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

6936:    Collective on Mat

6938:    Input Parameter:
6939: .  A - the matrix to check

6941:    Output Parameters:
6942: +  set - if the symmetric flag is set (this tells you if the next flag is valid)
6943: -  flg - the result

6945:    Level: advanced

6947:    Concepts: matrix^symmetry

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

6952: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6953: @*/
6954: PetscErrorCode  MatIsSymmetricKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6955: {
6960:   if (A->symmetric_set) {
6961:     *set = PETSC_TRUE;
6962:     *flg = A->symmetric;
6963:   } else {
6964:     *set = PETSC_FALSE;
6965:   }
6966:   return(0);
6967: }

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

6974:    Collective on Mat

6976:    Input Parameter:
6977: .  A - the matrix to check

6979:    Output Parameters:
6980: +  set - if the hermitian flag is set (this tells you if the next flag is valid)
6981: -  flg - the result

6983:    Level: advanced

6985:    Concepts: matrix^symmetry

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

6990: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
6991: @*/
6992: PetscErrorCode  MatIsHermitianKnown(Mat A,PetscTruth *set,PetscTruth *flg)
6993: {
6998:   if (A->hermitian_set) {
6999:     *set = PETSC_TRUE;
7000:     *flg = A->hermitian;
7001:   } else {
7002:     *set = PETSC_FALSE;
7003:   }
7004:   return(0);
7005: }

7009: /*@
7010:    MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric

7012:    Collective on Mat

7014:    Input Parameter:
7015: .  A - the matrix to test

7017:    Output Parameters:
7018: .  flg - the result

7020:    Level: intermediate

7022:    Concepts: matrix^symmetry

7024: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
7025: @*/
7026: PetscErrorCode  MatIsStructurallySymmetric(Mat A,PetscTruth *flg)
7027: {

7033:   if (!A->structurally_symmetric_set) {
7034:     if (!A->ops->isstructurallysymmetric) SETERRQ(PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
7035:     (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
7036:     A->structurally_symmetric_set = PETSC_TRUE;
7037:   }
7038:   *flg = A->structurally_symmetric;
7039:   return(0);
7040: }

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

7049:     Not collective

7051:    Input Parameter:
7052: .   vec - the vector

7054:    Output Parameters:
7055: +   nstash   - the size of the stash
7056: .   reallocs - the number of additional mallocs incurred.
7057: .   bnstash   - the size of the block stash
7058: -   breallocs - the number of additional mallocs incurred.in the block stash
7059:  
7060:    Level: advanced

7062: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
7063:   
7064: @*/
7065: PetscErrorCode  MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
7066: {
7069:   MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
7070:   MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
7071:   return(0);
7072: }

7076: /*@C
7077:    MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 
7078:      parallel layout
7079:    
7080:    Collective on Mat

7082:    Input Parameter:
7083: .  mat - the matrix

7085:    Output Parameter:
7086: +   right - (optional) vector that the matrix can be multiplied against
7087: -   left - (optional) vector that the matrix vector product can be stored in

7089:   Level: advanced

7091: .seealso: MatCreate()
7092: @*/
7093: PetscErrorCode  MatGetVecs(Mat mat,Vec *right,Vec *left)
7094: {

7100:   MatPreallocated(mat);
7101:   if (mat->ops->getvecs) {
7102:     (*mat->ops->getvecs)(mat,right,left);
7103:   } else {
7104:     PetscMPIInt size;
7105:     MPI_Comm_size(((PetscObject)mat)->comm, &size);
7106:     if (right) {
7107:       VecCreate(((PetscObject)mat)->comm,right);
7108:       VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
7109:       VecSetBlockSize(*right,mat->rmap->bs);
7110:       if (size > 1) {
7111:         /* New vectors uses Mat cmap and does not create a new one */
7112:         PetscMapDestroy((*right)->map);
7113:         (*right)->map = mat->cmap;
7114:         mat->cmap->refcnt++;

7116:         VecSetType(*right,VECMPI);
7117:       } else {VecSetType(*right,VECSEQ);}
7118:     }
7119:     if (left) {
7120:       VecCreate(((PetscObject)mat)->comm,left);
7121:       VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
7122:       VecSetBlockSize(*left,mat->rmap->bs);
7123:       if (size > 1) {
7124:         /* New vectors uses Mat rmap and does not create a new one */
7125:         PetscMapDestroy((*left)->map);
7126:         (*left)->map = mat->rmap;
7127:         mat->rmap->refcnt++;

7129:         VecSetType(*left,VECMPI);
7130:       } else {VecSetType(*left,VECSEQ);}
7131:     }
7132:   }
7133:   if (mat->mapping) {
7134:     if (right) {VecSetLocalToGlobalMapping(*right,mat->mapping);}
7135:     if (left) {VecSetLocalToGlobalMapping(*left,mat->mapping);}
7136:   }
7137:   if (mat->bmapping) {
7138:     if (right) {VecSetLocalToGlobalMappingBlock(*right,mat->bmapping);}
7139:     if (left) {VecSetLocalToGlobalMappingBlock(*left,mat->bmapping);}
7140:   }
7141:   return(0);
7142: }

7146: /*@C
7147:    MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
7148:      with default values.

7150:    Not Collective

7152:    Input Parameters:
7153: .    info - the MatFactorInfo data structure


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

7159:    Level: developer

7161: .seealso: MatFactorInfo

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

7166: @*/

7168: PetscErrorCode  MatFactorInfoInitialize(MatFactorInfo *info)
7169: {

7173:   PetscMemzero(info,sizeof(MatFactorInfo));
7174:   return(0);
7175: }

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

7182:    Collective on Mat

7184:    Input Parameters:
7185: +  A - the matrix
7186: .  P - the projection matrix
7187: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7188: -  fill - expected fill as ratio of nnz(C)/nnz(A) 

7190:    Output Parameters:
7191: .  C - the product matrix

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

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

7199:    Level: intermediate

7201: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult()
7202: @*/
7203: PetscErrorCode  MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
7204: {

7210:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7211:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7214:   MatPreallocated(P);
7215:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7216:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7218:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7219:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7220:   MatPreallocated(A);

7222:   PetscLogEventBegin(MAT_PtAP,A,P,0,0);
7223:   (*A->ops->ptap)(A,P,scall,fill,C);
7224:   PetscLogEventEnd(MAT_PtAP,A,P,0,0);

7226:   return(0);
7227: }

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

7234:    Collective on Mat

7236:    Input Parameters:
7237: +  A - the matrix
7238: -  P - the projection matrix

7240:    Output Parameters:
7241: .  C - the product matrix

7243:    Notes:
7244:    C must have been created by calling MatPtAPSymbolic and must be destroyed by
7245:    the user using MatDeatroy().

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

7250:    Level: intermediate

7252: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
7253: @*/
7254: PetscErrorCode  MatPtAPNumeric(Mat A,Mat P,Mat C)
7255: {

7261:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7262:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7265:   MatPreallocated(P);
7266:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7267:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7270:   MatPreallocated(C);
7271:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7272:   if (P->cmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N);
7273:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7274:   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);
7275:   if (P->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N);
7276:   MatPreallocated(A);

7278:   PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
7279:   (*A->ops->ptapnumeric)(A,P,C);
7280:   PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
7281:   return(0);
7282: }

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

7289:    Collective on Mat

7291:    Input Parameters:
7292: +  A - the matrix
7293: -  P - the projection matrix

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

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

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

7305:    Level: intermediate

7307: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
7308: @*/
7309: PetscErrorCode  MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
7310: {

7316:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7317:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7318:   if (fill <1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7321:   MatPreallocated(P);
7322:   if (!P->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7323:   if (P->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7326:   if (P->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N);
7327:   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);
7328:   MatPreallocated(A);
7329:   PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
7330:   (*A->ops->ptapsymbolic)(A,P,fill,C);
7331:   PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);

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

7335:   return(0);
7336: }

7340: /*@
7341:    MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.

7343:    Collective on Mat

7345:    Input Parameters:
7346: +  A - the left matrix
7347: .  B - the right matrix
7348: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7349: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
7350:           if the result is a dense matrix this is irrelevent

7352:    Output Parameters:
7353: .  C - the product matrix

7355:    Notes:
7356:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

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

7368:    Level: intermediate

7370: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatPtAP()
7371: @*/
7372: PetscErrorCode  MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7373: {
7375:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7376:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
7377:   PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL;

7382:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7383:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7386:   MatPreallocated(B);
7387:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7388:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7390:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7391:   if (scall == MAT_REUSE_MATRIX){
7394:   }
7395:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7396:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
7397:   MatPreallocated(A);

7399:   fA = A->ops->matmult;
7400:   fB = B->ops->matmult;
7401:   if (fB == fA) {
7402:     if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
7403:     mult = fB;
7404:   } else {
7405:     /* dispatch based on the type of A and B */
7406:     char  multname[256];
7407:     PetscStrcpy(multname,"MatMatMult_");
7408:     PetscStrcat(multname,((PetscObject)A)->type_name);
7409:     PetscStrcat(multname,"_");
7410:     PetscStrcat(multname,((PetscObject)B)->type_name);
7411:     PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
7412:     PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);
7413:     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);
7414:   }
7415:   PetscLogEventBegin(MAT_MatMult,A,B,0,0);
7416:   (*mult)(A,B,scall,fill,C);
7417:   PetscLogEventEnd(MAT_MatMult,A,B,0,0);
7418:   return(0);
7419: }

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

7427:    Collective on Mat

7429:    Input Parameters:
7430: +  A - the left matrix
7431: .  B - the right matrix
7432: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
7433:       if C is a dense matrix this is irrelevent
7434:  
7435:    Output Parameters:
7436: .  C - the product matrix

7438:    Notes:
7439:    Unless scall is MAT_REUSE_MATRIX C will be created.

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

7444:    This routine is currently implemented for 
7445:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
7446:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7447:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7449:    Level: intermediate

7451: .seealso: MatMatMult(), MatMatMultNumeric()
7452: @*/
7453: PetscErrorCode  MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
7454: {
7456:   PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *);
7457:   PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *);
7458:   PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL;

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

7468:   MatPreallocated(B);
7469:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7470:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7473:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7474:   if (fill == PETSC_DEFAULT) fill = 2.0;
7475:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7476:   MatPreallocated(A);
7477: 
7478:   Asymbolic = A->ops->matmultsymbolic;
7479:   Bsymbolic = B->ops->matmultsymbolic;
7480:   if (Asymbolic == Bsymbolic){
7481:     if (!Bsymbolic) SETERRQ1(PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
7482:     symbolic = Bsymbolic;
7483:   } else { /* dispatch based on the type of A and B */
7484:     char  symbolicname[256];
7485:     PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
7486:     PetscStrcat(symbolicname,((PetscObject)A)->type_name);
7487:     PetscStrcat(symbolicname,"_");
7488:     PetscStrcat(symbolicname,((PetscObject)B)->type_name);
7489:     PetscStrcat(symbolicname,"_C");
7490:     PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);
7491:     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);
7492:   }
7493:   PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
7494:   (*symbolic)(A,B,fill,C);
7495:   PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
7496:   return(0);
7497: }

7501: /*@
7502:    MatMatMultNumeric - Performs the numeric matrix-matrix product.
7503:    Call this routine after first calling MatMatMultSymbolic().

7505:    Collective on Mat

7507:    Input Parameters:
7508: +  A - the left matrix
7509: -  B - the right matrix

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

7514:    Notes:
7515:    C must have been created with MatMatMultSymbolic().

7517:    This routine is currently implemented for 
7518:     - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
7519:     - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
7520:     - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.

7522:    Level: intermediate

7524: .seealso: MatMatMult(), MatMatMultSymbolic()
7525: @*/
7526: PetscErrorCode  MatMatMultNumeric(Mat A,Mat B,Mat C)
7527: {
7529:   PetscErrorCode (*Anumeric)(Mat,Mat,Mat);
7530:   PetscErrorCode (*Bnumeric)(Mat,Mat,Mat);
7531:   PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL;

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

7541:   MatPreallocated(B);
7542:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7543:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7547:   MatPreallocated(C);
7548:   if (!C->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7549:   if (C->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");

7551:   if (B->cmap->N!=C->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N);
7552:   if (B->rmap->N!=A->cmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N);
7553:   if (A->rmap->N!=C->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N);
7554:   MatPreallocated(A);

7556:   Anumeric = A->ops->matmultnumeric;
7557:   Bnumeric = B->ops->matmultnumeric;
7558:   if (Anumeric == Bnumeric){
7559:     if (!Bnumeric) SETERRQ1(PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name);
7560:     numeric = Bnumeric;
7561:   } else {
7562:     char  numericname[256];
7563:     PetscStrcpy(numericname,"MatMatMultNumeric_");
7564:     PetscStrcat(numericname,((PetscObject)A)->type_name);
7565:     PetscStrcat(numericname,"_");
7566:     PetscStrcat(numericname,((PetscObject)B)->type_name);
7567:     PetscStrcat(numericname,"_C");
7568:     PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);
7569:     if (!numeric)
7570:       SETERRQ2(PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);
7571:   }
7572:   PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
7573:   (*numeric)(A,B,C);
7574:   PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
7575:   return(0);
7576: }

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

7583:    Collective on Mat

7585:    Input Parameters:
7586: +  A - the left matrix
7587: .  B - the right matrix
7588: .  scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7589: -  fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known

7591:    Output Parameters:
7592: .  C - the product matrix

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

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

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

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

7605:    Level: intermediate

7607: .seealso: MatMatMultTransposeSymbolic(), MatMatMultTransposeNumeric(), MatPtAP()
7608: @*/
7609: PetscErrorCode  MatMatMultTranspose(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
7610: {
7612:   PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
7613:   PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);

7618:   if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7619:   if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7622:   MatPreallocated(B);
7623:   if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7624:   if (B->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7626:   if (B->rmap->N!=A->rmap->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N);
7627:   if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
7628:   if (fill < 1.0) SETERRQ1(PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
7629:   MatPreallocated(A);

7631:   fA = A->ops->matmulttranspose;
7632:   if (!fA) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for A of type %s",((PetscObject)A)->type_name);
7633:   fB = B->ops->matmulttranspose;
7634:   if (!fB) SETERRQ1(PETSC_ERR_SUP,"MatMatMultTranspose not supported for B of type %s",((PetscObject)B)->type_name);
7635:   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);

7637:   PetscLogEventBegin(MAT_MatMultTranspose,A,B,0,0);
7638:   (*A->ops->matmulttranspose)(A,B,scall,fill,C);
7639:   PetscLogEventEnd(MAT_MatMultTranspose,A,B,0,0);
7640: 
7641:   return(0);
7642: }

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

7649:    Collective on Mat

7651:    Input Parameters:
7652: +  mat - the matrix
7653: .  nsubcomm - the number of subcommunicators (= number of redundant pareallel or sequential matrices)
7654: .  subcomm - MPI communicator split from the communicator where mat resides in
7655: .  mlocal_red - number of local rows of the redundant matrix
7656: -  reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX

7658:    Output Parameter:
7659: .  matredundant - redundant matrix

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

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

7668:    Only MPIAIJ matrix is supported. 
7669:    
7670:    Level: advanced

7672:    Concepts: subcommunicator
7673:    Concepts: duplicate matrix

7675: .seealso: MatDestroy()
7676: @*/
7677: PetscErrorCode  MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
7678: {

7683:   if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
7686:   }
7687:   if (!mat->ops->getredundantmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7688:   if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7689:   if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7690:   MatPreallocated(mat);

7692:   PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
7693:   (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
7694:   PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
7695:   return(0);
7696: }