1 /*$Id: matrix.c,v 1.414 2001/09/28 18:57:28 balay Exp $*/ 2 3 /* 4 This is where the abstract matrix operations are defined 5 */ 6 7 #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 8 #include "src/vec/vecimpl.h" 9 10 /* Logging support */ 11 int MAT_COOKIE; 12 int MATSNESMFCTX_COOKIE; 13 int MAT_Mult, MAT_MultMatrixFree, MAT_MultMultiple, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 14 int MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_SolveMultiple, MAT_SolveAdd, MAT_SolveTranspose; 15 int MAT_SolveTransposeAdd, MAT_Relax, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 16 int MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 17 int MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 18 int MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering; 19 int MAT_IncreaseOverlap, MAT_Partitioning, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 20 int MAT_FDColoringApply,MAT_Transpose; 21 22 #undef __FUNCT__ 23 #define __FUNCT__ "MatGetRow" 24 /*@C 25 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 26 for each row that you get to ensure that your application does 27 not bleed memory. 28 29 Not Collective 30 31 Input Parameters: 32 + mat - the matrix 33 - row - the row to get 34 35 Output Parameters: 36 + ncols - the number of nonzeros in the row 37 . cols - if not NULL, the column numbers 38 - vals - if not NULL, the values 39 40 Notes: 41 This routine is provided for people who need to have direct access 42 to the structure of a matrix. We hope that we provide enough 43 high-level matrix routines that few users will need it. 44 45 MatGetRow() always returns 0-based column indices, regardless of 46 whether the internal representation is 0-based (default) or 1-based. 47 48 For better efficiency, set cols and/or vals to PETSC_NULL if you do 49 not wish to extract these quantities. 50 51 The user can only examine the values extracted with MatGetRow(); 52 the values cannot be altered. To change the matrix entries, one 53 must use MatSetValues(). 54 55 You can only have one call to MatGetRow() outstanding for a particular 56 matrix at a time, per processor. MatGetRow() can only obtained rows 57 associated with the given processor, it cannot get rows from the 58 other processors; for that we suggest using MatGetSubMatrices(), then 59 MatGetRow() on the submatrix. The row indix passed to MatGetRows() 60 is in the global number of rows. 61 62 Fortran Notes: 63 The calling sequence from Fortran is 64 .vb 65 MatGetRow(matrix,row,ncols,cols,values,ierr) 66 Mat matrix (input) 67 integer row (input) 68 integer ncols (output) 69 integer cols(maxcols) (output) 70 double precision (or double complex) values(maxcols) output 71 .ve 72 where maxcols >= maximum nonzeros in any row of the matrix. 73 74 Caution: 75 Do not try to change the contents of the output arrays (cols and vals). 76 In some cases, this may corrupt the matrix. 77 78 Level: advanced 79 80 Concepts: matrices^row access 81 82 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubmatrices(), MatGetDiagonal() 83 @*/ 84 int MatGetRow(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals) 85 { 86 int ierr; 87 88 PetscFunctionBegin; 89 PetscValidHeaderSpecific(mat,MAT_COOKIE); 90 PetscValidIntPointer(ncols); 91 PetscValidType(mat); 92 MatPreallocated(mat); 93 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 94 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 95 if (!mat->ops->getrow) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 96 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 97 ierr = (*mat->ops->getrow)(mat,row,ncols,cols,vals);CHKERRQ(ierr); 98 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 #undef __FUNCT__ 103 #define __FUNCT__ "MatRestoreRow" 104 /*@C 105 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 106 107 Not Collective 108 109 Input Parameters: 110 + mat - the matrix 111 . row - the row to get 112 . ncols, cols - the number of nonzeros and their columns 113 - vals - if nonzero the column values 114 115 Notes: 116 This routine should be called after you have finished examining the entries. 117 118 Fortran Notes: 119 The calling sequence from Fortran is 120 .vb 121 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 122 Mat matrix (input) 123 integer row (input) 124 integer ncols (output) 125 integer cols(maxcols) (output) 126 double precision (or double complex) values(maxcols) output 127 .ve 128 Where maxcols >= maximum nonzeros in any row of the matrix. 129 130 In Fortran MatRestoreRow() MUST be called after MatGetRow() 131 before another call to MatGetRow() can be made. 132 133 Level: advanced 134 135 .seealso: MatGetRow() 136 @*/ 137 int MatRestoreRow(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals) 138 { 139 int ierr; 140 141 PetscFunctionBegin; 142 PetscValidHeaderSpecific(mat,MAT_COOKIE); 143 PetscValidIntPointer(ncols); 144 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 145 if (!mat->ops->restorerow) PetscFunctionReturn(0); 146 ierr = (*mat->ops->restorerow)(mat,row,ncols,cols,vals);CHKERRQ(ierr); 147 PetscFunctionReturn(0); 148 } 149 150 #undef __FUNCT__ 151 #define __FUNCT__ "MatView" 152 /*@C 153 MatView - Visualizes a matrix object. 154 155 Collective on Mat 156 157 Input Parameters: 158 + mat - the matrix 159 - ptr - visualization context 160 161 Notes: 162 The available visualization contexts include 163 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 164 . PETSC_VIEWER_STDOUT_WORLD - synchronized standard 165 output where only the first processor opens 166 the file. All other processors send their 167 data to the first processor to print. 168 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 169 170 The user can open alternative visualization contexts with 171 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 172 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 173 specified file; corresponding input uses MatLoad() 174 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 175 an X window display 176 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 177 Currently only the sequential dense and AIJ 178 matrix types support the Socket viewer. 179 180 The user can call PetscViewerSetFormat() to specify the output 181 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 182 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 183 + PETSC_VIEWER_ASCII_DEFAULT - default, prints matrix contents 184 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 185 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 186 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 187 format common among all matrix types 188 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 189 format (which is in many cases the same as the default) 190 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 191 size and structure (not the matrix entries) 192 . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 193 the matrix structure 194 195 Options Database Keys: 196 + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly() 197 . -mat_view_info_detailed - Prints more detailed info 198 . -mat_view - Prints matrix in ASCII format 199 . -mat_view_matlab - Prints matrix in Matlab format 200 . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 201 . -display <name> - Sets display name (default is host) 202 . -draw_pause <sec> - Sets number of seconds to pause after display 203 . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual) 204 . -viewer_socket_machine <machine> 205 . -viewer_socket_port <port> 206 . -mat_view_binary - save matrix to file in binary format 207 - -viewer_binary_filename <name> 208 Level: beginner 209 210 Concepts: matrices^viewing 211 Concepts: matrices^plotting 212 Concepts: matrices^printing 213 214 .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 215 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 216 @*/ 217 int MatView(Mat mat,PetscViewer viewer) 218 { 219 int ierr,rows,cols; 220 PetscTruth isascii; 221 char *cstr; 222 PetscViewerFormat format; 223 224 PetscFunctionBegin; 225 PetscValidHeaderSpecific(mat,MAT_COOKIE); 226 PetscValidType(mat); 227 MatPreallocated(mat); 228 if (!viewer) viewer = PETSC_VIEWER_STDOUT_(mat->comm); 229 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE); 230 PetscCheckSameComm(mat,viewer); 231 if (!mat->assembled) SETERRQ(1,"Must call MatAssemblyBegin/End() before viewing matrix"); 232 233 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 234 if (isascii) { 235 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 236 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 237 if (mat->prefix) { 238 ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:(%s)\n",mat->prefix);CHKERRQ(ierr); 239 } else { 240 ierr = PetscViewerASCIIPrintf(viewer,"Matrix Object:\n");CHKERRQ(ierr); 241 } 242 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 243 ierr = MatGetType(mat,&cstr);CHKERRQ(ierr); 244 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 245 ierr = PetscViewerASCIIPrintf(viewer,"type=%s, rows=%d, cols=%d\n",cstr,rows,cols);CHKERRQ(ierr); 246 if (mat->ops->getinfo) { 247 MatInfo info; 248 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 249 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%d, allocated nonzeros=%d\n", 250 (int)info.nz_used,(int)info.nz_allocated);CHKERRQ(ierr); 251 } 252 } 253 } 254 if (mat->ops->view) { 255 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 256 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 257 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 258 } else if (!isascii) { 259 SETERRQ1(1,"Viewer type %s not supported",((PetscObject)viewer)->type_name); 260 } 261 if (isascii) { 262 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 263 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 264 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 265 } 266 } 267 PetscFunctionReturn(0); 268 } 269 270 #undef __FUNCT__ 271 #define __FUNCT__ "MatScaleSystem" 272 /*@C 273 MatScaleSystem - Scale a vector solution and right hand side to 274 match the scaling of a scaled matrix. 275 276 Collective on Mat 277 278 Input Parameter: 279 + mat - the matrix 280 . x - solution vector (or PETSC_NULL) 281 - b - right hand side vector (or PETSC_NULL) 282 283 284 Notes: 285 For AIJ, BAIJ, and BDiag matrix formats, the matrices are not 286 internally scaled, so this does nothing. For MPIROWBS it 287 permutes and diagonally scales. 288 289 The SLES methods automatically call this routine when required 290 (via PCPreSolve()) so it is rarely used directly. 291 292 Level: Developer 293 294 Concepts: matrices^scaling 295 296 .seealso: MatUseScaledForm(), MatUnScaleSystem() 297 @*/ 298 int MatScaleSystem(Mat mat,Vec x,Vec b) 299 { 300 int ierr; 301 302 PetscFunctionBegin; 303 PetscValidHeaderSpecific(mat,MAT_COOKIE); 304 PetscValidType(mat); 305 MatPreallocated(mat); 306 if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);} 307 if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);} 308 309 if (mat->ops->scalesystem) { 310 ierr = (*mat->ops->scalesystem)(mat,x,b);CHKERRQ(ierr); 311 } 312 PetscFunctionReturn(0); 313 } 314 315 #undef __FUNCT__ 316 #define __FUNCT__ "MatUnScaleSystem" 317 /*@C 318 MatUnScaleSystem - Unscales a vector solution and right hand side to 319 match the original scaling of a scaled matrix. 320 321 Collective on Mat 322 323 Input Parameter: 324 + mat - the matrix 325 . x - solution vector (or PETSC_NULL) 326 - b - right hand side vector (or PETSC_NULL) 327 328 329 Notes: 330 For AIJ, BAIJ, and BDiag matrix formats, the matrices are not 331 internally scaled, so this does nothing. For MPIROWBS it 332 permutes and diagonally scales. 333 334 The SLES methods automatically call this routine when required 335 (via PCPreSolve()) so it is rarely used directly. 336 337 Level: Developer 338 339 .seealso: MatUseScaledForm(), MatScaleSystem() 340 @*/ 341 int MatUnScaleSystem(Mat mat,Vec x,Vec b) 342 { 343 int ierr; 344 345 PetscFunctionBegin; 346 PetscValidHeaderSpecific(mat,MAT_COOKIE); 347 PetscValidType(mat); 348 MatPreallocated(mat); 349 if (x) {PetscValidHeaderSpecific(x,VEC_COOKIE);PetscCheckSameComm(mat,x);} 350 if (b) {PetscValidHeaderSpecific(b,VEC_COOKIE);PetscCheckSameComm(mat,b);} 351 if (mat->ops->unscalesystem) { 352 ierr = (*mat->ops->unscalesystem)(mat,x,b);CHKERRQ(ierr); 353 } 354 PetscFunctionReturn(0); 355 } 356 357 #undef __FUNCT__ 358 #define __FUNCT__ "MatUseScaledForm" 359 /*@C 360 MatUseScaledForm - For matrix storage formats that scale the 361 matrix (for example MPIRowBS matrices are diagonally scaled on 362 assembly) indicates matrix operations (MatMult() etc) are 363 applied using the scaled matrix. 364 365 Collective on Mat 366 367 Input Parameter: 368 + mat - the matrix 369 - scaled - PETSC_TRUE for applying the scaled, PETSC_FALSE for 370 applying the original matrix 371 372 Notes: 373 For scaled matrix formats, applying the original, unscaled matrix 374 will be slightly more expensive 375 376 Level: Developer 377 378 .seealso: MatScaleSystem(), MatUnScaleSystem() 379 @*/ 380 int MatUseScaledForm(Mat mat,PetscTruth scaled) 381 { 382 int ierr; 383 384 PetscFunctionBegin; 385 PetscValidHeaderSpecific(mat,MAT_COOKIE); 386 PetscValidType(mat); 387 MatPreallocated(mat); 388 if (mat->ops->usescaledform) { 389 ierr = (*mat->ops->usescaledform)(mat,scaled);CHKERRQ(ierr); 390 } 391 PetscFunctionReturn(0); 392 } 393 394 #undef __FUNCT__ 395 #define __FUNCT__ "MatDestroy" 396 /*@C 397 MatDestroy - Frees space taken by a matrix. 398 399 Collective on Mat 400 401 Input Parameter: 402 . A - the matrix 403 404 Level: beginner 405 406 @*/ 407 int MatDestroy(Mat A) 408 { 409 int ierr; 410 411 PetscFunctionBegin; 412 PetscValidHeaderSpecific(A,MAT_COOKIE); 413 PetscValidType(A); 414 MatPreallocated(A); 415 if (--A->refct > 0) PetscFunctionReturn(0); 416 417 /* if memory was published with AMS then destroy it */ 418 ierr = PetscObjectDepublish(A);CHKERRQ(ierr); 419 if (A->mapping) { 420 ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr); 421 } 422 if (A->bmapping) { 423 ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr); 424 } 425 if (A->rmap) { 426 ierr = PetscMapDestroy(A->rmap);CHKERRQ(ierr); 427 } 428 if (A->cmap) { 429 ierr = PetscMapDestroy(A->cmap);CHKERRQ(ierr); 430 } 431 432 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 433 PetscLogObjectDestroy(A); 434 PetscHeaderDestroy(A); 435 PetscFunctionReturn(0); 436 } 437 438 #undef __FUNCT__ 439 #define __FUNCT__ "MatValid" 440 /*@ 441 MatValid - Checks whether a matrix object is valid. 442 443 Collective on Mat 444 445 Input Parameter: 446 . m - the matrix to check 447 448 Output Parameter: 449 flg - flag indicating matrix status, either 450 PETSC_TRUE if matrix is valid, or PETSC_FALSE otherwise. 451 452 Level: developer 453 454 Concepts: matrices^validity 455 @*/ 456 int MatValid(Mat m,PetscTruth *flg) 457 { 458 PetscFunctionBegin; 459 PetscValidIntPointer(flg); 460 if (!m) *flg = PETSC_FALSE; 461 else if (m->cookie != MAT_COOKIE) *flg = PETSC_FALSE; 462 else *flg = PETSC_TRUE; 463 PetscFunctionReturn(0); 464 } 465 466 #undef __FUNCT__ 467 #define __FUNCT__ "MatSetValues" 468 /*@ 469 MatSetValues - Inserts or adds a block of values into a matrix. 470 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 471 MUST be called after all calls to MatSetValues() have been completed. 472 473 Not Collective 474 475 Input Parameters: 476 + mat - the matrix 477 . v - a logically two-dimensional array of values 478 . m, idxm - the number of rows and their global indices 479 . n, idxn - the number of columns and their global indices 480 - addv - either ADD_VALUES or INSERT_VALUES, where 481 ADD_VALUES adds values to any existing entries, and 482 INSERT_VALUES replaces existing entries with new values 483 484 Notes: 485 By default the values, v, are row-oriented and unsorted. 486 See MatSetOption() for other options. 487 488 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 489 options cannot be mixed without intervening calls to the assembly 490 routines. 491 492 MatSetValues() uses 0-based row and column numbers in Fortran 493 as well as in C. 494 495 Negative indices may be passed in idxm and idxn, these rows and columns are 496 simply ignored. This allows easily inserting element stiffness matrices 497 with homogeneous Dirchlet boundary conditions that you don't want represented 498 in the matrix. 499 500 Efficiency Alert: 501 The routine MatSetValuesBlocked() may offer much better efficiency 502 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 503 504 Level: beginner 505 506 Concepts: matrices^putting entries in 507 508 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 509 @*/ 510 int MatSetValues(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v,InsertMode addv) 511 { 512 int ierr; 513 514 PetscFunctionBegin; 515 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 516 PetscValidHeaderSpecific(mat,MAT_COOKIE); 517 PetscValidType(mat); 518 MatPreallocated(mat); 519 PetscValidIntPointer(idxm); 520 PetscValidIntPointer(idxn); 521 PetscValidScalarPointer(v); 522 if (mat->insertmode == NOT_SET_VALUES) { 523 mat->insertmode = addv; 524 } 525 #if defined(PETSC_USE_BOPT_g) 526 else if (mat->insertmode != addv) { 527 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 528 } 529 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 530 #endif 531 532 if (mat->assembled) { 533 mat->was_assembled = PETSC_TRUE; 534 mat->assembled = PETSC_FALSE; 535 } 536 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 537 if (!mat->ops->setvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 538 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 539 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 540 PetscFunctionReturn(0); 541 } 542 543 #undef __FUNCT__ 544 #define __FUNCT__ "MatSetValuesStencil" 545 /*@C 546 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 547 Using structured grid indexing 548 549 Not Collective 550 551 Input Parameters: 552 + mat - the matrix 553 . v - a logically two-dimensional array of values 554 . m - number of rows being entered 555 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 556 . n - number of columns being entered 557 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 558 - addv - either ADD_VALUES or INSERT_VALUES, where 559 ADD_VALUES adds values to any existing entries, and 560 INSERT_VALUES replaces existing entries with new values 561 562 Notes: 563 By default the values, v, are row-oriented and unsorted. 564 See MatSetOption() for other options. 565 566 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 567 options cannot be mixed without intervening calls to the assembly 568 routines. 569 570 The grid coordinates are across the entire grid, not just the local portion 571 572 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 573 as well as in C. 574 575 In order to use this routine you must either obtain the matrix with DAGetMatrix() 576 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 577 578 In Fortran idxm and idxn should be declared as 579 $ MatStencil idxm(4,m),idxn(4,n) 580 and the values inserted using 581 $ idxm(MatStencil_i,1) = i 582 $ idxm(MatStencil_j,1) = j 583 $ idxm(MatStencil_k,1) = k 584 $ idxm(MatStencil_c,1) = c 585 etc 586 587 Negative indices may be passed in idxm and idxn, these rows and columns are 588 simply ignored. This allows easily inserting element stiffness matrices 589 with homogeneous Dirchlet boundary conditions that you don't want represented 590 in the matrix. 591 592 Inspired by the structured grid interface to the HYPRE package 593 (http://www.llnl.gov/CASC/hypre) 594 595 Efficiency Alert: 596 The routine MatSetValuesBlockedStencil() may offer much better efficiency 597 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 598 599 Level: beginner 600 601 Concepts: matrices^putting entries in 602 603 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 604 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DAGetMatrix() 605 @*/ 606 int MatSetValuesStencil(Mat mat,int m,MatStencil *idxm,int n,MatStencil *idxn,PetscScalar *v,InsertMode addv) 607 { 608 int j,i,ierr,jdxm[128],jdxn[256],dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 609 int *starts = mat->stencil.starts,*dxm = (int*)idxm,*dxn = (int*)idxn,sdim = dim - (1 - (int)mat->stencil.noc); 610 611 PetscFunctionBegin; 612 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 613 PetscValidHeaderSpecific(mat,MAT_COOKIE); 614 PetscValidType(mat); 615 PetscValidIntPointer(idxm); 616 PetscValidIntPointer(idxn); 617 PetscValidScalarPointer(v); 618 619 if (m > 128) SETERRQ1(1,"Can only set 128 rows at a time; trying to set %d",m); 620 if (n > 128) SETERRQ1(1,"Can only set 256 columns at a time; trying to set %d",n); 621 622 for (i=0; i<m; i++) { 623 for (j=0; j<3-sdim; j++) dxm++; 624 tmp = *dxm++ - starts[0]; 625 for (j=0; j<dim-1; j++) { 626 tmp = tmp*dims[j] + *dxm++ - starts[j+1]; 627 } 628 if (mat->stencil.noc) dxm++; 629 jdxm[i] = tmp; 630 } 631 for (i=0; i<n; i++) { 632 for (j=0; j<3-sdim; j++) dxn++; 633 tmp = *dxn++ - starts[0]; 634 for (j=0; j<dim-1; j++) { 635 tmp = tmp*dims[j] + *dxn++ - starts[j+1]; 636 } 637 if (mat->stencil.noc) dxn++; 638 jdxn[i] = tmp; 639 } 640 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "MatSetStencil" 646 /*@ 647 MatSetStencil - Sets the grid information for setting values into a matrix via 648 MatSetStencil() 649 650 Not Collective 651 652 Input Parameters: 653 + mat - the matrix 654 . dim - dimension of the grid 1,2, or 3 655 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 656 . starts - starting point of ghost nodes on your processor in x, y, and z direction 657 - dof - number of degrees of freedom per node 658 659 660 Inspired by the structured grid interface to the HYPRE package 661 (www.llnl.gov/CASC/hyper) 662 663 Level: beginner 664 665 Concepts: matrices^putting entries in 666 667 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 668 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 669 @*/ 670 int MatSetStencil(Mat mat,int dim,int *dims,int *starts,int dof) 671 { 672 int i; 673 674 PetscFunctionBegin; 675 PetscValidHeaderSpecific(mat,MAT_COOKIE); 676 PetscValidIntPointer(dims); 677 PetscValidIntPointer(starts); 678 679 mat->stencil.dim = dim + (dof > 1); 680 for (i=0; i<dim; i++) { 681 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 682 mat->stencil.starts[i] = starts[dim-i-1]; 683 } 684 mat->stencil.dims[dim] = dof; 685 mat->stencil.starts[dim] = 0; 686 mat->stencil.noc = (PetscTruth)(dof == 1); 687 PetscFunctionReturn(0); 688 } 689 690 #undef __FUNCT__ 691 #define __FUNCT__ "MatSetValuesBlocked" 692 /*@ 693 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 694 695 Not Collective 696 697 Input Parameters: 698 + mat - the matrix 699 . v - a logically two-dimensional array of values 700 . m, idxm - the number of block rows and their global block indices 701 . n, idxn - the number of block columns and their global block indices 702 - addv - either ADD_VALUES or INSERT_VALUES, where 703 ADD_VALUES adds values to any existing entries, and 704 INSERT_VALUES replaces existing entries with new values 705 706 Notes: 707 By default the values, v, are row-oriented and unsorted. So the layout of 708 v is the same as for MatSetValues(). See MatSetOption() for other options. 709 710 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 711 options cannot be mixed without intervening calls to the assembly 712 routines. 713 714 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 715 as well as in C. 716 717 Negative indices may be passed in idxm and idxn, these rows and columns are 718 simply ignored. This allows easily inserting element stiffness matrices 719 with homogeneous Dirchlet boundary conditions that you don't want represented 720 in the matrix. 721 722 Each time an entry is set within a sparse matrix via MatSetValues(), 723 internal searching must be done to determine where to place the the 724 data in the matrix storage space. By instead inserting blocks of 725 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 726 reduced. 727 728 Restrictions: 729 MatSetValuesBlocked() is currently supported only for the block AIJ 730 matrix format (MATSEQBAIJ and MATMPIBAIJ, which are created via 731 MatCreateSeqBAIJ() and MatCreateMPIBAIJ()). 732 733 Level: intermediate 734 735 Concepts: matrices^putting entries in blocked 736 737 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 738 @*/ 739 int MatSetValuesBlocked(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v,InsertMode addv) 740 { 741 int ierr; 742 743 PetscFunctionBegin; 744 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 745 PetscValidHeaderSpecific(mat,MAT_COOKIE); 746 PetscValidType(mat); 747 MatPreallocated(mat); 748 PetscValidIntPointer(idxm); 749 PetscValidIntPointer(idxn); 750 PetscValidScalarPointer(v); 751 if (mat->insertmode == NOT_SET_VALUES) { 752 mat->insertmode = addv; 753 } 754 #if defined(PETSC_USE_BOPT_g) 755 else if (mat->insertmode != addv) { 756 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 757 } 758 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 759 #endif 760 761 if (mat->assembled) { 762 mat->was_assembled = PETSC_TRUE; 763 mat->assembled = PETSC_FALSE; 764 } 765 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 766 if (!mat->ops->setvaluesblocked) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 767 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 768 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 769 PetscFunctionReturn(0); 770 } 771 772 /*MC 773 MatSetValue - Set a single entry into a matrix. 774 775 Synopsis: 776 int MatSetValue(Mat m,int row,int col,PetscScalar value,InsertMode mode); 777 778 Not collective 779 780 Input Parameters: 781 + m - the matrix 782 . row - the row location of the entry 783 . col - the column location of the entry 784 . value - the value to insert 785 - mode - either INSERT_VALUES or ADD_VALUES 786 787 Notes: 788 For efficiency one should use MatSetValues() and set several or many 789 values simultaneously if possible. 790 791 Note that VecSetValue() does NOT return an error code (since this 792 is checked internally). 793 794 Level: beginner 795 796 .seealso: MatSetValues() 797 M*/ 798 799 #undef __FUNCT__ 800 #define __FUNCT__ "MatGetValues" 801 /*@ 802 MatGetValues - Gets a block of values from a matrix. 803 804 Not Collective; currently only returns a local block 805 806 Input Parameters: 807 + mat - the matrix 808 . v - a logically two-dimensional array for storing the values 809 . m, idxm - the number of rows and their global indices 810 - n, idxn - the number of columns and their global indices 811 812 Notes: 813 The user must allocate space (m*n PetscScalars) for the values, v. 814 The values, v, are then returned in a row-oriented format, 815 analogous to that used by default in MatSetValues(). 816 817 MatGetValues() uses 0-based row and column numbers in 818 Fortran as well as in C. 819 820 MatGetValues() requires that the matrix has been assembled 821 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 822 MatSetValues() and MatGetValues() CANNOT be made in succession 823 without intermediate matrix assembly. 824 825 Level: advanced 826 827 Concepts: matrices^accessing values 828 829 .seealso: MatGetRow(), MatGetSubmatrices(), MatSetValues() 830 @*/ 831 int MatGetValues(Mat mat,int m,int *idxm,int n,int *idxn,PetscScalar *v) 832 { 833 int ierr; 834 835 PetscFunctionBegin; 836 PetscValidHeaderSpecific(mat,MAT_COOKIE); 837 PetscValidType(mat); 838 MatPreallocated(mat); 839 PetscValidIntPointer(idxm); 840 PetscValidIntPointer(idxn); 841 PetscValidScalarPointer(v); 842 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 843 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 844 if (!mat->ops->getvalues) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 845 846 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 847 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 848 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 849 PetscFunctionReturn(0); 850 } 851 852 #undef __FUNCT__ 853 #define __FUNCT__ "MatSetLocalToGlobalMapping" 854 /*@ 855 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 856 the routine MatSetValuesLocal() to allow users to insert matrix entries 857 using a local (per-processor) numbering. 858 859 Not Collective 860 861 Input Parameters: 862 + x - the matrix 863 - mapping - mapping created with ISLocalToGlobalMappingCreate() 864 or ISLocalToGlobalMappingCreateIS() 865 866 Level: intermediate 867 868 Concepts: matrices^local to global mapping 869 Concepts: local to global mapping^for matrices 870 871 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 872 @*/ 873 int MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping mapping) 874 { 875 int ierr; 876 PetscFunctionBegin; 877 PetscValidHeaderSpecific(x,MAT_COOKIE); 878 PetscValidType(x); 879 MatPreallocated(x); 880 PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 881 if (x->mapping) { 882 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix"); 883 } 884 885 if (x->ops->setlocaltoglobalmapping) { 886 ierr = (*x->ops->setlocaltoglobalmapping)(x,mapping);CHKERRQ(ierr); 887 } else { 888 x->mapping = mapping; 889 ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr); 890 } 891 PetscFunctionReturn(0); 892 } 893 894 #undef __FUNCT__ 895 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock" 896 /*@ 897 MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use 898 by the routine MatSetValuesBlockedLocal() to allow users to insert matrix 899 entries using a local (per-processor) numbering. 900 901 Not Collective 902 903 Input Parameters: 904 + x - the matrix 905 - mapping - mapping created with ISLocalToGlobalMappingCreate() or 906 ISLocalToGlobalMappingCreateIS() 907 908 Level: intermediate 909 910 Concepts: matrices^local to global mapping blocked 911 Concepts: local to global mapping^for matrices, blocked 912 913 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(), 914 MatSetValuesBlocked(), MatSetValuesLocal() 915 @*/ 916 int MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping mapping) 917 { 918 int ierr; 919 PetscFunctionBegin; 920 PetscValidHeaderSpecific(x,MAT_COOKIE); 921 PetscValidType(x); 922 MatPreallocated(x); 923 PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE); 924 if (x->bmapping) { 925 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Mapping already set for matrix"); 926 } 927 928 x->bmapping = mapping; 929 ierr = PetscObjectReference((PetscObject)mapping);CHKERRQ(ierr); 930 PetscFunctionReturn(0); 931 } 932 933 #undef __FUNCT__ 934 #define __FUNCT__ "MatSetValuesLocal" 935 /*@ 936 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 937 using a local ordering of the nodes. 938 939 Not Collective 940 941 Input Parameters: 942 + x - the matrix 943 . nrow, irow - number of rows and their local indices 944 . ncol, icol - number of columns and their local indices 945 . y - a logically two-dimensional array of values 946 - addv - either INSERT_VALUES or ADD_VALUES, where 947 ADD_VALUES adds values to any existing entries, and 948 INSERT_VALUES replaces existing entries with new values 949 950 Notes: 951 Before calling MatSetValuesLocal(), the user must first set the 952 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 953 954 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 955 options cannot be mixed without intervening calls to the assembly 956 routines. 957 958 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 959 MUST be called after all calls to MatSetValuesLocal() have been completed. 960 961 Level: intermediate 962 963 Concepts: matrices^putting entries in with local numbering 964 965 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 966 MatSetValueLocal() 967 @*/ 968 int MatSetValuesLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,PetscScalar *y,InsertMode addv) 969 { 970 int ierr,irowm[2048],icolm[2048]; 971 972 PetscFunctionBegin; 973 PetscValidHeaderSpecific(mat,MAT_COOKIE); 974 PetscValidType(mat); 975 MatPreallocated(mat); 976 PetscValidIntPointer(irow); 977 PetscValidIntPointer(icol); 978 PetscValidScalarPointer(y); 979 980 if (mat->insertmode == NOT_SET_VALUES) { 981 mat->insertmode = addv; 982 } 983 #if defined(PETSC_USE_BOPT_g) 984 else if (mat->insertmode != addv) { 985 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 986 } 987 if (!mat->ops->setvalueslocal && (nrow > 2048 || ncol > 2048)) { 988 SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol); 989 } 990 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 991 #endif 992 993 if (mat->assembled) { 994 mat->was_assembled = PETSC_TRUE; 995 mat->assembled = PETSC_FALSE; 996 } 997 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 998 if (!mat->ops->setvalueslocal) { 999 ierr = ISLocalToGlobalMappingApply(mat->mapping,nrow,irow,irowm);CHKERRQ(ierr); 1000 ierr = ISLocalToGlobalMappingApply(mat->mapping,ncol,icol,icolm);CHKERRQ(ierr); 1001 ierr = (*mat->ops->setvalues)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 1002 } else { 1003 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 1004 } 1005 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1006 PetscFunctionReturn(0); 1007 } 1008 1009 #undef __FUNCT__ 1010 #define __FUNCT__ "MatSetValuesBlockedLocal" 1011 /*@ 1012 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 1013 using a local ordering of the nodes a block at a time. 1014 1015 Not Collective 1016 1017 Input Parameters: 1018 + x - the matrix 1019 . nrow, irow - number of rows and their local indices 1020 . ncol, icol - number of columns and their local indices 1021 . y - a logically two-dimensional array of values 1022 - addv - either INSERT_VALUES or ADD_VALUES, where 1023 ADD_VALUES adds values to any existing entries, and 1024 INSERT_VALUES replaces existing entries with new values 1025 1026 Notes: 1027 Before calling MatSetValuesBlockedLocal(), the user must first set the 1028 local-to-global mapping by calling MatSetLocalToGlobalMappingBlock(), 1029 where the mapping MUST be set for matrix blocks, not for matrix elements. 1030 1031 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 1032 options cannot be mixed without intervening calls to the assembly 1033 routines. 1034 1035 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1036 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 1037 1038 Level: intermediate 1039 1040 Concepts: matrices^putting blocked values in with local numbering 1041 1042 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked() 1043 @*/ 1044 int MatSetValuesBlockedLocal(Mat mat,int nrow,int *irow,int ncol,int *icol,PetscScalar *y,InsertMode addv) 1045 { 1046 int ierr,irowm[2048],icolm[2048]; 1047 1048 PetscFunctionBegin; 1049 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1050 PetscValidType(mat); 1051 MatPreallocated(mat); 1052 PetscValidIntPointer(irow); 1053 PetscValidIntPointer(icol); 1054 PetscValidScalarPointer(y); 1055 if (mat->insertmode == NOT_SET_VALUES) { 1056 mat->insertmode = addv; 1057 } 1058 #if defined(PETSC_USE_BOPT_g) 1059 else if (mat->insertmode != addv) { 1060 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1061 } 1062 if (!mat->bmapping) { 1063 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with MatSetLocalToGlobalMappingBlock()"); 1064 } 1065 if (nrow > 2048 || ncol > 2048) { 1066 SETERRQ2(PETSC_ERR_SUP,"Number column/row indices must be <= 2048: are %d %d",nrow,ncol); 1067 } 1068 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1069 #endif 1070 1071 if (mat->assembled) { 1072 mat->was_assembled = PETSC_TRUE; 1073 mat->assembled = PETSC_FALSE; 1074 } 1075 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1076 ierr = ISLocalToGlobalMappingApply(mat->bmapping,nrow,irow,irowm);CHKERRQ(ierr); 1077 ierr = ISLocalToGlobalMappingApply(mat->bmapping,ncol,icol,icolm);CHKERRQ(ierr); 1078 ierr = (*mat->ops->setvaluesblocked)(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 1079 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1080 PetscFunctionReturn(0); 1081 } 1082 1083 /* --------------------------------------------------------*/ 1084 #undef __FUNCT__ 1085 #define __FUNCT__ "MatMult" 1086 /*@ 1087 MatMult - Computes the matrix-vector product, y = Ax. 1088 1089 Collective on Mat and Vec 1090 1091 Input Parameters: 1092 + mat - the matrix 1093 - x - the vector to be multilplied 1094 1095 Output Parameters: 1096 . y - the result 1097 1098 Notes: 1099 The vectors x and y cannot be the same. I.e., one cannot 1100 call MatMult(A,y,y). 1101 1102 Level: beginner 1103 1104 Concepts: matrix-vector product 1105 1106 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 1107 @*/ 1108 int MatMult(Mat mat,Vec x,Vec y) 1109 { 1110 int ierr; 1111 1112 PetscFunctionBegin; 1113 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1114 PetscValidType(mat); 1115 MatPreallocated(mat); 1116 PetscValidHeaderSpecific(x,VEC_COOKIE); 1117 PetscValidHeaderSpecific(y,VEC_COOKIE); 1118 1119 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1120 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1121 if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 1122 #ifndef PETSC_HAVE_CONSTRAINTS 1123 if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 1124 if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N); 1125 if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n); 1126 #endif 1127 1128 if (mat->nullsp) { 1129 ierr = MatNullSpaceRemove(mat->nullsp,x,&x);CHKERRQ(ierr); 1130 } 1131 1132 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 1133 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 1134 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 1135 1136 if (mat->nullsp) { 1137 ierr = MatNullSpaceRemove(mat->nullsp,y,PETSC_NULL);CHKERRQ(ierr); 1138 } 1139 PetscFunctionReturn(0); 1140 } 1141 1142 #undef __FUNCT__ 1143 #define __FUNCT__ "MatMultTranspose" 1144 /*@ 1145 MatMultTranspose - Computes matrix transpose times a vector. 1146 1147 Collective on Mat and Vec 1148 1149 Input Parameters: 1150 + mat - the matrix 1151 - x - the vector to be multilplied 1152 1153 Output Parameters: 1154 . y - the result 1155 1156 Notes: 1157 The vectors x and y cannot be the same. I.e., one cannot 1158 call MatMultTranspose(A,y,y). 1159 1160 Level: beginner 1161 1162 Concepts: matrix vector product^transpose 1163 1164 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd() 1165 @*/ 1166 int MatMultTranspose(Mat mat,Vec x,Vec y) 1167 { 1168 int ierr; 1169 PetscTruth flg1, flg2; 1170 1171 PetscFunctionBegin; 1172 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1173 PetscValidType(mat); 1174 MatPreallocated(mat); 1175 PetscValidHeaderSpecific(x,VEC_COOKIE); 1176 PetscValidHeaderSpecific(y,VEC_COOKIE); 1177 1178 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1179 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1180 if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 1181 #ifndef PETSC_HAVE_CONSTRAINTS 1182 if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N); 1183 if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N); 1184 #endif 1185 1186 if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP, "Operation not supported"); 1187 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 1188 if (!mat->ops->multtranspose) SETERRQ(PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined"); 1189 1190 ierr = PetscTypeCompare((PetscObject)mat,MATSEQSBAIJ,&flg1); 1191 ierr = PetscTypeCompare((PetscObject)mat,MATMPISBAIJ,&flg2); 1192 if (flg1 || flg2) { /* mat is in sbaij format */ 1193 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 1194 } else { 1195 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 1196 } 1197 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 1198 PetscFunctionReturn(0); 1199 } 1200 1201 #undef __FUNCT__ 1202 #define __FUNCT__ "MatMultAdd" 1203 /*@ 1204 MatMultAdd - Computes v3 = v2 + A * v1. 1205 1206 Collective on Mat and Vec 1207 1208 Input Parameters: 1209 + mat - the matrix 1210 - v1, v2 - the vectors 1211 1212 Output Parameters: 1213 . v3 - the result 1214 1215 Notes: 1216 The vectors v1 and v3 cannot be the same. I.e., one cannot 1217 call MatMultAdd(A,v1,v2,v1). 1218 1219 Level: beginner 1220 1221 Concepts: matrix vector product^addition 1222 1223 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 1224 @*/ 1225 int MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 1226 { 1227 int ierr; 1228 1229 PetscFunctionBegin; 1230 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1231 PetscValidType(mat); 1232 MatPreallocated(mat); 1233 PetscValidHeaderSpecific(v1,VEC_COOKIE); 1234 PetscValidHeaderSpecific(v2,VEC_COOKIE); 1235 PetscValidHeaderSpecific(v3,VEC_COOKIE); 1236 1237 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1238 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1239 if (mat->N != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->N,v1->N); 1240 if (mat->M != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->M,v2->N); 1241 if (mat->M != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->M,v3->N); 1242 if (mat->m != v3->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %d %d",mat->m,v3->n); 1243 if (mat->m != v2->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %d %d",mat->m,v2->n); 1244 if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 1245 1246 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 1247 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 1248 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 1249 PetscFunctionReturn(0); 1250 } 1251 1252 #undef __FUNCT__ 1253 #define __FUNCT__ "MatMultTransposeAdd" 1254 /*@ 1255 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 1256 1257 Collective on Mat and Vec 1258 1259 Input Parameters: 1260 + mat - the matrix 1261 - v1, v2 - the vectors 1262 1263 Output Parameters: 1264 . v3 - the result 1265 1266 Notes: 1267 The vectors v1 and v3 cannot be the same. I.e., one cannot 1268 call MatMultTransposeAdd(A,v1,v2,v1). 1269 1270 Level: beginner 1271 1272 Concepts: matrix vector product^transpose and addition 1273 1274 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 1275 @*/ 1276 int MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 1277 { 1278 int ierr; 1279 1280 PetscFunctionBegin; 1281 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1282 PetscValidType(mat); 1283 MatPreallocated(mat); 1284 PetscValidHeaderSpecific(v1,VEC_COOKIE); 1285 PetscValidHeaderSpecific(v2,VEC_COOKIE); 1286 PetscValidHeaderSpecific(v3,VEC_COOKIE); 1287 1288 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1289 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1290 if (!mat->ops->multtransposeadd) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1291 if (v1 == v3) SETERRQ(PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 1292 if (mat->M != v1->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %d %d",mat->M,v1->N); 1293 if (mat->N != v2->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %d %d",mat->N,v2->N); 1294 if (mat->N != v3->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %d %d",mat->N,v3->N); 1295 1296 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 1297 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 1298 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 1299 PetscFunctionReturn(0); 1300 } 1301 1302 #undef __FUNCT__ 1303 #define __FUNCT__ "MatMultConstrained" 1304 /*@ 1305 MatMultConstrained - The inner multiplication routine for a 1306 constrained matrix P^T A P. 1307 1308 Collective on Mat and Vec 1309 1310 Input Parameters: 1311 + mat - the matrix 1312 - x - the vector to be multilplied 1313 1314 Output Parameters: 1315 . y - the result 1316 1317 Notes: 1318 The vectors x and y cannot be the same. I.e., one cannot 1319 call MatMult(A,y,y). 1320 1321 Level: beginner 1322 1323 .keywords: matrix, multiply, matrix-vector product, constraint 1324 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd() 1325 @*/ 1326 int MatMultConstrained(Mat mat,Vec x,Vec y) 1327 { 1328 int ierr; 1329 1330 PetscFunctionBegin; 1331 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1332 PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE); 1333 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1334 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1335 if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 1336 if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 1337 if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N); 1338 if (mat->m != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %d %d",mat->m,y->n); 1339 1340 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 1341 ierr = (*mat->ops->multconstrained)(mat,x,y); CHKERRQ(ierr); 1342 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 1343 1344 PetscFunctionReturn(0); 1345 } 1346 1347 #undef __FUNCT__ 1348 #define __FUNCT__ "MatMultTransposeConstrained" 1349 /*@ 1350 MatMultTransposeConstrained - The inner multiplication routine for a 1351 constrained matrix P^T A^T P. 1352 1353 Collective on Mat and Vec 1354 1355 Input Parameters: 1356 + mat - the matrix 1357 - x - the vector to be multilplied 1358 1359 Output Parameters: 1360 . y - the result 1361 1362 Notes: 1363 The vectors x and y cannot be the same. I.e., one cannot 1364 call MatMult(A,y,y). 1365 1366 Level: beginner 1367 1368 .keywords: matrix, multiply, matrix-vector product, constraint 1369 .seealso: MatMult(), MatMultTrans(), MatMultAdd(), MatMultTransAdd() 1370 @*/ 1371 int MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 1372 { 1373 int ierr; 1374 1375 PetscFunctionBegin; 1376 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1377 PetscValidHeaderSpecific(x,VEC_COOKIE);PetscValidHeaderSpecific(y,VEC_COOKIE); 1378 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1379 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1380 if (x == y) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 1381 if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 1382 if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N); 1383 1384 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 1385 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 1386 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 1387 1388 PetscFunctionReturn(0); 1389 } 1390 /* ------------------------------------------------------------*/ 1391 #undef __FUNCT__ 1392 #define __FUNCT__ "MatGetInfo" 1393 /*@C 1394 MatGetInfo - Returns information about matrix storage (number of 1395 nonzeros, memory, etc.). 1396 1397 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used 1398 as the flag 1399 1400 Input Parameters: 1401 . mat - the matrix 1402 1403 Output Parameters: 1404 + flag - flag indicating the type of parameters to be returned 1405 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 1406 MAT_GLOBAL_SUM - sum over all processors) 1407 - info - matrix information context 1408 1409 Notes: 1410 The MatInfo context contains a variety of matrix data, including 1411 number of nonzeros allocated and used, number of mallocs during 1412 matrix assembly, etc. Additional information for factored matrices 1413 is provided (such as the fill ratio, number of mallocs during 1414 factorization, etc.). Much of this info is printed to STDOUT 1415 when using the runtime options 1416 $ -log_info -mat_view_info 1417 1418 Example for C/C++ Users: 1419 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 1420 data within the MatInfo context. For example, 1421 .vb 1422 MatInfo info; 1423 Mat A; 1424 double mal, nz_a, nz_u; 1425 1426 MatGetInfo(A,MAT_LOCAL,&info); 1427 mal = info.mallocs; 1428 nz_a = info.nz_allocated; 1429 .ve 1430 1431 Example for Fortran Users: 1432 Fortran users should declare info as a double precision 1433 array of dimension MAT_INFO_SIZE, and then extract the parameters 1434 of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h 1435 a complete list of parameter names. 1436 .vb 1437 double precision info(MAT_INFO_SIZE) 1438 double precision mal, nz_a 1439 Mat A 1440 integer ierr 1441 1442 call MatGetInfo(A,MAT_LOCAL,info,ierr) 1443 mal = info(MAT_INFO_MALLOCS) 1444 nz_a = info(MAT_INFO_NZ_ALLOCATED) 1445 .ve 1446 1447 Level: intermediate 1448 1449 Concepts: matrices^getting information on 1450 1451 @*/ 1452 int MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 1453 { 1454 int ierr; 1455 1456 PetscFunctionBegin; 1457 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1458 PetscValidType(mat); 1459 MatPreallocated(mat); 1460 PetscValidPointer(info); 1461 if (!mat->ops->getinfo) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1462 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 1463 PetscFunctionReturn(0); 1464 } 1465 1466 /* ----------------------------------------------------------*/ 1467 #undef __FUNCT__ 1468 #define __FUNCT__ "MatILUDTFactor" 1469 /*@C 1470 MatILUDTFactor - Performs a drop tolerance ILU factorization. 1471 1472 Collective on Mat 1473 1474 Input Parameters: 1475 + mat - the matrix 1476 . info - information about the factorization to be done 1477 . row - row permutation 1478 - col - column permutation 1479 1480 Output Parameters: 1481 . fact - the factored matrix 1482 1483 Level: developer 1484 1485 Notes: 1486 Most users should employ the simplified SLES interface for linear solvers 1487 instead of working directly with matrix algebra routines such as this. 1488 See, e.g., SLESCreate(). 1489 1490 This is currently only supported for the SeqAIJ matrix format using code 1491 from Yousef Saad's SPARSEKIT2 package (translated to C with f2c) and/or 1492 Matlab. SPARSEKIT2 is copyrighted by Yousef Saad with the GNU copyright 1493 and thus can be distributed with PETSc. 1494 1495 Concepts: matrices^ILUDT factorization 1496 1497 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo 1498 @*/ 1499 int MatILUDTFactor(Mat mat,MatILUInfo *info,IS row,IS col,Mat *fact) 1500 { 1501 int ierr; 1502 1503 PetscFunctionBegin; 1504 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1505 PetscValidType(mat); 1506 MatPreallocated(mat); 1507 PetscValidPointer(fact); 1508 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1509 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1510 if (!mat->ops->iludtfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1511 1512 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 1513 ierr = (*mat->ops->iludtfactor)(mat,info,row,col,fact);CHKERRQ(ierr); 1514 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 1515 1516 PetscFunctionReturn(0); 1517 } 1518 1519 #undef __FUNCT__ 1520 #define __FUNCT__ "MatLUFactor" 1521 /*@ 1522 MatLUFactor - Performs in-place LU factorization of matrix. 1523 1524 Collective on Mat 1525 1526 Input Parameters: 1527 + mat - the matrix 1528 . row - row permutation 1529 . col - column permutation 1530 - info - options for factorization, includes 1531 $ fill - expected fill as ratio of original fill. 1532 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 1533 $ Run with the option -log_info to determine an optimal value to use 1534 1535 Notes: 1536 Most users should employ the simplified SLES interface for linear solvers 1537 instead of working directly with matrix algebra routines such as this. 1538 See, e.g., SLESCreate(). 1539 1540 This changes the state of the matrix to a factored matrix; it cannot be used 1541 for example with MatSetValues() unless one first calls MatSetUnfactored(). 1542 1543 Level: developer 1544 1545 Concepts: matrices^LU factorization 1546 1547 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 1548 MatGetOrdering(), MatSetUnfactored(), MatLUInfo 1549 1550 @*/ 1551 int MatLUFactor(Mat mat,IS row,IS col,MatLUInfo *info) 1552 { 1553 int ierr; 1554 1555 PetscFunctionBegin; 1556 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1557 PetscValidType(mat); 1558 MatPreallocated(mat); 1559 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1560 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1561 if (!mat->ops->lufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1562 1563 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 1564 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 1565 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 1566 PetscFunctionReturn(0); 1567 } 1568 1569 #undef __FUNCT__ 1570 #define __FUNCT__ "MatILUFactor" 1571 /*@ 1572 MatILUFactor - Performs in-place ILU factorization of matrix. 1573 1574 Collective on Mat 1575 1576 Input Parameters: 1577 + mat - the matrix 1578 . row - row permutation 1579 . col - column permutation 1580 - info - structure containing 1581 $ levels - number of levels of fill. 1582 $ expected fill - as ratio of original fill. 1583 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 1584 missing diagonal entries) 1585 1586 Notes: 1587 Probably really in-place only when level of fill is zero, otherwise allocates 1588 new space to store factored matrix and deletes previous memory. 1589 1590 Most users should employ the simplified SLES interface for linear solvers 1591 instead of working directly with matrix algebra routines such as this. 1592 See, e.g., SLESCreate(). 1593 1594 Level: developer 1595 1596 Concepts: matrices^ILU factorization 1597 1598 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatILUInfo 1599 @*/ 1600 int MatILUFactor(Mat mat,IS row,IS col,MatILUInfo *info) 1601 { 1602 int ierr; 1603 1604 PetscFunctionBegin; 1605 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1606 PetscValidType(mat); 1607 MatPreallocated(mat); 1608 if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square"); 1609 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1610 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1611 if (!mat->ops->ilufactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1612 1613 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 1614 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 1615 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 1616 PetscFunctionReturn(0); 1617 } 1618 1619 #undef __FUNCT__ 1620 #define __FUNCT__ "MatLUFactorSymbolic" 1621 /*@ 1622 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 1623 Call this routine before calling MatLUFactorNumeric(). 1624 1625 Collective on Mat 1626 1627 Input Parameters: 1628 + mat - the matrix 1629 . row, col - row and column permutations 1630 - info - options for factorization, includes 1631 $ fill - expected fill as ratio of original fill. 1632 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 1633 $ Run with the option -log_info to determine an optimal value to use 1634 1635 Output Parameter: 1636 . fact - new matrix that has been symbolically factored 1637 1638 Notes: 1639 See the users manual for additional information about 1640 choosing the fill factor for better efficiency. 1641 1642 Most users should employ the simplified SLES interface for linear solvers 1643 instead of working directly with matrix algebra routines such as this. 1644 See, e.g., SLESCreate(). 1645 1646 Level: developer 1647 1648 Concepts: matrices^LU symbolic factorization 1649 1650 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatLUInfo 1651 @*/ 1652 int MatLUFactorSymbolic(Mat mat,IS row,IS col,MatLUInfo *info,Mat *fact) 1653 { 1654 int ierr; 1655 1656 PetscFunctionBegin; 1657 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1658 PetscValidType(mat); 1659 MatPreallocated(mat); 1660 PetscValidPointer(fact); 1661 PetscValidHeaderSpecific(row,IS_COOKIE); 1662 PetscValidHeaderSpecific(col,IS_COOKIE); 1663 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1664 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1665 if (!mat->ops->lufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic LU",mat->type_name); 1666 1667 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 1668 ierr = (*mat->ops->lufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr); 1669 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 1670 PetscFunctionReturn(0); 1671 } 1672 1673 #undef __FUNCT__ 1674 #define __FUNCT__ "MatLUFactorNumeric" 1675 /*@ 1676 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 1677 Call this routine after first calling MatLUFactorSymbolic(). 1678 1679 Collective on Mat 1680 1681 Input Parameters: 1682 + mat - the matrix 1683 - fact - the matrix generated for the factor, from MatLUFactorSymbolic() 1684 1685 Notes: 1686 See MatLUFactor() for in-place factorization. See 1687 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 1688 1689 Most users should employ the simplified SLES interface for linear solvers 1690 instead of working directly with matrix algebra routines such as this. 1691 See, e.g., SLESCreate(). 1692 1693 Level: developer 1694 1695 Concepts: matrices^LU numeric factorization 1696 1697 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 1698 @*/ 1699 int MatLUFactorNumeric(Mat mat,Mat *fact) 1700 { 1701 int ierr; 1702 PetscTruth flg; 1703 1704 PetscFunctionBegin; 1705 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1706 PetscValidType(mat); 1707 MatPreallocated(mat); 1708 PetscValidPointer(fact); 1709 PetscValidHeaderSpecific(*fact,MAT_COOKIE); 1710 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1711 if (mat->M != (*fact)->M || mat->N != (*fact)->N) { 1712 SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dimensions are different %d should = %d %d should = %d", 1713 mat->M,(*fact)->M,mat->N,(*fact)->N); 1714 } 1715 if (!(*fact)->ops->lufactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1716 1717 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr); 1718 ierr = (*(*fact)->ops->lufactornumeric)(mat,fact);CHKERRQ(ierr); 1719 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr); 1720 ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_draw",&flg);CHKERRQ(ierr); 1721 if (flg) { 1722 ierr = PetscOptionsHasName(PETSC_NULL,"-mat_view_contour",&flg);CHKERRQ(ierr); 1723 if (flg) { 1724 ierr = PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1725 } 1726 ierr = MatView(*fact,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); 1727 ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); 1728 if (flg) { 1729 ierr = PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); 1730 } 1731 } 1732 PetscFunctionReturn(0); 1733 } 1734 1735 #undef __FUNCT__ 1736 #define __FUNCT__ "MatCholeskyFactor" 1737 /*@ 1738 MatCholeskyFactor - Performs in-place Cholesky factorization of a 1739 symmetric matrix. 1740 1741 Collective on Mat 1742 1743 Input Parameters: 1744 + mat - the matrix 1745 . perm - row and column permutations 1746 - f - expected fill as ratio of original fill 1747 1748 Notes: 1749 See MatLUFactor() for the nonsymmetric case. See also 1750 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 1751 1752 Most users should employ the simplified SLES interface for linear solvers 1753 instead of working directly with matrix algebra routines such as this. 1754 See, e.g., SLESCreate(). 1755 1756 Level: developer 1757 1758 Concepts: matrices^Cholesky factorization 1759 1760 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 1761 MatGetOrdering() 1762 1763 @*/ 1764 int MatCholeskyFactor(Mat mat,IS perm,PetscReal f) 1765 { 1766 int ierr; 1767 1768 PetscFunctionBegin; 1769 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1770 PetscValidType(mat); 1771 MatPreallocated(mat); 1772 PetscValidHeaderSpecific(perm,IS_COOKIE); 1773 if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square"); 1774 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1775 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1776 if (!mat->ops->choleskyfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1777 1778 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 1779 ierr = (*mat->ops->choleskyfactor)(mat,perm,f);CHKERRQ(ierr); 1780 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 1781 PetscFunctionReturn(0); 1782 } 1783 1784 #undef __FUNCT__ 1785 #define __FUNCT__ "MatCholeskyFactorSymbolic" 1786 /*@ 1787 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 1788 of a symmetric matrix. 1789 1790 Collective on Mat 1791 1792 Input Parameters: 1793 + mat - the matrix 1794 . perm - row and column permutations 1795 - f - expected fill as ratio of original 1796 1797 Output Parameter: 1798 . fact - the factored matrix 1799 1800 Notes: 1801 See MatLUFactorSymbolic() for the nonsymmetric case. See also 1802 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 1803 1804 Most users should employ the simplified SLES interface for linear solvers 1805 instead of working directly with matrix algebra routines such as this. 1806 See, e.g., SLESCreate(). 1807 1808 Level: developer 1809 1810 Concepts: matrices^Cholesky symbolic factorization 1811 1812 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 1813 MatGetOrdering() 1814 1815 @*/ 1816 int MatCholeskyFactorSymbolic(Mat mat,IS perm,PetscReal f,Mat *fact) 1817 { 1818 int ierr; 1819 1820 PetscFunctionBegin; 1821 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1822 PetscValidType(mat); 1823 MatPreallocated(mat); 1824 PetscValidPointer(fact); 1825 if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square"); 1826 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1827 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1828 if (!mat->ops->choleskyfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1829 1830 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 1831 ierr = (*mat->ops->choleskyfactorsymbolic)(mat,perm,f,fact);CHKERRQ(ierr); 1832 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 1833 PetscFunctionReturn(0); 1834 } 1835 1836 #undef __FUNCT__ 1837 #define __FUNCT__ "MatCholeskyFactorNumeric" 1838 /*@ 1839 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 1840 of a symmetric matrix. Call this routine after first calling 1841 MatCholeskyFactorSymbolic(). 1842 1843 Collective on Mat 1844 1845 Input Parameter: 1846 . mat - the initial matrix 1847 1848 Output Parameter: 1849 . fact - the factored matrix 1850 1851 Notes: 1852 Most users should employ the simplified SLES interface for linear solvers 1853 instead of working directly with matrix algebra routines such as this. 1854 See, e.g., SLESCreate(). 1855 1856 Level: developer 1857 1858 Concepts: matrices^Cholesky numeric factorization 1859 1860 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 1861 @*/ 1862 int MatCholeskyFactorNumeric(Mat mat,Mat *fact) 1863 { 1864 int ierr; 1865 1866 PetscFunctionBegin; 1867 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1868 PetscValidType(mat); 1869 MatPreallocated(mat); 1870 PetscValidPointer(fact); 1871 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1872 if (!(*fact)->ops->choleskyfactornumeric) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1873 if (mat->M != (*fact)->M || mat->N != (*fact)->N) { 1874 SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat mat,Mat *fact: global dim %d should = %d %d should = %d", 1875 mat->M,(*fact)->M,mat->N,(*fact)->N); 1876 } 1877 1878 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr); 1879 ierr = (*(*fact)->ops->choleskyfactornumeric)(mat,fact);CHKERRQ(ierr); 1880 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,*fact,0,0);CHKERRQ(ierr); 1881 PetscFunctionReturn(0); 1882 } 1883 1884 /* ----------------------------------------------------------------*/ 1885 #undef __FUNCT__ 1886 #define __FUNCT__ "MatSolve" 1887 /*@ 1888 MatSolve - Solves A x = b, given a factored matrix. 1889 1890 Collective on Mat and Vec 1891 1892 Input Parameters: 1893 + mat - the factored matrix 1894 - b - the right-hand-side vector 1895 1896 Output Parameter: 1897 . x - the result vector 1898 1899 Notes: 1900 The vectors b and x cannot be the same. I.e., one cannot 1901 call MatSolve(A,x,x). 1902 1903 Notes: 1904 Most users should employ the simplified SLES interface for linear solvers 1905 instead of working directly with matrix algebra routines such as this. 1906 See, e.g., SLESCreate(). 1907 1908 Level: developer 1909 1910 Concepts: matrices^triangular solves 1911 1912 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 1913 @*/ 1914 int MatSolve(Mat mat,Vec b,Vec x) 1915 { 1916 int ierr; 1917 1918 PetscFunctionBegin; 1919 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1920 PetscValidType(mat); 1921 MatPreallocated(mat); 1922 PetscValidHeaderSpecific(b,VEC_COOKIE); 1923 PetscValidHeaderSpecific(x,VEC_COOKIE); 1924 PetscCheckSameComm(mat,b); 1925 PetscCheckSameComm(mat,x); 1926 if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 1927 if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 1928 if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 1929 if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N); 1930 if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n); 1931 if (mat->M == 0 && mat->N == 0) PetscFunctionReturn(0); 1932 1933 if (!mat->ops->solve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1934 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 1935 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 1936 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 1937 PetscFunctionReturn(0); 1938 } 1939 1940 #undef __FUNCT__ 1941 #define __FUNCT__ "MatForwardSolve" 1942 /* @ 1943 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU. 1944 1945 Collective on Mat and Vec 1946 1947 Input Parameters: 1948 + mat - the factored matrix 1949 - b - the right-hand-side vector 1950 1951 Output Parameter: 1952 . x - the result vector 1953 1954 Notes: 1955 MatSolve() should be used for most applications, as it performs 1956 a forward solve followed by a backward solve. 1957 1958 The vectors b and x cannot be the same. I.e., one cannot 1959 call MatForwardSolve(A,x,x). 1960 1961 Most users should employ the simplified SLES interface for linear solvers 1962 instead of working directly with matrix algebra routines such as this. 1963 See, e.g., SLESCreate(). 1964 1965 Level: developer 1966 1967 Concepts: matrices^forward solves 1968 1969 .seealso: MatSolve(), MatBackwardSolve() 1970 @ */ 1971 int MatForwardSolve(Mat mat,Vec b,Vec x) 1972 { 1973 int ierr; 1974 1975 PetscFunctionBegin; 1976 PetscValidHeaderSpecific(mat,MAT_COOKIE); 1977 PetscValidType(mat); 1978 MatPreallocated(mat); 1979 PetscValidHeaderSpecific(b,VEC_COOKIE); 1980 PetscValidHeaderSpecific(x,VEC_COOKIE); 1981 PetscCheckSameComm(mat,b); 1982 PetscCheckSameComm(mat,x); 1983 if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 1984 if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 1985 if (!mat->ops->forwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 1986 if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 1987 if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N); 1988 if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n); 1989 1990 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 1991 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 1992 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 1993 PetscFunctionReturn(0); 1994 } 1995 1996 #undef __FUNCT__ 1997 #define __FUNCT__ "MatBackwardSolve" 1998 /* @ 1999 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 2000 2001 Collective on Mat and Vec 2002 2003 Input Parameters: 2004 + mat - the factored matrix 2005 - b - the right-hand-side vector 2006 2007 Output Parameter: 2008 . x - the result vector 2009 2010 Notes: 2011 MatSolve() should be used for most applications, as it performs 2012 a forward solve followed by a backward solve. 2013 2014 The vectors b and x cannot be the same. I.e., one cannot 2015 call MatBackwardSolve(A,x,x). 2016 2017 Most users should employ the simplified SLES interface for linear solvers 2018 instead of working directly with matrix algebra routines such as this. 2019 See, e.g., SLESCreate(). 2020 2021 Level: developer 2022 2023 Concepts: matrices^backward solves 2024 2025 .seealso: MatSolve(), MatForwardSolve() 2026 @ */ 2027 int MatBackwardSolve(Mat mat,Vec b,Vec x) 2028 { 2029 int ierr; 2030 2031 PetscFunctionBegin; 2032 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2033 PetscValidType(mat); 2034 MatPreallocated(mat); 2035 PetscValidHeaderSpecific(b,VEC_COOKIE); 2036 PetscValidHeaderSpecific(x,VEC_COOKIE); 2037 PetscCheckSameComm(mat,b); 2038 PetscCheckSameComm(mat,x); 2039 if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 2040 if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 2041 if (!mat->ops->backwardsolve) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2042 if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 2043 if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N); 2044 if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n); 2045 2046 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 2047 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 2048 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 2049 PetscFunctionReturn(0); 2050 } 2051 2052 #undef __FUNCT__ 2053 #define __FUNCT__ "MatSolveAdd" 2054 /*@ 2055 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 2056 2057 Collective on Mat and Vec 2058 2059 Input Parameters: 2060 + mat - the factored matrix 2061 . b - the right-hand-side vector 2062 - y - the vector to be added to 2063 2064 Output Parameter: 2065 . x - the result vector 2066 2067 Notes: 2068 The vectors b and x cannot be the same. I.e., one cannot 2069 call MatSolveAdd(A,x,y,x). 2070 2071 Most users should employ the simplified SLES interface for linear solvers 2072 instead of working directly with matrix algebra routines such as this. 2073 See, e.g., SLESCreate(). 2074 2075 Level: developer 2076 2077 Concepts: matrices^triangular solves 2078 2079 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 2080 @*/ 2081 int MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 2082 { 2083 PetscScalar one = 1.0; 2084 Vec tmp; 2085 int ierr; 2086 2087 PetscFunctionBegin; 2088 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2089 PetscValidType(mat); 2090 MatPreallocated(mat); 2091 PetscValidHeaderSpecific(y,VEC_COOKIE); 2092 PetscValidHeaderSpecific(b,VEC_COOKIE); 2093 PetscValidHeaderSpecific(x,VEC_COOKIE); 2094 PetscCheckSameComm(mat,b); 2095 PetscCheckSameComm(mat,y); 2096 PetscCheckSameComm(mat,x); 2097 if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 2098 if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 2099 if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 2100 if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N); 2101 if (mat->M != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->M,y->N); 2102 if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n); 2103 if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n); 2104 2105 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 2106 if (mat->ops->solveadd) { 2107 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 2108 } else { 2109 /* do the solve then the add manually */ 2110 if (x != y) { 2111 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 2112 ierr = VecAXPY(&one,y,x);CHKERRQ(ierr); 2113 } else { 2114 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 2115 PetscLogObjectParent(mat,tmp); 2116 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 2117 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 2118 ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr); 2119 ierr = VecDestroy(tmp);CHKERRQ(ierr); 2120 } 2121 } 2122 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 2123 PetscFunctionReturn(0); 2124 } 2125 2126 #undef __FUNCT__ 2127 #define __FUNCT__ "MatSolveTranspose" 2128 /*@ 2129 MatSolveTranspose - Solves A' x = b, given a factored matrix. 2130 2131 Collective on Mat and Vec 2132 2133 Input Parameters: 2134 + mat - the factored matrix 2135 - b - the right-hand-side vector 2136 2137 Output Parameter: 2138 . x - the result vector 2139 2140 Notes: 2141 The vectors b and x cannot be the same. I.e., one cannot 2142 call MatSolveTranspose(A,x,x). 2143 2144 Most users should employ the simplified SLES interface for linear solvers 2145 instead of working directly with matrix algebra routines such as this. 2146 See, e.g., SLESCreate(). 2147 2148 Level: developer 2149 2150 Concepts: matrices^triangular solves 2151 2152 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 2153 @*/ 2154 int MatSolveTranspose(Mat mat,Vec b,Vec x) 2155 { 2156 int ierr; 2157 2158 PetscFunctionBegin; 2159 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2160 PetscValidType(mat); 2161 MatPreallocated(mat); 2162 PetscValidHeaderSpecific(b,VEC_COOKIE); 2163 PetscValidHeaderSpecific(x,VEC_COOKIE); 2164 PetscCheckSameComm(mat,b); 2165 PetscCheckSameComm(mat,x); 2166 if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 2167 if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 2168 if (!mat->ops->solvetranspose) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s",mat->type_name); 2169 if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N); 2170 if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N); 2171 2172 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 2173 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 2174 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 2175 PetscFunctionReturn(0); 2176 } 2177 2178 #undef __FUNCT__ 2179 #define __FUNCT__ "MatSolveTransposeAdd" 2180 /*@ 2181 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 2182 factored matrix. 2183 2184 Collective on Mat and Vec 2185 2186 Input Parameters: 2187 + mat - the factored matrix 2188 . b - the right-hand-side vector 2189 - y - the vector to be added to 2190 2191 Output Parameter: 2192 . x - the result vector 2193 2194 Notes: 2195 The vectors b and x cannot be the same. I.e., one cannot 2196 call MatSolveTransposeAdd(A,x,y,x). 2197 2198 Most users should employ the simplified SLES interface for linear solvers 2199 instead of working directly with matrix algebra routines such as this. 2200 See, e.g., SLESCreate(). 2201 2202 Level: developer 2203 2204 Concepts: matrices^triangular solves 2205 2206 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 2207 @*/ 2208 int MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 2209 { 2210 PetscScalar one = 1.0; 2211 int ierr; 2212 Vec tmp; 2213 2214 PetscFunctionBegin; 2215 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2216 PetscValidType(mat); 2217 MatPreallocated(mat); 2218 PetscValidHeaderSpecific(y,VEC_COOKIE); 2219 PetscValidHeaderSpecific(b,VEC_COOKIE); 2220 PetscValidHeaderSpecific(x,VEC_COOKIE); 2221 PetscCheckSameComm(mat,b); 2222 PetscCheckSameComm(mat,y); 2223 PetscCheckSameComm(mat,x); 2224 if (x == b) SETERRQ(PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 2225 if (!mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 2226 if (mat->M != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->M,x->N); 2227 if (mat->N != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->N,b->N); 2228 if (mat->N != y->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %d %d",mat->N,y->N); 2229 if (x->n != y->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %d %d",x->n,y->n); 2230 2231 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 2232 if (mat->ops->solvetransposeadd) { 2233 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 2234 } else { 2235 /* do the solve then the add manually */ 2236 if (x != y) { 2237 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 2238 ierr = VecAXPY(&one,y,x);CHKERRQ(ierr); 2239 } else { 2240 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 2241 PetscLogObjectParent(mat,tmp); 2242 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 2243 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 2244 ierr = VecAXPY(&one,tmp,x);CHKERRQ(ierr); 2245 ierr = VecDestroy(tmp);CHKERRQ(ierr); 2246 } 2247 } 2248 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 2249 PetscFunctionReturn(0); 2250 } 2251 /* ----------------------------------------------------------------*/ 2252 2253 #undef __FUNCT__ 2254 #define __FUNCT__ "MatRelax" 2255 /*@ 2256 MatRelax - Computes one relaxation sweep. 2257 2258 Collective on Mat and Vec 2259 2260 Input Parameters: 2261 + mat - the matrix 2262 . b - the right hand side 2263 . omega - the relaxation factor 2264 . flag - flag indicating the type of SOR (see below) 2265 . shift - diagonal shift 2266 - its - the number of iterations 2267 - lits - the number of local iterations 2268 2269 Output Parameters: 2270 . x - the solution (can contain an initial guess) 2271 2272 SOR Flags: 2273 . SOR_FORWARD_SWEEP - forward SOR 2274 . SOR_BACKWARD_SWEEP - backward SOR 2275 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 2276 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 2277 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 2278 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 2279 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 2280 upper/lower triangular part of matrix to 2281 vector (with omega) 2282 . SOR_ZERO_INITIAL_GUESS - zero initial guess 2283 2284 Notes: 2285 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 2286 SOR_LOCAL_SYMMETRIC_SWEEP perform seperate independent smoothings 2287 on each processor. 2288 2289 Application programmers will not generally use MatRelax() directly, 2290 but instead will employ the SLES/PC interface. 2291 2292 Notes for Advanced Users: 2293 The flags are implemented as bitwise inclusive or operations. 2294 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 2295 to specify a zero initial guess for SSOR. 2296 2297 Most users should employ the simplified SLES interface for linear solvers 2298 instead of working directly with matrix algebra routines such as this. 2299 See, e.g., SLESCreate(). 2300 2301 Level: developer 2302 2303 Concepts: matrices^relaxation 2304 Concepts: matrices^SOR 2305 Concepts: matrices^Gauss-Seidel 2306 2307 @*/ 2308 int MatRelax(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,int its,int lits,Vec x) 2309 { 2310 int ierr; 2311 2312 PetscFunctionBegin; 2313 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2314 PetscValidType(mat); 2315 MatPreallocated(mat); 2316 PetscValidHeaderSpecific(b,VEC_COOKIE); 2317 PetscValidHeaderSpecific(x,VEC_COOKIE); 2318 PetscCheckSameComm(mat,b); 2319 PetscCheckSameComm(mat,x); 2320 if (!mat->ops->relax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2321 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2322 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2323 if (mat->N != x->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %d %d",mat->N,x->N); 2324 if (mat->M != b->N) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %d %d",mat->M,b->N); 2325 if (mat->m != b->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %d %d",mat->m,b->n); 2326 2327 ierr = PetscLogEventBegin(MAT_Relax,mat,b,x,0);CHKERRQ(ierr); 2328 ierr =(*mat->ops->relax)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 2329 ierr = PetscLogEventEnd(MAT_Relax,mat,b,x,0);CHKERRQ(ierr); 2330 PetscFunctionReturn(0); 2331 } 2332 2333 #undef __FUNCT__ 2334 #define __FUNCT__ "MatCopy_Basic" 2335 /* 2336 Default matrix copy routine. 2337 */ 2338 int MatCopy_Basic(Mat A,Mat B,MatStructure str) 2339 { 2340 int ierr,i,rstart,rend,nz,*cwork; 2341 PetscScalar *vwork; 2342 2343 PetscFunctionBegin; 2344 ierr = MatZeroEntries(B);CHKERRQ(ierr); 2345 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 2346 for (i=rstart; i<rend; i++) { 2347 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 2348 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 2349 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 2350 } 2351 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2352 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2353 PetscFunctionReturn(0); 2354 } 2355 2356 #undef __FUNCT__ 2357 #define __FUNCT__ "MatCopy" 2358 /*@C 2359 MatCopy - Copys a matrix to another matrix. 2360 2361 Collective on Mat 2362 2363 Input Parameters: 2364 + A - the matrix 2365 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 2366 2367 Output Parameter: 2368 . B - where the copy is put 2369 2370 Notes: 2371 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 2372 same nonzero pattern or the routine will crash. 2373 2374 MatCopy() copies the matrix entries of a matrix to another existing 2375 matrix (after first zeroing the second matrix). A related routine is 2376 MatConvert(), which first creates a new matrix and then copies the data. 2377 2378 Level: intermediate 2379 2380 Concepts: matrices^copying 2381 2382 .seealso: MatConvert(), MatDuplicate() 2383 2384 @*/ 2385 int MatCopy(Mat A,Mat B,MatStructure str) 2386 { 2387 int ierr; 2388 2389 PetscFunctionBegin; 2390 PetscValidHeaderSpecific(A,MAT_COOKIE); 2391 PetscValidHeaderSpecific(B,MAT_COOKIE); 2392 PetscValidType(A); 2393 MatPreallocated(A); 2394 PetscValidType(B); 2395 MatPreallocated(B); 2396 PetscCheckSameComm(A,B); 2397 if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2398 if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2399 if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%d,%d) (%d,%d)",A->M,B->M, 2400 A->N,B->N); 2401 2402 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 2403 if (A->ops->copy) { 2404 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 2405 } else { /* generic conversion */ 2406 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2407 } 2408 if (A->mapping) { 2409 if (B->mapping) {ierr = ISLocalToGlobalMappingDestroy(B->mapping);CHKERRQ(ierr);} 2410 ierr = MatSetLocalToGlobalMapping(B,A->mapping);CHKERRQ(ierr); 2411 } 2412 if (A->bmapping) { 2413 if (B->bmapping) {ierr = ISLocalToGlobalMappingDestroy(B->bmapping);CHKERRQ(ierr);} 2414 ierr = MatSetLocalToGlobalMappingBlock(B,A->mapping);CHKERRQ(ierr); 2415 } 2416 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 2417 PetscFunctionReturn(0); 2418 } 2419 2420 #include "petscsys.h" 2421 PetscTruth MatConvertRegisterAllCalled = PETSC_FALSE; 2422 PetscFList MatConvertList = 0; 2423 2424 #undef __FUNCT__ 2425 #define __FUNCT__ "MatConvertRegister" 2426 /*@C 2427 MatConvertRegister - Allows one to register a routine that reads matrices 2428 from a binary file for a particular matrix type. 2429 2430 Not Collective 2431 2432 Input Parameters: 2433 + type - the type of matrix (defined in include/petscmat.h), for example, MATSEQAIJ. 2434 - Converter - the function that reads the matrix from the binary file. 2435 2436 Level: developer 2437 2438 .seealso: MatConvertRegisterAll(), MatConvert() 2439 2440 @*/ 2441 int MatConvertRegister(char *sname,char *path,char *name,int (*function)(Mat,MatType,Mat*)) 2442 { 2443 int ierr; 2444 char fullname[PETSC_MAX_PATH_LEN]; 2445 2446 PetscFunctionBegin; 2447 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2448 ierr = PetscFListAdd(&MatConvertList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2449 PetscFunctionReturn(0); 2450 } 2451 2452 #undef __FUNCT__ 2453 #define __FUNCT__ "MatConvert" 2454 /*@C 2455 MatConvert - Converts a matrix to another matrix, either of the same 2456 or different type. 2457 2458 Collective on Mat 2459 2460 Input Parameters: 2461 + mat - the matrix 2462 - newtype - new matrix type. Use MATSAME to create a new matrix of the 2463 same type as the original matrix. 2464 2465 Output Parameter: 2466 . M - pointer to place new matrix 2467 2468 Notes: 2469 MatConvert() first creates a new matrix and then copies the data from 2470 the first matrix. A related routine is MatCopy(), which copies the matrix 2471 entries of one matrix to another already existing matrix context. 2472 2473 Level: intermediate 2474 2475 Concepts: matrices^converting between storage formats 2476 2477 .seealso: MatCopy(), MatDuplicate() 2478 @*/ 2479 int MatConvert(Mat mat,MatType newtype,Mat *M) 2480 { 2481 int ierr; 2482 PetscTruth sametype,issame,flg; 2483 char convname[256],mtype[256]; 2484 2485 PetscFunctionBegin; 2486 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2487 PetscValidType(mat); 2488 MatPreallocated(mat); 2489 PetscValidPointer(M); 2490 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2491 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2492 2493 ierr = PetscOptionsGetString(PETSC_NULL,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 2494 if (flg) { 2495 newtype = mtype; 2496 } 2497 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 2498 2499 ierr = PetscTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 2500 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 2501 if ((sametype || issame) && mat->ops->duplicate) { 2502 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 2503 } else { 2504 int (*conv)(Mat,MatType,Mat*); 2505 if (!MatConvertRegisterAllCalled) { 2506 ierr = MatConvertRegisterAll(PETSC_NULL);CHKERRQ(ierr); 2507 } 2508 ierr = PetscFListFind(mat->comm,MatConvertList,newtype,(void(**)(void))&conv);CHKERRQ(ierr); 2509 if (conv) { 2510 ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr); 2511 } else { 2512 ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr); 2513 ierr = PetscStrcat(convname,mat->type_name);CHKERRQ(ierr); 2514 ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 2515 ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 2516 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 2517 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr); 2518 if (conv) { 2519 ierr = (*conv)(mat,newtype,M);CHKERRQ(ierr); 2520 } else { 2521 if (mat->ops->convert) { 2522 ierr = (*mat->ops->convert)(mat,newtype,M);CHKERRQ(ierr); 2523 } else { 2524 ierr = MatConvert_Basic(mat,newtype,M);CHKERRQ(ierr); 2525 } 2526 } 2527 } 2528 } 2529 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 2530 PetscFunctionReturn(0); 2531 } 2532 2533 2534 #undef __FUNCT__ 2535 #define __FUNCT__ "MatDuplicate" 2536 /*@C 2537 MatDuplicate - Duplicates a matrix including the non-zero structure. 2538 2539 Collective on Mat 2540 2541 Input Parameters: 2542 + mat - the matrix 2543 - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy nonzero 2544 values as well or not 2545 2546 Output Parameter: 2547 . M - pointer to place new matrix 2548 2549 Level: intermediate 2550 2551 Concepts: matrices^duplicating 2552 2553 .seealso: MatCopy(), MatConvert() 2554 @*/ 2555 int MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 2556 { 2557 int ierr; 2558 2559 PetscFunctionBegin; 2560 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2561 PetscValidType(mat); 2562 MatPreallocated(mat); 2563 PetscValidPointer(M); 2564 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2565 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2566 2567 *M = 0; 2568 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 2569 if (!mat->ops->duplicate) { 2570 SETERRQ(PETSC_ERR_SUP,"Not written for this matrix type"); 2571 } 2572 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 2573 if (mat->mapping) { 2574 ierr = MatSetLocalToGlobalMapping(*M,mat->mapping);CHKERRQ(ierr); 2575 } 2576 if (mat->bmapping) { 2577 ierr = MatSetLocalToGlobalMappingBlock(*M,mat->mapping);CHKERRQ(ierr); 2578 } 2579 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 2580 PetscFunctionReturn(0); 2581 } 2582 2583 #undef __FUNCT__ 2584 #define __FUNCT__ "MatGetDiagonal" 2585 /*@ 2586 MatGetDiagonal - Gets the diagonal of a matrix. 2587 2588 Collective on Mat and Vec 2589 2590 Input Parameters: 2591 + mat - the matrix 2592 - v - the vector for storing the diagonal 2593 2594 Output Parameter: 2595 . v - the diagonal of the matrix 2596 2597 Notes: 2598 For the SeqAIJ matrix format, this routine may also be called 2599 on a LU factored matrix; in that case it routines the reciprocal of 2600 the diagonal entries in U. It returns the entries permuted by the 2601 row and column permutation used during the symbolic factorization. 2602 2603 Level: intermediate 2604 2605 Concepts: matrices^accessing diagonals 2606 2607 .seealso: MatGetRow(), MatGetSubmatrices(), MatGetSubmatrix(), MatGetRowMax() 2608 @*/ 2609 int MatGetDiagonal(Mat mat,Vec v) 2610 { 2611 int ierr; 2612 2613 PetscFunctionBegin; 2614 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2615 PetscValidType(mat); 2616 MatPreallocated(mat); 2617 PetscValidHeaderSpecific(v,VEC_COOKIE); 2618 /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */ 2619 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2620 if (!mat->ops->getdiagonal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2621 2622 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 2623 PetscFunctionReturn(0); 2624 } 2625 2626 #undef __FUNCT__ 2627 #define __FUNCT__ "MatGetRowMax" 2628 /*@ 2629 MatGetRowMax - Gets the maximum value (in absolute value) of each 2630 row of the matrix 2631 2632 Collective on Mat and Vec 2633 2634 Input Parameters: 2635 . mat - the matrix 2636 2637 Output Parameter: 2638 . v - the vector for storing the maximums 2639 2640 Level: intermediate 2641 2642 Concepts: matrices^getting row maximums 2643 2644 .seealso: MatGetDiagonal(), MatGetSubmatrices(), MatGetSubmatrix() 2645 @*/ 2646 int MatGetRowMax(Mat mat,Vec v) 2647 { 2648 int ierr; 2649 2650 PetscFunctionBegin; 2651 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2652 PetscValidType(mat); 2653 MatPreallocated(mat); 2654 PetscValidHeaderSpecific(v,VEC_COOKIE); 2655 /* PetscCheckSameComm(mat,v); Could be MPI vector but Seq matrix cause of two submatrix storage */ 2656 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2657 if (!mat->ops->getrowmax) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2658 2659 ierr = (*mat->ops->getrowmax)(mat,v);CHKERRQ(ierr); 2660 PetscFunctionReturn(0); 2661 } 2662 2663 #undef __FUNCT__ 2664 #define __FUNCT__ "MatTranspose" 2665 /*@C 2666 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 2667 2668 Collective on Mat 2669 2670 Input Parameter: 2671 . mat - the matrix to transpose 2672 2673 Output Parameters: 2674 . B - the transpose (or pass in PETSC_NULL for an in-place transpose) 2675 2676 Level: intermediate 2677 2678 Concepts: matrices^transposing 2679 2680 .seealso: MatMultTranspose(), MatMultTransposeAdd() 2681 @*/ 2682 int MatTranspose(Mat mat,Mat *B) 2683 { 2684 int ierr; 2685 2686 PetscFunctionBegin; 2687 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2688 PetscValidType(mat); 2689 MatPreallocated(mat); 2690 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2691 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2692 if (!mat->ops->transpose) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2693 2694 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 2695 ierr = (*mat->ops->transpose)(mat,B);CHKERRQ(ierr); 2696 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 2697 PetscFunctionReturn(0); 2698 } 2699 2700 #undef __FUNCT__ 2701 #define __FUNCT__ "MatPermute" 2702 /*@C 2703 MatPermute - Creates a new matrix with rows and columns permuted from the 2704 original. 2705 2706 Collective on Mat 2707 2708 Input Parameters: 2709 + mat - the matrix to permute 2710 . row - row permutation, each processor supplies only the permutation for its rows 2711 - col - column permutation, each processor needs the entire column permutation, that is 2712 this is the same size as the total number of columns in the matrix 2713 2714 Output Parameters: 2715 . B - the permuted matrix 2716 2717 Level: advanced 2718 2719 Concepts: matrices^permuting 2720 2721 .seealso: MatGetOrdering() 2722 @*/ 2723 int MatPermute(Mat mat,IS row,IS col,Mat *B) 2724 { 2725 int ierr; 2726 2727 PetscFunctionBegin; 2728 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2729 PetscValidType(mat); 2730 MatPreallocated(mat); 2731 PetscValidHeaderSpecific(row,IS_COOKIE); 2732 PetscValidHeaderSpecific(col,IS_COOKIE); 2733 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2734 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2735 if (!mat->ops->permute) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2736 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 2737 PetscFunctionReturn(0); 2738 } 2739 2740 #undef __FUNCT__ 2741 #define __FUNCT__ "MatPermuteSparsify" 2742 /*@C 2743 MatPermuteSparsify - Creates a new matrix with rows and columns permuted from the 2744 original and sparsified to the prescribed tolerance. 2745 2746 Collective on Mat 2747 2748 Input Parameters: 2749 + A - The matrix to permute 2750 . band - The half-bandwidth of the sparsified matrix, or PETSC_DECIDE 2751 . frac - The half-bandwidth as a fraction of the total size, or 0.0 2752 . tol - The drop tolerance 2753 . rowp - The row permutation 2754 - colp - The column permutation 2755 2756 Output Parameter: 2757 . B - The permuted, sparsified matrix 2758 2759 Level: advanced 2760 2761 Note: 2762 The default behavior (band = PETSC_DECIDE and frac = 0.0) is to 2763 restrict the half-bandwidth of the resulting matrix to 5% of the 2764 total matrix size. 2765 2766 .keywords: matrix, permute, sparsify 2767 2768 .seealso: MatGetOrdering(), MatPermute() 2769 @*/ 2770 int MatPermuteSparsify(Mat A, int band, PetscReal frac, PetscReal tol, IS rowp, IS colp, Mat *B) 2771 { 2772 IS irowp, icolp; 2773 int *rows, *cols; 2774 int M, N, locRowStart, locRowEnd; 2775 int nz, newNz; 2776 int *cwork, *cnew; 2777 PetscScalar *vwork, *vnew; 2778 int bw, size; 2779 int row, locRow, newRow, col, newCol; 2780 int ierr; 2781 2782 PetscFunctionBegin; 2783 PetscValidHeaderSpecific(A, MAT_COOKIE); 2784 PetscValidHeaderSpecific(rowp, IS_COOKIE); 2785 PetscValidHeaderSpecific(colp, IS_COOKIE); 2786 if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2787 if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2788 if (!A->ops->permutesparsify) { 2789 ierr = MatGetSize(A, &M, &N); CHKERRQ(ierr); 2790 ierr = MatGetOwnershipRange(A, &locRowStart, &locRowEnd); CHKERRQ(ierr); 2791 ierr = ISGetSize(rowp, &size); CHKERRQ(ierr); 2792 if (size != M) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for row permutation, should be %d", size, M); 2793 ierr = ISGetSize(colp, &size); CHKERRQ(ierr); 2794 if (size != N) SETERRQ2(PETSC_ERR_ARG_WRONG, "Wrong size %d for column permutation, should be %d", size, N); 2795 ierr = ISInvertPermutation(rowp, 0, &irowp); CHKERRQ(ierr); 2796 ierr = ISGetIndices(irowp, &rows); CHKERRQ(ierr); 2797 ierr = ISInvertPermutation(colp, 0, &icolp); CHKERRQ(ierr); 2798 ierr = ISGetIndices(icolp, &cols); CHKERRQ(ierr); 2799 ierr = PetscMalloc(N * sizeof(int), &cnew); CHKERRQ(ierr); 2800 ierr = PetscMalloc(N * sizeof(PetscScalar), &vnew); CHKERRQ(ierr); 2801 2802 /* Setup bandwidth to include */ 2803 if (band == PETSC_DECIDE) { 2804 if (frac <= 0.0) 2805 bw = (int) (M * 0.05); 2806 else 2807 bw = (int) (M * frac); 2808 } else { 2809 if (band <= 0) SETERRQ(PETSC_ERR_ARG_WRONG, "Bandwidth must be a positive integer"); 2810 bw = band; 2811 } 2812 2813 /* Put values into new matrix */ 2814 ierr = MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, B); CHKERRQ(ierr); 2815 for(row = locRowStart, locRow = 0; row < locRowEnd; row++, locRow++) { 2816 ierr = MatGetRow(A, row, &nz, &cwork, &vwork); CHKERRQ(ierr); 2817 newRow = rows[locRow]+locRowStart; 2818 for(col = 0, newNz = 0; col < nz; col++) { 2819 newCol = cols[cwork[col]]; 2820 if ((newCol >= newRow - bw) && (newCol < newRow + bw) && (PetscAbsScalar(vwork[col]) >= tol)) { 2821 cnew[newNz] = newCol; 2822 vnew[newNz] = vwork[col]; 2823 newNz++; 2824 } 2825 } 2826 ierr = MatSetValues(*B, 1, &newRow, newNz, cnew, vnew, INSERT_VALUES); CHKERRQ(ierr); 2827 ierr = MatRestoreRow(A, row, &nz, &cwork, &vwork); CHKERRQ(ierr); 2828 } 2829 ierr = PetscFree(cnew); CHKERRQ(ierr); 2830 ierr = PetscFree(vnew); CHKERRQ(ierr); 2831 ierr = MatAssemblyBegin(*B, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2832 ierr = MatAssemblyEnd(*B, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2833 ierr = ISRestoreIndices(irowp, &rows); CHKERRQ(ierr); 2834 ierr = ISRestoreIndices(icolp, &cols); CHKERRQ(ierr); 2835 ierr = ISDestroy(irowp); CHKERRQ(ierr); 2836 ierr = ISDestroy(icolp); CHKERRQ(ierr); 2837 } else { 2838 ierr = (*A->ops->permutesparsify)(A, band, frac, tol, rowp, colp, B); CHKERRQ(ierr); 2839 } 2840 PetscFunctionReturn(0); 2841 } 2842 2843 #undef __FUNCT__ 2844 #define __FUNCT__ "MatEqual" 2845 /*@ 2846 MatEqual - Compares two matrices. 2847 2848 Collective on Mat 2849 2850 Input Parameters: 2851 + A - the first matrix 2852 - B - the second matrix 2853 2854 Output Parameter: 2855 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 2856 2857 Level: intermediate 2858 2859 Concepts: matrices^equality between 2860 @*/ 2861 int MatEqual(Mat A,Mat B,PetscTruth *flg) 2862 { 2863 int ierr; 2864 2865 PetscFunctionBegin; 2866 PetscValidHeaderSpecific(A,MAT_COOKIE); 2867 PetscValidHeaderSpecific(B,MAT_COOKIE); 2868 PetscValidType(A); 2869 MatPreallocated(A); 2870 PetscValidType(B); 2871 MatPreallocated(B); 2872 PetscValidIntPointer(flg); 2873 PetscCheckSameComm(A,B); 2874 if (!A->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2875 if (!B->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2876 if (A->M != B->M || A->N != B->N) SETERRQ4(PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %d %d %d %d",A->M,B->M,A->N,B->N); 2877 if (!A->ops->equal) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",A->type_name); 2878 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 2879 PetscFunctionReturn(0); 2880 } 2881 2882 #undef __FUNCT__ 2883 #define __FUNCT__ "MatDiagonalScale" 2884 /*@ 2885 MatDiagonalScale - Scales a matrix on the left and right by diagonal 2886 matrices that are stored as vectors. Either of the two scaling 2887 matrices can be PETSC_NULL. 2888 2889 Collective on Mat 2890 2891 Input Parameters: 2892 + mat - the matrix to be scaled 2893 . l - the left scaling vector (or PETSC_NULL) 2894 - r - the right scaling vector (or PETSC_NULL) 2895 2896 Notes: 2897 MatDiagonalScale() computes A = LAR, where 2898 L = a diagonal matrix, R = a diagonal matrix 2899 2900 Level: intermediate 2901 2902 Concepts: matrices^diagonal scaling 2903 Concepts: diagonal scaling of matrices 2904 2905 .seealso: MatScale() 2906 @*/ 2907 int MatDiagonalScale(Mat mat,Vec l,Vec r) 2908 { 2909 int ierr; 2910 2911 PetscFunctionBegin; 2912 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2913 PetscValidType(mat); 2914 MatPreallocated(mat); 2915 if (!mat->ops->diagonalscale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2916 if (l) {PetscValidHeaderSpecific(l,VEC_COOKIE);PetscCheckSameComm(mat,l);} 2917 if (r) {PetscValidHeaderSpecific(r,VEC_COOKIE);PetscCheckSameComm(mat,r);} 2918 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2919 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2920 2921 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 2922 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 2923 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 2924 PetscFunctionReturn(0); 2925 } 2926 2927 #undef __FUNCT__ 2928 #define __FUNCT__ "MatScale" 2929 /*@ 2930 MatScale - Scales all elements of a matrix by a given number. 2931 2932 Collective on Mat 2933 2934 Input Parameters: 2935 + mat - the matrix to be scaled 2936 - a - the scaling value 2937 2938 Output Parameter: 2939 . mat - the scaled matrix 2940 2941 Level: intermediate 2942 2943 Concepts: matrices^scaling all entries 2944 2945 .seealso: MatDiagonalScale() 2946 @*/ 2947 int MatScale(PetscScalar *a,Mat mat) 2948 { 2949 int ierr; 2950 2951 PetscFunctionBegin; 2952 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2953 PetscValidType(mat); 2954 MatPreallocated(mat); 2955 PetscValidScalarPointer(a); 2956 if (!mat->ops->scale) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2957 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2958 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2959 2960 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 2961 ierr = (*mat->ops->scale)(a,mat);CHKERRQ(ierr); 2962 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 2963 PetscFunctionReturn(0); 2964 } 2965 2966 #undef __FUNCT__ 2967 #define __FUNCT__ "MatNorm" 2968 /*@ 2969 MatNorm - Calculates various norms of a matrix. 2970 2971 Collective on Mat 2972 2973 Input Parameters: 2974 + mat - the matrix 2975 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 2976 2977 Output Parameters: 2978 . nrm - the resulting norm 2979 2980 Level: intermediate 2981 2982 Concepts: matrices^norm 2983 Concepts: norm^of matrix 2984 @*/ 2985 int MatNorm(Mat mat,NormType type,PetscReal *nrm) 2986 { 2987 int ierr; 2988 2989 PetscFunctionBegin; 2990 PetscValidHeaderSpecific(mat,MAT_COOKIE); 2991 PetscValidType(mat); 2992 MatPreallocated(mat); 2993 PetscValidScalarPointer(nrm); 2994 2995 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2996 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2997 if (!mat->ops->norm) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 2998 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 2999 PetscFunctionReturn(0); 3000 } 3001 3002 /* 3003 This variable is used to prevent counting of MatAssemblyBegin() that 3004 are called from within a MatAssemblyEnd(). 3005 */ 3006 static int MatAssemblyEnd_InUse = 0; 3007 #undef __FUNCT__ 3008 #define __FUNCT__ "MatAssemblyBegin" 3009 /*@ 3010 MatAssemblyBegin - Begins assembling the matrix. This routine should 3011 be called after completing all calls to MatSetValues(). 3012 3013 Collective on Mat 3014 3015 Input Parameters: 3016 + mat - the matrix 3017 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 3018 3019 Notes: 3020 MatSetValues() generally caches the values. The matrix is ready to 3021 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 3022 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 3023 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 3024 using the matrix. 3025 3026 Level: beginner 3027 3028 Concepts: matrices^assembling 3029 3030 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 3031 @*/ 3032 int MatAssemblyBegin(Mat mat,MatAssemblyType type) 3033 { 3034 int ierr; 3035 3036 PetscFunctionBegin; 3037 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3038 PetscValidType(mat); 3039 MatPreallocated(mat); 3040 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 3041 if (mat->assembled) { 3042 mat->was_assembled = PETSC_TRUE; 3043 mat->assembled = PETSC_FALSE; 3044 } 3045 if (!MatAssemblyEnd_InUse) { 3046 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 3047 if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 3048 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 3049 } else { 3050 if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 3051 } 3052 PetscFunctionReturn(0); 3053 } 3054 3055 #undef __FUNCT__ 3056 #define __FUNCT__ "MatAssembed" 3057 /*@ 3058 MatAssembled - Indicates if a matrix has been assembled and is ready for 3059 use; for example, in matrix-vector product. 3060 3061 Collective on Mat 3062 3063 Input Parameter: 3064 . mat - the matrix 3065 3066 Output Parameter: 3067 . assembled - PETSC_TRUE or PETSC_FALSE 3068 3069 Level: advanced 3070 3071 Concepts: matrices^assembled? 3072 3073 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 3074 @*/ 3075 int MatAssembled(Mat mat,PetscTruth *assembled) 3076 { 3077 PetscFunctionBegin; 3078 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3079 PetscValidType(mat); 3080 MatPreallocated(mat); 3081 *assembled = mat->assembled; 3082 PetscFunctionReturn(0); 3083 } 3084 3085 #undef __FUNCT__ 3086 #define __FUNCT__ "MatView_Private" 3087 /* 3088 Processes command line options to determine if/how a matrix 3089 is to be viewed. Called by MatAssemblyEnd() and MatLoad(). 3090 */ 3091 int MatView_Private(Mat mat) 3092 { 3093 int ierr; 3094 PetscTruth flg; 3095 3096 PetscFunctionBegin; 3097 ierr = PetscOptionsBegin(mat->comm,mat->prefix,"Matrix Options","Mat");CHKERRQ(ierr); 3098 ierr = PetscOptionsName("-mat_view_info","Information on matrix size","MatView",&flg);CHKERRQ(ierr); 3099 if (flg) { 3100 ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 3101 ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr); 3102 ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr); 3103 } 3104 ierr = PetscOptionsName("-mat_view_info_detailed","Nonzeros in the matrix","MatView",&flg);CHKERRQ(ierr); 3105 if (flg) { 3106 ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); 3107 ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr); 3108 ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr); 3109 } 3110 ierr = PetscOptionsName("-mat_view","Print matrix to stdout","MatView",&flg);CHKERRQ(ierr); 3111 if (flg) { 3112 ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr); 3113 } 3114 ierr = PetscOptionsName("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",&flg);CHKERRQ(ierr); 3115 if (flg) { 3116 ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(mat->comm),PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3117 ierr = MatView(mat,PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr); 3118 ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(mat->comm));CHKERRQ(ierr); 3119 } 3120 ierr = PetscOptionsName("-mat_view_draw","Plot nonzero pattern of matrix","MatView",&flg);CHKERRQ(ierr); 3121 if (flg) { 3122 ierr = PetscOptionsName("-mat_view_contour","Use colors to indicate size of matrix elements","MatView",&flg);CHKERRQ(ierr); 3123 if (flg) { 3124 PetscViewerPushFormat(PETSC_VIEWER_DRAW_(mat->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 3125 } 3126 ierr = MatView(mat,PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); 3127 ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); 3128 if (flg) { 3129 PetscViewerPopFormat(PETSC_VIEWER_DRAW_(mat->comm));CHKERRQ(ierr); 3130 } 3131 } 3132 ierr = PetscOptionsName("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",&flg);CHKERRQ(ierr); 3133 if (flg) { 3134 ierr = MatView(mat,PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr); 3135 ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(mat->comm));CHKERRQ(ierr); 3136 } 3137 ierr = PetscOptionsName("-mat_view_binary","Save matrix to file in binary format","MatView",&flg);CHKERRQ(ierr); 3138 if (flg) { 3139 ierr = MatView(mat,PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr); 3140 ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(mat->comm));CHKERRQ(ierr); 3141 } 3142 ierr = PetscOptionsEnd();CHKERRQ(ierr); 3143 PetscFunctionReturn(0); 3144 } 3145 3146 #undef __FUNCT__ 3147 #define __FUNCT__ "MatAssemblyEnd" 3148 /*@ 3149 MatAssemblyEnd - Completes assembling the matrix. This routine should 3150 be called after MatAssemblyBegin(). 3151 3152 Collective on Mat 3153 3154 Input Parameters: 3155 + mat - the matrix 3156 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 3157 3158 Options Database Keys: 3159 + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly() 3160 . -mat_view_info_detailed - Prints more detailed info 3161 . -mat_view - Prints matrix in ASCII format 3162 . -mat_view_matlab - Prints matrix in Matlab format 3163 . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 3164 . -display <name> - Sets display name (default is host) 3165 . -draw_pause <sec> - Sets number of seconds to pause after display 3166 . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see users manual) 3167 . -viewer_socket_machine <machine> 3168 . -viewer_socket_port <port> 3169 . -mat_view_binary - save matrix to file in binary format 3170 - -viewer_binary_filename <name> 3171 3172 Notes: 3173 MatSetValues() generally caches the values. The matrix is ready to 3174 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 3175 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 3176 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 3177 using the matrix. 3178 3179 Level: beginner 3180 3181 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen() 3182 @*/ 3183 int MatAssemblyEnd(Mat mat,MatAssemblyType type) 3184 { 3185 int ierr; 3186 static int inassm = 0; 3187 PetscTruth flg; 3188 3189 PetscFunctionBegin; 3190 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3191 PetscValidType(mat); 3192 MatPreallocated(mat); 3193 3194 inassm++; 3195 MatAssemblyEnd_InUse++; 3196 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 3197 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 3198 if (mat->ops->assemblyend) { 3199 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 3200 } 3201 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 3202 } else { 3203 if (mat->ops->assemblyend) { 3204 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 3205 } 3206 } 3207 3208 /* Flush assembly is not a true assembly */ 3209 if (type != MAT_FLUSH_ASSEMBLY) { 3210 mat->assembled = PETSC_TRUE; mat->num_ass++; 3211 } 3212 mat->insertmode = NOT_SET_VALUES; 3213 MatAssemblyEnd_InUse--; 3214 3215 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 3216 ierr = MatView_Private(mat);CHKERRQ(ierr); 3217 } 3218 inassm--; 3219 ierr = PetscOptionsHasName(mat->prefix,"-help",&flg);CHKERRQ(ierr); 3220 if (flg) { 3221 ierr = MatPrintHelp(mat);CHKERRQ(ierr); 3222 } 3223 PetscFunctionReturn(0); 3224 } 3225 3226 3227 #undef __FUNCT__ 3228 #define __FUNCT__ "MatCompress" 3229 /*@ 3230 MatCompress - Tries to store the matrix in as little space as 3231 possible. May fail if memory is already fully used, since it 3232 tries to allocate new space. 3233 3234 Collective on Mat 3235 3236 Input Parameters: 3237 . mat - the matrix 3238 3239 Level: advanced 3240 3241 @*/ 3242 int MatCompress(Mat mat) 3243 { 3244 int ierr; 3245 3246 PetscFunctionBegin; 3247 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3248 PetscValidType(mat); 3249 MatPreallocated(mat); 3250 if (mat->ops->compress) {ierr = (*mat->ops->compress)(mat);CHKERRQ(ierr);} 3251 PetscFunctionReturn(0); 3252 } 3253 3254 #undef __FUNCT__ 3255 #define __FUNCT__ "MatSetOption" 3256 /*@ 3257 MatSetOption - Sets a parameter option for a matrix. Some options 3258 may be specific to certain storage formats. Some options 3259 determine how values will be inserted (or added). Sorted, 3260 row-oriented input will generally assemble the fastest. The default 3261 is row-oriented, nonsorted input. 3262 3263 Collective on Mat 3264 3265 Input Parameters: 3266 + mat - the matrix 3267 - option - the option, one of those listed below (and possibly others), 3268 e.g., MAT_ROWS_SORTED, MAT_NEW_NONZERO_LOCATION_ERR 3269 3270 Options Describing Matrix Structure: 3271 + MAT_SYMMETRIC - symmetric in terms of both structure and value 3272 - MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 3273 3274 Options For Use with MatSetValues(): 3275 Insert a logically dense subblock, which can be 3276 + MAT_ROW_ORIENTED - row-oriented (default) 3277 . MAT_COLUMN_ORIENTED - column-oriented 3278 . MAT_ROWS_SORTED - sorted by row 3279 . MAT_ROWS_UNSORTED - not sorted by row (default) 3280 . MAT_COLUMNS_SORTED - sorted by column 3281 - MAT_COLUMNS_UNSORTED - not sorted by column (default) 3282 3283 Not these options reflect the data you pass in with MatSetValues(); it has 3284 nothing to do with how the data is stored internally in the matrix 3285 data structure. 3286 3287 When (re)assembling a matrix, we can restrict the input for 3288 efficiency/debugging purposes. These options include 3289 + MAT_NO_NEW_NONZERO_LOCATIONS - additional insertions will not be 3290 allowed if they generate a new nonzero 3291 . MAT_YES_NEW_NONZERO_LOCATIONS - additional insertions will be allowed 3292 . MAT_NO_NEW_DIAGONALS - additional insertions will not be allowed if 3293 they generate a nonzero in a new diagonal (for block diagonal format only) 3294 . MAT_YES_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 3295 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 3296 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 3297 - MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 3298 3299 Notes: 3300 Some options are relevant only for particular matrix types and 3301 are thus ignored by others. Other options are not supported by 3302 certain matrix types and will generate an error message if set. 3303 3304 If using a Fortran 77 module to compute a matrix, one may need to 3305 use the column-oriented option (or convert to the row-oriented 3306 format). 3307 3308 MAT_NO_NEW_NONZERO_LOCATIONS indicates that any add or insertion 3309 that would generate a new entry in the nonzero structure is instead 3310 ignored. Thus, if memory has not alredy been allocated for this particular 3311 data, then the insertion is ignored. For dense matrices, in which 3312 the entire array is allocated, no entries are ever ignored. 3313 Set after the first MatAssemblyEnd() 3314 3315 MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion 3316 that would generate a new entry in the nonzero structure instead produces 3317 an error. (Currently supported for AIJ and BAIJ formats only.) 3318 This is a useful flag when using SAME_NONZERO_PATTERN in calling 3319 SLESSetOperators() to ensure that the nonzero pattern truely does 3320 remain unchanged. Set after the first MatAssemblyEnd() 3321 3322 MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion 3323 that would generate a new entry that has not been preallocated will 3324 instead produce an error. (Currently supported for AIJ and BAIJ formats 3325 only.) This is a useful flag when debugging matrix memory preallocation. 3326 3327 MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 3328 other processors should be dropped, rather than stashed. 3329 This is useful if you know that the "owning" processor is also 3330 always generating the correct matrix entries, so that PETSc need 3331 not transfer duplicate entries generated on another processor. 3332 3333 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 3334 searches during matrix assembly. When this flag is set, the hash table 3335 is created during the first Matrix Assembly. This hash table is 3336 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 3337 to improve the searching of indices. MAT_NO_NEW_NONZERO_LOCATIONS flag 3338 should be used with MAT_USE_HASH_TABLE flag. This option is currently 3339 supported by MATMPIBAIJ format only. 3340 3341 MAT_KEEP_ZEROED_ROWS indicates when MatZeroRows() is called the zeroed entries 3342 are kept in the nonzero structure 3343 3344 MAT_IGNORE_ZERO_ENTRIES - when using ADD_VALUES for AIJ matrices this will stop 3345 zero values from creating a zero location in the matrix 3346 3347 MAT_USE_INODES - indicates using inode version of the code - works with AIJ and 3348 ROWBS matrix types 3349 3350 MAT_DO_NOT_USE_INODES - indicates not using inode version of the code - works 3351 with AIJ and ROWBS matrix types 3352 3353 Level: intermediate 3354 3355 Concepts: matrices^setting options 3356 3357 @*/ 3358 int MatSetOption(Mat mat,MatOption op) 3359 { 3360 int ierr; 3361 3362 PetscFunctionBegin; 3363 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3364 PetscValidType(mat); 3365 MatPreallocated(mat); 3366 switch (op) { 3367 case MAT_SYMMETRIC: 3368 mat->symmetric = PETSC_TRUE; 3369 mat->structurally_symmetric = PETSC_TRUE; 3370 break; 3371 case MAT_STRUCTURALLY_SYMMETRIC: 3372 mat->structurally_symmetric = PETSC_TRUE; 3373 break; 3374 default: 3375 if (mat->ops->setoption) {ierr = (*mat->ops->setoption)(mat,op);CHKERRQ(ierr);} 3376 break; 3377 } 3378 PetscFunctionReturn(0); 3379 } 3380 3381 #undef __FUNCT__ 3382 #define __FUNCT__ "MatZeroEntries" 3383 /*@ 3384 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 3385 this routine retains the old nonzero structure. 3386 3387 Collective on Mat 3388 3389 Input Parameters: 3390 . mat - the matrix 3391 3392 Level: intermediate 3393 3394 Concepts: matrices^zeroing 3395 3396 .seealso: MatZeroRows() 3397 @*/ 3398 int MatZeroEntries(Mat mat) 3399 { 3400 int ierr; 3401 3402 PetscFunctionBegin; 3403 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3404 PetscValidType(mat); 3405 MatPreallocated(mat); 3406 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3407 if (!mat->ops->zeroentries) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 3408 3409 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 3410 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 3411 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 3412 PetscFunctionReturn(0); 3413 } 3414 3415 #undef __FUNCT__ 3416 #define __FUNCT__ "MatZeroRows" 3417 /*@C 3418 MatZeroRows - Zeros all entries (except possibly the main diagonal) 3419 of a set of rows of a matrix. 3420 3421 Collective on Mat 3422 3423 Input Parameters: 3424 + mat - the matrix 3425 . is - index set of rows to remove 3426 - diag - pointer to value put in all diagonals of eliminated rows. 3427 Note that diag is not a pointer to an array, but merely a 3428 pointer to a single value. 3429 3430 Notes: 3431 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 3432 but does not release memory. For the dense and block diagonal 3433 formats this does not alter the nonzero structure. 3434 3435 If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure 3436 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 3437 merely zeroed. 3438 3439 The user can set a value in the diagonal entry (or for the AIJ and 3440 row formats can optionally remove the main diagonal entry from the 3441 nonzero structure as well, by passing a null pointer (PETSC_NULL 3442 in C or PETSC_NULL_SCALAR in Fortran) as the final argument). 3443 3444 For the parallel case, all processes that share the matrix (i.e., 3445 those in the communicator used for matrix creation) MUST call this 3446 routine, regardless of whether any rows being zeroed are owned by 3447 them. 3448 3449 3450 Level: intermediate 3451 3452 Concepts: matrices^zeroing rows 3453 3454 .seealso: MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 3455 @*/ 3456 int MatZeroRows(Mat mat,IS is,PetscScalar *diag) 3457 { 3458 int ierr; 3459 3460 PetscFunctionBegin; 3461 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3462 PetscValidType(mat); 3463 MatPreallocated(mat); 3464 PetscValidHeaderSpecific(is,IS_COOKIE); 3465 if (diag) PetscValidScalarPointer(diag); 3466 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3467 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3468 if (!mat->ops->zerorows) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 3469 3470 ierr = (*mat->ops->zerorows)(mat,is,diag);CHKERRQ(ierr); 3471 ierr = MatView_Private(mat);CHKERRQ(ierr); 3472 PetscFunctionReturn(0); 3473 } 3474 3475 #undef __FUNCT__ 3476 #define __FUNCT__ "MatZeroRowsLocal" 3477 /*@C 3478 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 3479 of a set of rows of a matrix; using local numbering of rows. 3480 3481 Collective on Mat 3482 3483 Input Parameters: 3484 + mat - the matrix 3485 . is - index set of rows to remove 3486 - diag - pointer to value put in all diagonals of eliminated rows. 3487 Note that diag is not a pointer to an array, but merely a 3488 pointer to a single value. 3489 3490 Notes: 3491 Before calling MatZeroRowsLocal(), the user must first set the 3492 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 3493 3494 For the AIJ matrix formats this removes the old nonzero structure, 3495 but does not release memory. For the dense and block diagonal 3496 formats this does not alter the nonzero structure. 3497 3498 If the option MatSetOption(mat,MAT_KEEP_ZEROED_ROWS) the nonzero structure 3499 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 3500 merely zeroed. 3501 3502 The user can set a value in the diagonal entry (or for the AIJ and 3503 row formats can optionally remove the main diagonal entry from the 3504 nonzero structure as well, by passing a null pointer (PETSC_NULL 3505 in C or PETSC_NULL_SCALAR in Fortran) as the final argument). 3506 3507 Level: intermediate 3508 3509 Concepts: matrices^zeroing 3510 3511 .seealso: MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 3512 @*/ 3513 int MatZeroRowsLocal(Mat mat,IS is,PetscScalar *diag) 3514 { 3515 int ierr; 3516 IS newis; 3517 3518 PetscFunctionBegin; 3519 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3520 PetscValidType(mat); 3521 MatPreallocated(mat); 3522 PetscValidHeaderSpecific(is,IS_COOKIE); 3523 if (diag) PetscValidScalarPointer(diag); 3524 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3525 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3526 3527 if (mat->ops->zerorowslocal) { 3528 ierr = (*mat->ops->zerorowslocal)(mat,is,diag);CHKERRQ(ierr); 3529 } else { 3530 if (!mat->mapping) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 3531 ierr = ISLocalToGlobalMappingApplyIS(mat->mapping,is,&newis);CHKERRQ(ierr); 3532 ierr = (*mat->ops->zerorows)(mat,newis,diag);CHKERRQ(ierr); 3533 ierr = ISDestroy(newis);CHKERRQ(ierr); 3534 } 3535 PetscFunctionReturn(0); 3536 } 3537 3538 #undef __FUNCT__ 3539 #define __FUNCT__ "MatGetSize" 3540 /*@ 3541 MatGetSize - Returns the numbers of rows and columns in a matrix. 3542 3543 Not Collective 3544 3545 Input Parameter: 3546 . mat - the matrix 3547 3548 Output Parameters: 3549 + m - the number of global rows 3550 - n - the number of global columns 3551 3552 Level: beginner 3553 3554 Concepts: matrices^size 3555 3556 .seealso: MatGetLocalSize() 3557 @*/ 3558 int MatGetSize(Mat mat,int *m,int* n) 3559 { 3560 PetscFunctionBegin; 3561 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3562 if (m) *m = mat->M; 3563 if (n) *n = mat->N; 3564 PetscFunctionReturn(0); 3565 } 3566 3567 #undef __FUNCT__ 3568 #define __FUNCT__ "MatGetLocalSize" 3569 /*@ 3570 MatGetLocalSize - Returns the number of rows and columns in a matrix 3571 stored locally. This information may be implementation dependent, so 3572 use with care. 3573 3574 Not Collective 3575 3576 Input Parameters: 3577 . mat - the matrix 3578 3579 Output Parameters: 3580 + m - the number of local rows 3581 - n - the number of local columns 3582 3583 Level: beginner 3584 3585 Concepts: matrices^local size 3586 3587 .seealso: MatGetSize() 3588 @*/ 3589 int MatGetLocalSize(Mat mat,int *m,int* n) 3590 { 3591 PetscFunctionBegin; 3592 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3593 if (m) *m = mat->m; 3594 if (n) *n = mat->n; 3595 PetscFunctionReturn(0); 3596 } 3597 3598 #undef __FUNCT__ 3599 #define __FUNCT__ "MatGetOwnershipRange" 3600 /*@ 3601 MatGetOwnershipRange - Returns the range of matrix rows owned by 3602 this processor, assuming that the matrix is laid out with the first 3603 n1 rows on the first processor, the next n2 rows on the second, etc. 3604 For certain parallel layouts this range may not be well defined. 3605 3606 Not Collective 3607 3608 Input Parameters: 3609 . mat - the matrix 3610 3611 Output Parameters: 3612 + m - the global index of the first local row 3613 - n - one more than the global index of the last local row 3614 3615 Level: beginner 3616 3617 Concepts: matrices^row ownership 3618 @*/ 3619 int MatGetOwnershipRange(Mat mat,int *m,int* n) 3620 { 3621 int ierr; 3622 3623 PetscFunctionBegin; 3624 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3625 PetscValidType(mat); 3626 MatPreallocated(mat); 3627 if (m) PetscValidIntPointer(m); 3628 if (n) PetscValidIntPointer(n); 3629 ierr = PetscMapGetLocalRange(mat->rmap,m,n);CHKERRQ(ierr); 3630 PetscFunctionReturn(0); 3631 } 3632 3633 #undef __FUNCT__ 3634 #define __FUNCT__ "MatILUFactorSymbolic" 3635 /*@ 3636 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 3637 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 3638 to complete the factorization. 3639 3640 Collective on Mat 3641 3642 Input Parameters: 3643 + mat - the matrix 3644 . row - row permutation 3645 . column - column permutation 3646 - info - structure containing 3647 $ levels - number of levels of fill. 3648 $ expected fill - as ratio of original fill. 3649 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3650 missing diagonal entries) 3651 3652 Output Parameters: 3653 . fact - new matrix that has been symbolically factored 3654 3655 Notes: 3656 See the users manual for additional information about 3657 choosing the fill factor for better efficiency. 3658 3659 Most users should employ the simplified SLES interface for linear solvers 3660 instead of working directly with matrix algebra routines such as this. 3661 See, e.g., SLESCreate(). 3662 3663 Level: developer 3664 3665 Concepts: matrices^symbolic LU factorization 3666 Concepts: matrices^factorization 3667 Concepts: LU^symbolic factorization 3668 3669 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 3670 MatGetOrdering(), MatILUInfo 3671 3672 @*/ 3673 int MatILUFactorSymbolic(Mat mat,IS row,IS col,MatILUInfo *info,Mat *fact) 3674 { 3675 int ierr; 3676 3677 PetscFunctionBegin; 3678 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3679 PetscValidType(mat); 3680 MatPreallocated(mat); 3681 PetscValidPointer(fact); 3682 PetscValidHeaderSpecific(row,IS_COOKIE); 3683 PetscValidHeaderSpecific(col,IS_COOKIE); 3684 if (info && info->levels < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %d",(int)info->levels); 3685 if (info && info->fill < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",info->fill); 3686 if (!mat->ops->ilufactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ILU",mat->type_name); 3687 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3688 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3689 3690 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3691 ierr = (*mat->ops->ilufactorsymbolic)(mat,row,col,info,fact);CHKERRQ(ierr); 3692 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3693 PetscFunctionReturn(0); 3694 } 3695 3696 #undef __FUNCT__ 3697 #define __FUNCT__ "MatICCFactorSymbolic" 3698 /*@ 3699 MatICCFactorSymbolic - Performs symbolic incomplete 3700 Cholesky factorization for a symmetric matrix. Use 3701 MatCholeskyFactorNumeric() to complete the factorization. 3702 3703 Collective on Mat 3704 3705 Input Parameters: 3706 + mat - the matrix 3707 . perm - row and column permutation 3708 . fill - levels of fill 3709 - f - expected fill as ratio of original fill 3710 3711 Output Parameter: 3712 . fact - the factored matrix 3713 3714 Notes: 3715 Currently only no-fill factorization is supported. 3716 3717 Most users should employ the simplified SLES interface for linear solvers 3718 instead of working directly with matrix algebra routines such as this. 3719 See, e.g., SLESCreate(). 3720 3721 Level: developer 3722 3723 Concepts: matrices^symbolic incomplete Cholesky factorization 3724 Concepts: matrices^factorization 3725 Concepts: Cholsky^symbolic factorization 3726 3727 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor() 3728 @*/ 3729 int MatICCFactorSymbolic(Mat mat,IS perm,PetscReal f,int fill,Mat *fact) 3730 { 3731 int ierr; 3732 3733 PetscFunctionBegin; 3734 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3735 PetscValidType(mat); 3736 MatPreallocated(mat); 3737 PetscValidPointer(fact); 3738 PetscValidHeaderSpecific(perm,IS_COOKIE); 3739 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3740 if (fill < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Fill negative %d",fill); 3741 if (f < 1.0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",f); 3742 if (!mat->ops->iccfactorsymbolic) SETERRQ1(PETSC_ERR_SUP,"Matrix type %s symbolic ICC",mat->type_name); 3743 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3744 3745 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3746 ierr = (*mat->ops->iccfactorsymbolic)(mat,perm,f,fill,fact);CHKERRQ(ierr); 3747 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3748 PetscFunctionReturn(0); 3749 } 3750 3751 #undef __FUNCT__ 3752 #define __FUNCT__ "MatGetArray" 3753 /*@C 3754 MatGetArray - Returns a pointer to the element values in the matrix. 3755 The result of this routine is dependent on the underlying matrix data 3756 structure, and may not even work for certain matrix types. You MUST 3757 call MatRestoreArray() when you no longer need to access the array. 3758 3759 Not Collective 3760 3761 Input Parameter: 3762 . mat - the matrix 3763 3764 Output Parameter: 3765 . v - the location of the values 3766 3767 3768 Fortran Note: 3769 This routine is used differently from Fortran, e.g., 3770 .vb 3771 Mat mat 3772 PetscScalar mat_array(1) 3773 PetscOffset i_mat 3774 int ierr 3775 call MatGetArray(mat,mat_array,i_mat,ierr) 3776 3777 C Access first local entry in matrix; note that array is 3778 C treated as one dimensional 3779 value = mat_array(i_mat + 1) 3780 3781 [... other code ...] 3782 call MatRestoreArray(mat,mat_array,i_mat,ierr) 3783 .ve 3784 3785 See the Fortran chapter of the users manual and 3786 petsc/src/mat/examples/tests for details. 3787 3788 Level: advanced 3789 3790 Concepts: matrices^access array 3791 3792 .seealso: MatRestoreArray(), MatGetArrayF90() 3793 @*/ 3794 int MatGetArray(Mat mat,PetscScalar **v) 3795 { 3796 int ierr; 3797 3798 PetscFunctionBegin; 3799 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3800 PetscValidType(mat); 3801 MatPreallocated(mat); 3802 PetscValidPointer(v); 3803 if (!mat->ops->getarray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 3804 ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr); 3805 PetscFunctionReturn(0); 3806 } 3807 3808 #undef __FUNCT__ 3809 #define __FUNCT__ "MatRestoreArray" 3810 /*@C 3811 MatRestoreArray - Restores the matrix after MatGetArray() has been called. 3812 3813 Not Collective 3814 3815 Input Parameter: 3816 + mat - the matrix 3817 - v - the location of the values 3818 3819 Fortran Note: 3820 This routine is used differently from Fortran, e.g., 3821 .vb 3822 Mat mat 3823 PetscScalar mat_array(1) 3824 PetscOffset i_mat 3825 int ierr 3826 call MatGetArray(mat,mat_array,i_mat,ierr) 3827 3828 C Access first local entry in matrix; note that array is 3829 C treated as one dimensional 3830 value = mat_array(i_mat + 1) 3831 3832 [... other code ...] 3833 call MatRestoreArray(mat,mat_array,i_mat,ierr) 3834 .ve 3835 3836 See the Fortran chapter of the users manual and 3837 petsc/src/mat/examples/tests for details 3838 3839 Level: advanced 3840 3841 .seealso: MatGetArray(), MatRestoreArrayF90() 3842 @*/ 3843 int MatRestoreArray(Mat mat,PetscScalar **v) 3844 { 3845 int ierr; 3846 3847 PetscFunctionBegin; 3848 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3849 PetscValidType(mat); 3850 MatPreallocated(mat); 3851 PetscValidPointer(v); 3852 if (!mat->ops->restorearray) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 3853 ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr); 3854 PetscFunctionReturn(0); 3855 } 3856 3857 #undef __FUNCT__ 3858 #define __FUNCT__ "MatGetSubMatrices" 3859 /*@C 3860 MatGetSubMatrices - Extracts several submatrices from a matrix. If submat 3861 points to an array of valid matrices, they may be reused to store the new 3862 submatrices. 3863 3864 Collective on Mat 3865 3866 Input Parameters: 3867 + mat - the matrix 3868 . n - the number of submatrixes to be extracted (on this processor, may be zero) 3869 . irow, icol - index sets of rows and columns to extract 3870 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 3871 3872 Output Parameter: 3873 . submat - the array of submatrices 3874 3875 Notes: 3876 MatGetSubMatrices() can extract only sequential submatrices 3877 (from both sequential and parallel matrices). Use MatGetSubMatrix() 3878 to extract a parallel submatrix. 3879 3880 When extracting submatrices from a parallel matrix, each processor can 3881 form a different submatrix by setting the rows and columns of its 3882 individual index sets according to the local submatrix desired. 3883 3884 When finished using the submatrices, the user should destroy 3885 them with MatDestroyMatrices(). 3886 3887 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 3888 original matrix has not changed from that last call to MatGetSubMatrices(). 3889 3890 This routine creates the matrices submat; you should NOT create them before 3891 calling it. 3892 3893 Fortran Note: 3894 The Fortran interface is slightly different from that given below; it 3895 requires one to pass in as submat a Mat (integer) array of size at least m. 3896 3897 Level: advanced 3898 3899 Concepts: matrices^accessing submatrices 3900 Concepts: submatrices 3901 3902 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal() 3903 @*/ 3904 int MatGetSubMatrices(Mat mat,int n,IS *irow,IS *icol,MatReuse scall,Mat **submat) 3905 { 3906 int ierr; 3907 3908 PetscFunctionBegin; 3909 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3910 PetscValidType(mat); 3911 MatPreallocated(mat); 3912 if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 3913 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3914 3915 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 3916 ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 3917 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 3918 PetscFunctionReturn(0); 3919 } 3920 3921 #undef __FUNCT__ 3922 #define __FUNCT__ "MatDestroyMatrices" 3923 /*@C 3924 MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices(). 3925 3926 Collective on Mat 3927 3928 Input Parameters: 3929 + n - the number of local matrices 3930 - mat - the matrices 3931 3932 Level: advanced 3933 3934 Notes: Frees not only the matrices, but also the array that contains the matrices 3935 3936 .seealso: MatGetSubMatrices() 3937 @*/ 3938 int MatDestroyMatrices(int n,Mat **mat) 3939 { 3940 int ierr,i; 3941 3942 PetscFunctionBegin; 3943 if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %d",n); 3944 PetscValidPointer(mat); 3945 for (i=0; i<n; i++) { 3946 ierr = MatDestroy((*mat)[i]);CHKERRQ(ierr); 3947 } 3948 /* memory is allocated even if n = 0 */ 3949 ierr = PetscFree(*mat);CHKERRQ(ierr); 3950 PetscFunctionReturn(0); 3951 } 3952 3953 #undef __FUNCT__ 3954 #define __FUNCT__ "MatIncreaseOverlap" 3955 /*@ 3956 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 3957 replaces the index sets by larger ones that represent submatrices with 3958 additional overlap. 3959 3960 Collective on Mat 3961 3962 Input Parameters: 3963 + mat - the matrix 3964 . n - the number of index sets 3965 . is - the array of pointers to index sets 3966 - ov - the additional overlap requested 3967 3968 Level: developer 3969 3970 Concepts: overlap 3971 Concepts: ASM^computing overlap 3972 3973 .seealso: MatGetSubMatrices() 3974 @*/ 3975 int MatIncreaseOverlap(Mat mat,int n,IS *is,int ov) 3976 { 3977 int ierr; 3978 3979 PetscFunctionBegin; 3980 PetscValidHeaderSpecific(mat,MAT_COOKIE); 3981 PetscValidType(mat); 3982 MatPreallocated(mat); 3983 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3984 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3985 3986 if (!ov) PetscFunctionReturn(0); 3987 if (!mat->ops->increaseoverlap) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 3988 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 3989 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 3990 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 3991 PetscFunctionReturn(0); 3992 } 3993 3994 #undef __FUNCT__ 3995 #define __FUNCT__ "MatPrintHelp" 3996 /*@ 3997 MatPrintHelp - Prints all the options for the matrix. 3998 3999 Collective on Mat 4000 4001 Input Parameter: 4002 . mat - the matrix 4003 4004 Options Database Keys: 4005 + -help - Prints matrix options 4006 - -h - Prints matrix options 4007 4008 Level: developer 4009 4010 .seealso: MatCreate(), MatCreateXXX() 4011 @*/ 4012 int MatPrintHelp(Mat mat) 4013 { 4014 static PetscTruth called = PETSC_FALSE; 4015 int ierr; 4016 MPI_Comm comm; 4017 4018 PetscFunctionBegin; 4019 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4020 PetscValidType(mat); 4021 MatPreallocated(mat); 4022 4023 comm = mat->comm; 4024 if (!called) { 4025 if (mat->ops->printhelp) { 4026 ierr = (*mat->ops->printhelp)(mat);CHKERRQ(ierr); 4027 } 4028 called = PETSC_TRUE; 4029 } 4030 PetscFunctionReturn(0); 4031 } 4032 4033 #undef __FUNCT__ 4034 #define __FUNCT__ "MatGetBlockSize" 4035 /*@ 4036 MatGetBlockSize - Returns the matrix block size; useful especially for the 4037 block row and block diagonal formats. 4038 4039 Not Collective 4040 4041 Input Parameter: 4042 . mat - the matrix 4043 4044 Output Parameter: 4045 . bs - block size 4046 4047 Notes: 4048 Block diagonal formats are MATSEQBDIAG, MATMPIBDIAG. 4049 Block row formats are MATSEQBAIJ, MATMPIBAIJ 4050 4051 Level: intermediate 4052 4053 Concepts: matrices^block size 4054 4055 .seealso: MatCreateSeqBAIJ(), MatCreateMPIBAIJ(), MatCreateSeqBDiag(), MatCreateMPIBDiag() 4056 @*/ 4057 int MatGetBlockSize(Mat mat,int *bs) 4058 { 4059 int ierr; 4060 4061 PetscFunctionBegin; 4062 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4063 PetscValidType(mat); 4064 MatPreallocated(mat); 4065 PetscValidIntPointer(bs); 4066 if (!mat->ops->getblocksize) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 4067 ierr = (*mat->ops->getblocksize)(mat,bs);CHKERRQ(ierr); 4068 PetscFunctionReturn(0); 4069 } 4070 4071 #undef __FUNCT__ 4072 #define __FUNCT__ "MatGetRowIJ" 4073 /*@C 4074 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 4075 4076 Collective on Mat 4077 4078 Input Parameters: 4079 + mat - the matrix 4080 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 4081 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 4082 symmetrized 4083 4084 Output Parameters: 4085 + n - number of rows in the (possibly compressed) matrix 4086 . ia - the row pointers 4087 . ja - the column indices 4088 - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 4089 4090 Level: developer 4091 4092 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 4093 @*/ 4094 int MatGetRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done) 4095 { 4096 int ierr; 4097 4098 PetscFunctionBegin; 4099 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4100 PetscValidType(mat); 4101 MatPreallocated(mat); 4102 if (ia) PetscValidIntPointer(ia); 4103 if (ja) PetscValidIntPointer(ja); 4104 PetscValidIntPointer(done); 4105 if (!mat->ops->getrowij) *done = PETSC_FALSE; 4106 else { 4107 *done = PETSC_TRUE; 4108 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr); 4109 } 4110 PetscFunctionReturn(0); 4111 } 4112 4113 #undef __FUNCT__ 4114 #define __FUNCT__ "MatGetColumnIJ" 4115 /*@C 4116 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 4117 4118 Collective on Mat 4119 4120 Input Parameters: 4121 + mat - the matrix 4122 . shift - 1 or zero indicating we want the indices starting at 0 or 1 4123 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 4124 symmetrized 4125 4126 Output Parameters: 4127 + n - number of columns in the (possibly compressed) matrix 4128 . ia - the column pointers 4129 . ja - the row indices 4130 - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 4131 4132 Level: developer 4133 4134 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 4135 @*/ 4136 int MatGetColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done) 4137 { 4138 int ierr; 4139 4140 PetscFunctionBegin; 4141 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4142 PetscValidType(mat); 4143 MatPreallocated(mat); 4144 if (ia) PetscValidIntPointer(ia); 4145 if (ja) PetscValidIntPointer(ja); 4146 PetscValidIntPointer(done); 4147 4148 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 4149 else { 4150 *done = PETSC_TRUE; 4151 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr); 4152 } 4153 PetscFunctionReturn(0); 4154 } 4155 4156 #undef __FUNCT__ 4157 #define __FUNCT__ "MatRestoreRowIJ" 4158 /*@C 4159 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 4160 MatGetRowIJ(). 4161 4162 Collective on Mat 4163 4164 Input Parameters: 4165 + mat - the matrix 4166 . shift - 1 or zero indicating we want the indices starting at 0 or 1 4167 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 4168 symmetrized 4169 4170 Output Parameters: 4171 + n - size of (possibly compressed) matrix 4172 . ia - the row pointers 4173 . ja - the column indices 4174 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 4175 4176 Level: developer 4177 4178 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 4179 @*/ 4180 int MatRestoreRowIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done) 4181 { 4182 int ierr; 4183 4184 PetscFunctionBegin; 4185 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4186 PetscValidType(mat); 4187 MatPreallocated(mat); 4188 if (ia) PetscValidIntPointer(ia); 4189 if (ja) PetscValidIntPointer(ja); 4190 PetscValidIntPointer(done); 4191 4192 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 4193 else { 4194 *done = PETSC_TRUE; 4195 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr); 4196 } 4197 PetscFunctionReturn(0); 4198 } 4199 4200 #undef __FUNCT__ 4201 #define __FUNCT__ "MatRestoreColumnIJ" 4202 /*@C 4203 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 4204 MatGetColumnIJ(). 4205 4206 Collective on Mat 4207 4208 Input Parameters: 4209 + mat - the matrix 4210 . shift - 1 or zero indicating we want the indices starting at 0 or 1 4211 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 4212 symmetrized 4213 4214 Output Parameters: 4215 + n - size of (possibly compressed) matrix 4216 . ia - the column pointers 4217 . ja - the row indices 4218 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 4219 4220 Level: developer 4221 4222 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 4223 @*/ 4224 int MatRestoreColumnIJ(Mat mat,int shift,PetscTruth symmetric,int *n,int **ia,int** ja,PetscTruth *done) 4225 { 4226 int ierr; 4227 4228 PetscFunctionBegin; 4229 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4230 PetscValidType(mat); 4231 MatPreallocated(mat); 4232 if (ia) PetscValidIntPointer(ia); 4233 if (ja) PetscValidIntPointer(ja); 4234 PetscValidIntPointer(done); 4235 4236 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 4237 else { 4238 *done = PETSC_TRUE; 4239 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,n,ia,ja,done);CHKERRQ(ierr); 4240 } 4241 PetscFunctionReturn(0); 4242 } 4243 4244 #undef __FUNCT__ 4245 #define __FUNCT__ "MatColoringPatch" 4246 /*@C 4247 MatColoringPatch -Used inside matrix coloring routines that 4248 use MatGetRowIJ() and/or MatGetColumnIJ(). 4249 4250 Collective on Mat 4251 4252 Input Parameters: 4253 + mat - the matrix 4254 . n - number of colors 4255 - colorarray - array indicating color for each column 4256 4257 Output Parameters: 4258 . iscoloring - coloring generated using colorarray information 4259 4260 Level: developer 4261 4262 .seealso: MatGetRowIJ(), MatGetColumnIJ() 4263 4264 @*/ 4265 int MatColoringPatch(Mat mat,int n,int ncolors,int *colorarray,ISColoring *iscoloring) 4266 { 4267 int ierr; 4268 4269 PetscFunctionBegin; 4270 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4271 PetscValidType(mat); 4272 MatPreallocated(mat); 4273 PetscValidIntPointer(colorarray); 4274 4275 if (!mat->ops->coloringpatch){ 4276 ierr = ISColoringCreate(mat->comm,n,colorarray,iscoloring);CHKERRQ(ierr); 4277 } else { 4278 ierr = (*mat->ops->coloringpatch)(mat,n,ncolors,colorarray,iscoloring);CHKERRQ(ierr); 4279 } 4280 PetscFunctionReturn(0); 4281 } 4282 4283 4284 #undef __FUNCT__ 4285 #define __FUNCT__ "MatSetUnfactored" 4286 /*@ 4287 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 4288 4289 Collective on Mat 4290 4291 Input Parameter: 4292 . mat - the factored matrix to be reset 4293 4294 Notes: 4295 This routine should be used only with factored matrices formed by in-place 4296 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 4297 format). This option can save memory, for example, when solving nonlinear 4298 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 4299 ILU(0) preconditioner. 4300 4301 Note that one can specify in-place ILU(0) factorization by calling 4302 .vb 4303 PCType(pc,PCILU); 4304 PCILUSeUseInPlace(pc); 4305 .ve 4306 or by using the options -pc_type ilu -pc_ilu_in_place 4307 4308 In-place factorization ILU(0) can also be used as a local 4309 solver for the blocks within the block Jacobi or additive Schwarz 4310 methods (runtime option: -sub_pc_ilu_in_place). See the discussion 4311 of these preconditioners in the users manual for details on setting 4312 local solver options. 4313 4314 Most users should employ the simplified SLES interface for linear solvers 4315 instead of working directly with matrix algebra routines such as this. 4316 See, e.g., SLESCreate(). 4317 4318 Level: developer 4319 4320 .seealso: PCILUSetUseInPlace(), PCLUSetUseInPlace() 4321 4322 Concepts: matrices^unfactored 4323 4324 @*/ 4325 int MatSetUnfactored(Mat mat) 4326 { 4327 int ierr; 4328 4329 PetscFunctionBegin; 4330 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4331 PetscValidType(mat); 4332 MatPreallocated(mat); 4333 mat->factor = 0; 4334 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 4335 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 4336 PetscFunctionReturn(0); 4337 } 4338 4339 /*MC 4340 MatGetArrayF90 - Accesses a matrix array from Fortran90. 4341 4342 Synopsis: 4343 MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 4344 4345 Not collective 4346 4347 Input Parameter: 4348 . x - matrix 4349 4350 Output Parameters: 4351 + xx_v - the Fortran90 pointer to the array 4352 - ierr - error code 4353 4354 Example of Usage: 4355 .vb 4356 PetscScalar, pointer xx_v(:) 4357 .... 4358 call MatGetArrayF90(x,xx_v,ierr) 4359 a = xx_v(3) 4360 call MatRestoreArrayF90(x,xx_v,ierr) 4361 .ve 4362 4363 Notes: 4364 Not yet supported for all F90 compilers 4365 4366 Level: advanced 4367 4368 .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray() 4369 4370 Concepts: matrices^accessing array 4371 4372 M*/ 4373 4374 /*MC 4375 MatRestoreArrayF90 - Restores a matrix array that has been 4376 accessed with MatGetArrayF90(). 4377 4378 Synopsis: 4379 MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 4380 4381 Not collective 4382 4383 Input Parameters: 4384 + x - matrix 4385 - xx_v - the Fortran90 pointer to the array 4386 4387 Output Parameter: 4388 . ierr - error code 4389 4390 Example of Usage: 4391 .vb 4392 PetscScalar, pointer xx_v(:) 4393 .... 4394 call MatGetArrayF90(x,xx_v,ierr) 4395 a = xx_v(3) 4396 call MatRestoreArrayF90(x,xx_v,ierr) 4397 .ve 4398 4399 Notes: 4400 Not yet supported for all F90 compilers 4401 4402 Level: advanced 4403 4404 .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray() 4405 4406 M*/ 4407 4408 4409 #undef __FUNCT__ 4410 #define __FUNCT__ "MatGetSubMatrix" 4411 /*@ 4412 MatGetSubMatrix - Gets a single submatrix on the same number of processors 4413 as the original matrix. 4414 4415 Collective on Mat 4416 4417 Input Parameters: 4418 + mat - the original matrix 4419 . isrow - rows this processor should obtain 4420 . iscol - columns for all processors you wish to keep 4421 . csize - number of columns "local" to this processor (does nothing for sequential 4422 matrices). This should match the result from VecGetLocalSize(x,...) if you 4423 plan to use the matrix in a A*x; alternatively, you can use PETSC_DECIDE 4424 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 4425 4426 Output Parameter: 4427 . newmat - the new submatrix, of the same type as the old 4428 4429 Level: advanced 4430 4431 Notes: the iscol argument MUST be the same on each processor. You might be 4432 able to create the iscol argument with ISAllGather(). 4433 4434 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 4435 the MatGetSubMatrix() routine will create the newmat for you. Any additional calls 4436 to this routine with a mat of the same nonzero structure will reuse the matrix 4437 generated the first time. 4438 4439 Concepts: matrices^submatrices 4440 4441 .seealso: MatGetSubMatrices(), ISAllGather() 4442 @*/ 4443 int MatGetSubMatrix(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,Mat *newmat) 4444 { 4445 int ierr, size; 4446 Mat *local; 4447 4448 PetscFunctionBegin; 4449 PetscValidType(mat); 4450 MatPreallocated(mat); 4451 ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr); 4452 4453 /* if original matrix is on just one processor then use submatrix generated */ 4454 if (!mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 4455 ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 4456 PetscFunctionReturn(0); 4457 } else if (!mat->ops->getsubmatrix && size == 1) { 4458 ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 4459 *newmat = *local; 4460 ierr = PetscFree(local);CHKERRQ(ierr); 4461 PetscFunctionReturn(0); 4462 } 4463 4464 if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 4465 ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscol,csize,cll,newmat);CHKERRQ(ierr); 4466 PetscFunctionReturn(0); 4467 } 4468 4469 #undef __FUNCT__ 4470 #define __FUNCT__ "MatGetPetscMaps" 4471 /*@C 4472 MatGetPetscMaps - Returns the maps associated with the matrix. 4473 4474 Not Collective 4475 4476 Input Parameter: 4477 . mat - the matrix 4478 4479 Output Parameters: 4480 + rmap - the row (right) map 4481 - cmap - the column (left) map 4482 4483 Level: developer 4484 4485 Concepts: maps^getting from matrix 4486 4487 @*/ 4488 int MatGetPetscMaps(Mat mat,PetscMap *rmap,PetscMap *cmap) 4489 { 4490 int ierr; 4491 4492 PetscFunctionBegin; 4493 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4494 PetscValidType(mat); 4495 MatPreallocated(mat); 4496 ierr = (*mat->ops->getmaps)(mat,rmap,cmap);CHKERRQ(ierr); 4497 PetscFunctionReturn(0); 4498 } 4499 4500 /* 4501 Version that works for all PETSc matrices 4502 */ 4503 #undef __FUNCT__ 4504 #define __FUNCT__ "MatGetPetscMaps_Petsc" 4505 int MatGetPetscMaps_Petsc(Mat mat,PetscMap *rmap,PetscMap *cmap) 4506 { 4507 PetscFunctionBegin; 4508 if (rmap) *rmap = mat->rmap; 4509 if (cmap) *cmap = mat->cmap; 4510 PetscFunctionReturn(0); 4511 } 4512 4513 #undef __FUNCT__ 4514 #define __FUNCT__ "MatSetStashInitialSize" 4515 /*@ 4516 MatSetStashInitialSize - sets the sizes of the matrix stash, that is 4517 used during the assembly process to store values that belong to 4518 other processors. 4519 4520 Not Collective 4521 4522 Input Parameters: 4523 + mat - the matrix 4524 . size - the initial size of the stash. 4525 - bsize - the initial size of the block-stash(if used). 4526 4527 Options Database Keys: 4528 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 4529 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 4530 4531 Level: intermediate 4532 4533 Notes: 4534 The block-stash is used for values set with VecSetValuesBlocked() while 4535 the stash is used for values set with VecSetValues() 4536 4537 Run with the option -log_info and look for output of the form 4538 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 4539 to determine the appropriate value, MM, to use for size and 4540 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 4541 to determine the value, BMM to use for bsize 4542 4543 Concepts: stash^setting matrix size 4544 Concepts: matrices^stash 4545 4546 @*/ 4547 int MatSetStashInitialSize(Mat mat,int size, int bsize) 4548 { 4549 int ierr; 4550 4551 PetscFunctionBegin; 4552 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4553 PetscValidType(mat); 4554 MatPreallocated(mat); 4555 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 4556 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 4557 PetscFunctionReturn(0); 4558 } 4559 4560 #undef __FUNCT__ 4561 #define __FUNCT__ "MatInterpolateAdd" 4562 /*@ 4563 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 4564 the matrix 4565 4566 Collective on Mat 4567 4568 Input Parameters: 4569 + mat - the matrix 4570 . x,y - the vectors 4571 - w - where the result is stored 4572 4573 Level: intermediate 4574 4575 Notes: 4576 w may be the same vector as y. 4577 4578 This allows one to use either the restriction or interpolation (its transpose) 4579 matrix to do the interpolation 4580 4581 Concepts: interpolation 4582 4583 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 4584 4585 @*/ 4586 int MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 4587 { 4588 int M,N,ierr; 4589 4590 PetscFunctionBegin; 4591 PetscValidType(A); 4592 MatPreallocated(A); 4593 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 4594 if (N > M) { 4595 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 4596 } else { 4597 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 4598 } 4599 PetscFunctionReturn(0); 4600 } 4601 4602 #undef __FUNCT__ 4603 #define __FUNCT__ "MatInterpolate" 4604 /*@ 4605 MatInterpolate - y = A*x or A'*x depending on the shape of 4606 the matrix 4607 4608 Collective on Mat 4609 4610 Input Parameters: 4611 + mat - the matrix 4612 - x,y - the vectors 4613 4614 Level: intermediate 4615 4616 Notes: 4617 This allows one to use either the restriction or interpolation (its transpose) 4618 matrix to do the interpolation 4619 4620 Concepts: matrices^interpolation 4621 4622 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 4623 4624 @*/ 4625 int MatInterpolate(Mat A,Vec x,Vec y) 4626 { 4627 int M,N,ierr; 4628 4629 PetscFunctionBegin; 4630 PetscValidType(A); 4631 MatPreallocated(A); 4632 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 4633 if (N > M) { 4634 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 4635 } else { 4636 ierr = MatMult(A,x,y);CHKERRQ(ierr); 4637 } 4638 PetscFunctionReturn(0); 4639 } 4640 4641 #undef __FUNCT__ 4642 #define __FUNCT__ "MatRestrict" 4643 /*@ 4644 MatRestrict - y = A*x or A'*x 4645 4646 Collective on Mat 4647 4648 Input Parameters: 4649 + mat - the matrix 4650 - x,y - the vectors 4651 4652 Level: intermediate 4653 4654 Notes: 4655 This allows one to use either the restriction or interpolation (its transpose) 4656 matrix to do the restriction 4657 4658 Concepts: matrices^restriction 4659 4660 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 4661 4662 @*/ 4663 int MatRestrict(Mat A,Vec x,Vec y) 4664 { 4665 int M,N,ierr; 4666 4667 PetscFunctionBegin; 4668 PetscValidType(A); 4669 MatPreallocated(A); 4670 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 4671 if (N > M) { 4672 ierr = MatMult(A,x,y);CHKERRQ(ierr); 4673 } else { 4674 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 4675 } 4676 PetscFunctionReturn(0); 4677 } 4678 4679 #undef __FUNCT__ 4680 #define __FUNCT__ "MatNullSpaceAttach" 4681 /*@C 4682 MatNullSpaceAttach - attaches a null space to a matrix. 4683 This null space will be removed from the resulting vector whenever 4684 MatMult() is called 4685 4686 Collective on Mat 4687 4688 Input Parameters: 4689 + mat - the matrix 4690 - nullsp - the null space object 4691 4692 Level: developer 4693 4694 Notes: 4695 Overwrites any previous null space that may have been attached 4696 4697 Concepts: null space^attaching to matrix 4698 4699 .seealso: MatCreate(), MatNullSpaceCreate() 4700 @*/ 4701 int MatNullSpaceAttach(Mat mat,MatNullSpace nullsp) 4702 { 4703 int ierr; 4704 4705 PetscFunctionBegin; 4706 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4707 PetscValidType(mat); 4708 MatPreallocated(mat); 4709 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_COOKIE); 4710 4711 if (mat->nullsp) { 4712 ierr = MatNullSpaceDestroy(mat->nullsp);CHKERRQ(ierr); 4713 } 4714 mat->nullsp = nullsp; 4715 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 4716 PetscFunctionReturn(0); 4717 } 4718 4719 #undef __FUNCT__ 4720 #define __FUNCT__ "MatICCFactor" 4721 /*@ 4722 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 4723 4724 Collective on Mat 4725 4726 Input Parameters: 4727 + mat - the matrix 4728 . row - row/column permutation 4729 . fill - expected fill factor >= 1.0 4730 - level - level of fill, for ICC(k) 4731 4732 Notes: 4733 Probably really in-place only when level of fill is zero, otherwise allocates 4734 new space to store factored matrix and deletes previous memory. 4735 4736 Most users should employ the simplified SLES interface for linear solvers 4737 instead of working directly with matrix algebra routines such as this. 4738 See, e.g., SLESCreate(). 4739 4740 Level: developer 4741 4742 Concepts: matrices^incomplete Cholesky factorization 4743 Concepts: Cholesky factorization 4744 4745 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 4746 @*/ 4747 int MatICCFactor(Mat mat,IS row,PetscReal fill,int level) 4748 { 4749 int ierr; 4750 4751 PetscFunctionBegin; 4752 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4753 PetscValidType(mat); 4754 MatPreallocated(mat); 4755 if (mat->M != mat->N) SETERRQ(PETSC_ERR_ARG_WRONG,"matrix must be square"); 4756 if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4757 if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4758 if (!mat->ops->iccfactor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 4759 ierr = (*mat->ops->iccfactor)(mat,row,fill,level);CHKERRQ(ierr); 4760 PetscFunctionReturn(0); 4761 } 4762 4763 #undef __FUNCT__ 4764 #define __FUNCT__ "MatSetValuesAdic" 4765 /*@ 4766 MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix. 4767 4768 Not Collective 4769 4770 Input Parameters: 4771 + mat - the matrix 4772 - v - the values compute with ADIC 4773 4774 Level: developer 4775 4776 Notes: 4777 Must call MatSetColoring() before using this routine. Also this matrix must already 4778 have its nonzero pattern determined. 4779 4780 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 4781 MatSetValues(), MatSetColoring(), MatSetValuesAdifor() 4782 @*/ 4783 int MatSetValuesAdic(Mat mat,void *v) 4784 { 4785 int ierr; 4786 4787 PetscFunctionBegin; 4788 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4789 PetscValidType(mat); 4790 4791 if (!mat->assembled) { 4792 SETERRQ(1,"Matrix must be already assembled"); 4793 } 4794 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 4795 if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 4796 ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr); 4797 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 4798 ierr = MatView_Private(mat);CHKERRQ(ierr); 4799 PetscFunctionReturn(0); 4800 } 4801 4802 4803 #undef __FUNCT__ 4804 #define __FUNCT__ "MatSetColoring" 4805 /*@ 4806 MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic() 4807 4808 Not Collective 4809 4810 Input Parameters: 4811 + mat - the matrix 4812 - coloring - the coloring 4813 4814 Level: developer 4815 4816 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 4817 MatSetValues(), MatSetValuesAdic() 4818 @*/ 4819 int MatSetColoring(Mat mat,ISColoring coloring) 4820 { 4821 int ierr; 4822 4823 PetscFunctionBegin; 4824 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4825 PetscValidType(mat); 4826 4827 if (!mat->assembled) { 4828 SETERRQ(1,"Matrix must be already assembled"); 4829 } 4830 if (!mat->ops->setcoloring) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 4831 ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr); 4832 PetscFunctionReturn(0); 4833 } 4834 4835 #undef __FUNCT__ 4836 #define __FUNCT__ "MatSetValuesAdifor" 4837 /*@ 4838 MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix. 4839 4840 Not Collective 4841 4842 Input Parameters: 4843 + mat - the matrix 4844 . nl - leading dimension of v 4845 - v - the values compute with ADIFOR 4846 4847 Level: developer 4848 4849 Notes: 4850 Must call MatSetColoring() before using this routine. Also this matrix must already 4851 have its nonzero pattern determined. 4852 4853 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 4854 MatSetValues(), MatSetColoring() 4855 @*/ 4856 int MatSetValuesAdifor(Mat mat,int nl,void *v) 4857 { 4858 int ierr; 4859 4860 PetscFunctionBegin; 4861 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4862 PetscValidType(mat); 4863 4864 if (!mat->assembled) { 4865 SETERRQ(1,"Matrix must be already assembled"); 4866 } 4867 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 4868 if (!mat->ops->setvaluesadifor) SETERRQ1(PETSC_ERR_SUP,"Mat type %s",mat->type_name); 4869 ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr); 4870 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 4871 PetscFunctionReturn(0); 4872 } 4873 4874 EXTERN int MatMPIAIJDiagonalScaleLocal(Mat,Vec); 4875 EXTERN int MatMPIBAIJDiagonalScaleLocal(Mat,Vec); 4876 4877 #undef __FUNCT__ 4878 #define __FUNCT__ "MatDiagonalScaleLocal" 4879 /*@ 4880 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 4881 ghosted ones. 4882 4883 Not Collective 4884 4885 Input Parameters: 4886 + mat - the matrix 4887 - diag = the diagonal values, including ghost ones 4888 4889 Level: developer 4890 4891 Notes: Works only for MPIAIJ and MPIBAIJ matrices 4892 4893 .seealso: MatDiagonalScale() 4894 @*/ 4895 int MatDiagonalScaleLocal(Mat mat,Vec diag) 4896 { 4897 int ierr; 4898 PetscTruth flag; 4899 4900 PetscFunctionBegin; 4901 PetscValidHeaderSpecific(mat,MAT_COOKIE); 4902 PetscValidHeaderSpecific(diag,VEC_COOKIE); 4903 PetscValidType(mat); 4904 4905 if (!mat->assembled) { 4906 SETERRQ(1,"Matrix must be already assembled"); 4907 } 4908 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4909 ierr = PetscTypeCompare((PetscObject)mat,MATMPIAIJ,&flag);CHKERRQ(ierr); 4910 if (flag) { 4911 ierr = MatMPIAIJDiagonalScaleLocal(mat,diag);CHKERRQ(ierr); 4912 } else { 4913 ierr = PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flag);CHKERRQ(ierr); 4914 if (flag) { 4915 ierr = MatMPIBAIJDiagonalScaleLocal(mat,diag);CHKERRQ(ierr); 4916 } else { 4917 int size; 4918 ierr = MPI_Comm_size(mat->comm,&size);CHKERRQ(ierr); 4919 if (size == 1) { 4920 int n,m; 4921 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 4922 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 4923 if (m == n) { 4924 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 4925 } else { 4926 SETERRQ(1,"Only supprted for sequential matrices when no ghost points/periodic conditions"); 4927 } 4928 } else { 4929 SETERRQ(1,"Only supported for MPIAIJ and MPIBAIJ parallel matrices"); 4930 } 4931 } 4932 } 4933 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4934 PetscFunctionReturn(0); 4935 } 4936