1 2 /* 3 This is where the abstract matrix operations are defined 4 */ 5 6 #include <petsc-private/matimpl.h> /*I "petscmat.h" I*/ 7 #include <petsc-private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_FDCOLORING_CLASSID; 12 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 13 14 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 15 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve; 16 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 17 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 18 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 19 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure; 20 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 21 PetscLogEvent MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction; 22 PetscLogEvent MAT_TransposeColoringCreate; 23 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 24 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 25 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 26 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 27 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 28 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols; 29 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 30 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 31 PetscLogEvent MAT_GetMultiProcBlock; 32 PetscLogEvent MAT_CUSPCopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV; 33 PetscLogEvent MAT_Merge; 34 35 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 36 37 #undef __FUNCT__ 38 #define __FUNCT__ "MatFindNonzeroRows" 39 /*@ 40 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 41 42 Input Parameter: 43 . A - the matrix 44 45 Output Parameter: 46 . keptrows - the rows that are not completely zero 47 48 Level: intermediate 49 50 @*/ 51 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 52 { 53 PetscErrorCode ierr; 54 55 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 56 PetscValidType(mat,1); 57 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 58 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 59 if (!mat->ops->findnonzerorows) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not coded for this matrix type"); 60 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 61 PetscFunctionReturn(0); 62 } 63 64 #undef __FUNCT__ 65 #define __FUNCT__ "MatGetDiagonalBlock" 66 /*@ 67 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 68 69 Not Collective 70 71 Input Parameters: 72 . A - the matrix 73 74 Output Parameters: 75 . a - the diagonal part (which is a SEQUENTIAL matrix) 76 77 Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 78 79 Level: advanced 80 81 @*/ 82 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 83 { 84 PetscErrorCode ierr,(*f)(Mat,Mat*); 85 PetscMPIInt size; 86 87 PetscFunctionBegin; 88 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 89 PetscValidType(A,1); 90 PetscValidPointer(a,3); 91 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 92 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 93 ierr = MPI_Comm_size(((PetscObject)A)->comm,&size);CHKERRQ(ierr); 94 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",(void (**)(void))&f);CHKERRQ(ierr); 95 if (f) { 96 ierr = (*f)(A,a);CHKERRQ(ierr); 97 PetscFunctionReturn(0); 98 } else if (size == 1) { 99 *a = A; 100 } else { 101 const MatType mattype; 102 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 103 SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype); 104 } 105 PetscFunctionReturn(0); 106 } 107 108 #undef __FUNCT__ 109 #define __FUNCT__ "MatGetTrace" 110 /*@ 111 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 112 113 Collective on Mat 114 115 Input Parameters: 116 . mat - the matrix 117 118 Output Parameter: 119 . trace - the sum of the diagonal entries 120 121 Level: advanced 122 123 @*/ 124 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 125 { 126 PetscErrorCode ierr; 127 Vec diag; 128 129 PetscFunctionBegin; 130 ierr = MatGetVecs(mat,&diag,PETSC_NULL);CHKERRQ(ierr); 131 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 132 ierr = VecSum(diag,trace);CHKERRQ(ierr); 133 ierr = VecDestroy(&diag);CHKERRQ(ierr); 134 PetscFunctionReturn(0); 135 } 136 137 #undef __FUNCT__ 138 #define __FUNCT__ "MatRealPart" 139 /*@ 140 MatRealPart - Zeros out the imaginary part of the matrix 141 142 Logically Collective on Mat 143 144 Input Parameters: 145 . mat - the matrix 146 147 Level: advanced 148 149 150 .seealso: MatImaginaryPart() 151 @*/ 152 PetscErrorCode MatRealPart(Mat mat) 153 { 154 PetscErrorCode ierr; 155 156 PetscFunctionBegin; 157 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 158 PetscValidType(mat,1); 159 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 160 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 161 if (!mat->ops->realpart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 162 MatCheckPreallocated(mat,1); 163 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 164 #if defined(PETSC_HAVE_CUSP) 165 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 166 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 167 } 168 #endif 169 PetscFunctionReturn(0); 170 } 171 172 #undef __FUNCT__ 173 #define __FUNCT__ "MatGetGhosts" 174 /*@C 175 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 176 177 Collective on Mat 178 179 Input Parameter: 180 . mat - the matrix 181 182 Output Parameters: 183 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 184 - ghosts - the global indices of the ghost points 185 186 Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost() 187 188 Level: advanced 189 190 @*/ 191 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 192 { 193 PetscErrorCode ierr; 194 195 PetscFunctionBegin; 196 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 197 PetscValidType(mat,1); 198 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 199 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 200 if (!mat->ops->getghosts) { 201 if (nghosts) *nghosts = 0; 202 if (ghosts) *ghosts = 0; 203 } else { 204 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 205 } 206 PetscFunctionReturn(0); 207 } 208 209 210 #undef __FUNCT__ 211 #define __FUNCT__ "MatImaginaryPart" 212 /*@ 213 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 214 215 Logically Collective on Mat 216 217 Input Parameters: 218 . mat - the matrix 219 220 Level: advanced 221 222 223 .seealso: MatRealPart() 224 @*/ 225 PetscErrorCode MatImaginaryPart(Mat mat) 226 { 227 PetscErrorCode ierr; 228 229 PetscFunctionBegin; 230 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 231 PetscValidType(mat,1); 232 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 233 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 234 if (!mat->ops->imaginarypart) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 235 MatCheckPreallocated(mat,1); 236 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 237 #if defined(PETSC_HAVE_CUSP) 238 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 239 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 240 } 241 #endif 242 PetscFunctionReturn(0); 243 } 244 245 #undef __FUNCT__ 246 #define __FUNCT__ "MatMissingDiagonal" 247 /*@ 248 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 249 250 Collective on Mat 251 252 Input Parameter: 253 . mat - the matrix 254 255 Output Parameters: 256 + missing - is any diagonal missing 257 - dd - first diagonal entry that is missing (optional) 258 259 Level: advanced 260 261 262 .seealso: MatRealPart() 263 @*/ 264 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 265 { 266 PetscErrorCode ierr; 267 268 PetscFunctionBegin; 269 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 270 PetscValidType(mat,1); 271 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 272 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 273 if (!mat->ops->missingdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 274 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 275 PetscFunctionReturn(0); 276 } 277 278 #undef __FUNCT__ 279 #define __FUNCT__ "MatGetRow" 280 /*@C 281 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 282 for each row that you get to ensure that your application does 283 not bleed memory. 284 285 Not Collective 286 287 Input Parameters: 288 + mat - the matrix 289 - row - the row to get 290 291 Output Parameters: 292 + ncols - if not NULL, the number of nonzeros in the row 293 . cols - if not NULL, the column numbers 294 - vals - if not NULL, the values 295 296 Notes: 297 This routine is provided for people who need to have direct access 298 to the structure of a matrix. We hope that we provide enough 299 high-level matrix routines that few users will need it. 300 301 MatGetRow() always returns 0-based column indices, regardless of 302 whether the internal representation is 0-based (default) or 1-based. 303 304 For better efficiency, set cols and/or vals to PETSC_NULL if you do 305 not wish to extract these quantities. 306 307 The user can only examine the values extracted with MatGetRow(); 308 the values cannot be altered. To change the matrix entries, one 309 must use MatSetValues(). 310 311 You can only have one call to MatGetRow() outstanding for a particular 312 matrix at a time, per processor. MatGetRow() can only obtain rows 313 associated with the given processor, it cannot get rows from the 314 other processors; for that we suggest using MatGetSubMatrices(), then 315 MatGetRow() on the submatrix. The row indix passed to MatGetRows() 316 is in the global number of rows. 317 318 Fortran Notes: 319 The calling sequence from Fortran is 320 .vb 321 MatGetRow(matrix,row,ncols,cols,values,ierr) 322 Mat matrix (input) 323 integer row (input) 324 integer ncols (output) 325 integer cols(maxcols) (output) 326 double precision (or double complex) values(maxcols) output 327 .ve 328 where maxcols >= maximum nonzeros in any row of the matrix. 329 330 331 Caution: 332 Do not try to change the contents of the output arrays (cols and vals). 333 In some cases, this may corrupt the matrix. 334 335 Level: advanced 336 337 Concepts: matrices^row access 338 339 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal() 340 @*/ 341 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 342 { 343 PetscErrorCode ierr; 344 PetscInt incols; 345 346 PetscFunctionBegin; 347 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 348 PetscValidType(mat,1); 349 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 350 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 351 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 352 MatCheckPreallocated(mat,1); 353 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 354 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 355 if (ncols) *ncols = incols; 356 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 357 PetscFunctionReturn(0); 358 } 359 360 #undef __FUNCT__ 361 #define __FUNCT__ "MatConjugate" 362 /*@ 363 MatConjugate - replaces the matrix values with their complex conjugates 364 365 Logically Collective on Mat 366 367 Input Parameters: 368 . mat - the matrix 369 370 Level: advanced 371 372 .seealso: VecConjugate() 373 @*/ 374 PetscErrorCode MatConjugate(Mat mat) 375 { 376 #ifdef PETSC_USE_COMPLEX 377 PetscErrorCode ierr; 378 379 PetscFunctionBegin; 380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 381 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 382 if (!mat->ops->conjugate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 383 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 384 #if defined(PETSC_HAVE_CUSP) 385 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 386 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 387 } 388 #endif 389 PetscFunctionReturn(0); 390 #else 391 return 0; 392 #endif 393 } 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "MatRestoreRow" 397 /*@C 398 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 399 400 Not Collective 401 402 Input Parameters: 403 + mat - the matrix 404 . row - the row to get 405 . ncols, cols - the number of nonzeros and their columns 406 - vals - if nonzero the column values 407 408 Notes: 409 This routine should be called after you have finished examining the entries. 410 411 Fortran Notes: 412 The calling sequence from Fortran is 413 .vb 414 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 415 Mat matrix (input) 416 integer row (input) 417 integer ncols (output) 418 integer cols(maxcols) (output) 419 double precision (or double complex) values(maxcols) output 420 .ve 421 Where maxcols >= maximum nonzeros in any row of the matrix. 422 423 In Fortran MatRestoreRow() MUST be called after MatGetRow() 424 before another call to MatGetRow() can be made. 425 426 Level: advanced 427 428 .seealso: MatGetRow() 429 @*/ 430 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 431 { 432 PetscErrorCode ierr; 433 434 PetscFunctionBegin; 435 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 436 if (ncols) {PetscValidIntPointer(ncols,3);} 437 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 438 if (!mat->ops->restorerow) PetscFunctionReturn(0); 439 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 440 PetscFunctionReturn(0); 441 } 442 443 #undef __FUNCT__ 444 #define __FUNCT__ "MatGetRowUpperTriangular" 445 /*@ 446 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 447 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 448 449 Not Collective 450 451 Input Parameters: 452 + mat - the matrix 453 454 Notes: 455 The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format. 456 457 Level: advanced 458 459 Concepts: matrices^row access 460 461 .seealso: MatRestoreRowRowUpperTriangular() 462 @*/ 463 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 464 { 465 PetscErrorCode ierr; 466 467 PetscFunctionBegin; 468 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 469 PetscValidType(mat,1); 470 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 471 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 472 if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 473 MatCheckPreallocated(mat,1); 474 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 475 PetscFunctionReturn(0); 476 } 477 478 #undef __FUNCT__ 479 #define __FUNCT__ "MatRestoreRowUpperTriangular" 480 /*@ 481 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 482 483 Not Collective 484 485 Input Parameters: 486 + mat - the matrix 487 488 Notes: 489 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 490 491 492 Level: advanced 493 494 .seealso: MatGetRowUpperTriangular() 495 @*/ 496 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 497 { 498 PetscErrorCode ierr; 499 500 PetscFunctionBegin; 501 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 502 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 503 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 504 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 505 PetscFunctionReturn(0); 506 } 507 508 #undef __FUNCT__ 509 #define __FUNCT__ "MatSetOptionsPrefix" 510 /*@C 511 MatSetOptionsPrefix - Sets the prefix used for searching for all 512 Mat options in the database. 513 514 Logically Collective on Mat 515 516 Input Parameter: 517 + A - the Mat context 518 - prefix - the prefix to prepend to all option names 519 520 Notes: 521 A hyphen (-) must NOT be given at the beginning of the prefix name. 522 The first character of all runtime options is AUTOMATICALLY the hyphen. 523 524 Level: advanced 525 526 .keywords: Mat, set, options, prefix, database 527 528 .seealso: MatSetFromOptions() 529 @*/ 530 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 531 { 532 PetscErrorCode ierr; 533 534 PetscFunctionBegin; 535 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 536 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 537 PetscFunctionReturn(0); 538 } 539 540 #undef __FUNCT__ 541 #define __FUNCT__ "MatAppendOptionsPrefix" 542 /*@C 543 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 544 Mat options in the database. 545 546 Logically Collective on Mat 547 548 Input Parameters: 549 + A - the Mat context 550 - prefix - the prefix to prepend to all option names 551 552 Notes: 553 A hyphen (-) must NOT be given at the beginning of the prefix name. 554 The first character of all runtime options is AUTOMATICALLY the hyphen. 555 556 Level: advanced 557 558 .keywords: Mat, append, options, prefix, database 559 560 .seealso: MatGetOptionsPrefix() 561 @*/ 562 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 563 { 564 PetscErrorCode ierr; 565 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 568 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 569 PetscFunctionReturn(0); 570 } 571 572 #undef __FUNCT__ 573 #define __FUNCT__ "MatGetOptionsPrefix" 574 /*@C 575 MatGetOptionsPrefix - Sets the prefix used for searching for all 576 Mat options in the database. 577 578 Not Collective 579 580 Input Parameter: 581 . A - the Mat context 582 583 Output Parameter: 584 . prefix - pointer to the prefix string used 585 586 Notes: On the fortran side, the user should pass in a string 'prefix' of 587 sufficient length to hold the prefix. 588 589 Level: advanced 590 591 .keywords: Mat, get, options, prefix, database 592 593 .seealso: MatAppendOptionsPrefix() 594 @*/ 595 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 596 { 597 PetscErrorCode ierr; 598 599 PetscFunctionBegin; 600 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 601 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 602 PetscFunctionReturn(0); 603 } 604 605 #undef __FUNCT__ 606 #define __FUNCT__ "MatSetUp" 607 /*@ 608 MatSetUp - Sets up the internal matrix data structures for the later use. 609 610 Collective on Mat 611 612 Input Parameters: 613 . A - the Mat context 614 615 Notes: 616 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 617 618 If a suitable preallocation routine is used, this function does not need to be called. 619 620 See the Performance chapter of the PETSc users manual for how to preallocate matrices 621 622 Level: beginner 623 624 .keywords: Mat, setup 625 626 .seealso: MatCreate(), MatDestroy() 627 @*/ 628 PetscErrorCode MatSetUp(Mat A) 629 { 630 PetscMPIInt size; 631 PetscErrorCode ierr; 632 633 PetscFunctionBegin; 634 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 635 if (!((PetscObject)A)->type_name) { 636 ierr = MPI_Comm_size(((PetscObject)A)->comm, &size);CHKERRQ(ierr); 637 if (size == 1) { 638 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 639 } else { 640 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 641 } 642 } 643 if (!A->preallocated && A->ops->setup) { 644 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 645 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 646 } 647 A->preallocated = PETSC_TRUE; 648 PetscFunctionReturn(0); 649 } 650 651 652 #undef __FUNCT__ 653 #define __FUNCT__ "MatView" 654 /*@C 655 MatView - Visualizes a matrix object. 656 657 Collective on Mat 658 659 Input Parameters: 660 + mat - the matrix 661 - viewer - visualization context 662 663 Notes: 664 The available visualization contexts include 665 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 666 . PETSC_VIEWER_STDOUT_WORLD - synchronized standard 667 output where only the first processor opens 668 the file. All other processors send their 669 data to the first processor to print. 670 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 671 672 The user can open alternative visualization contexts with 673 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 674 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 675 specified file; corresponding input uses MatLoad() 676 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 677 an X window display 678 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 679 Currently only the sequential dense and AIJ 680 matrix types support the Socket viewer. 681 682 The user can call PetscViewerSetFormat() to specify the output 683 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 684 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 685 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 686 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 687 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 688 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 689 format common among all matrix types 690 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 691 format (which is in many cases the same as the default) 692 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 693 size and structure (not the matrix entries) 694 . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 695 the matrix structure 696 697 Options Database Keys: 698 + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly() 699 . -mat_view_info_detailed - Prints more detailed info 700 . -mat_view - Prints matrix in ASCII format 701 . -mat_view_matlab - Prints matrix in Matlab format 702 . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 703 . -display <name> - Sets display name (default is host) 704 . -draw_pause <sec> - Sets number of seconds to pause after display 705 . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details). 706 . -viewer_socket_machine <machine> 707 . -viewer_socket_port <port> 708 . -mat_view_binary - save matrix to file in binary format 709 - -viewer_binary_filename <name> 710 Level: beginner 711 712 Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary 713 viewer is used. 714 715 See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 716 viewer is used. 717 718 Concepts: matrices^viewing 719 Concepts: matrices^plotting 720 Concepts: matrices^printing 721 722 .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 723 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 724 @*/ 725 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 726 { 727 PetscErrorCode ierr; 728 PetscInt rows,cols,bs; 729 PetscBool iascii; 730 PetscViewerFormat format; 731 732 PetscFunctionBegin; 733 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 734 PetscValidType(mat,1); 735 if (!viewer) { 736 ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr); 737 } 738 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 739 PetscCheckSameComm(mat,1,viewer,2); 740 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 741 MatCheckPreallocated(mat,1); 742 743 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 744 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 745 if (iascii) { 746 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 747 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 748 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");CHKERRQ(ierr); 749 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 750 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 751 ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 752 if (bs != 1) { 753 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);CHKERRQ(ierr); 754 } else { 755 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 756 } 757 if (mat->factortype) { 758 const MatSolverPackage solver; 759 ierr = MatFactorGetSolverPackage(mat,&solver);CHKERRQ(ierr); 760 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 761 } 762 if (mat->ops->getinfo) { 763 MatInfo info; 764 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 765 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%D, allocated nonzeros=%D\n",(PetscInt)info.nz_used,(PetscInt)info.nz_allocated);CHKERRQ(ierr); 766 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 767 } 768 } 769 } 770 if (mat->ops->view) { 771 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 772 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 773 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 774 } else if (!iascii) { 775 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name); 776 } 777 if (iascii) { 778 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 779 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 780 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 781 } 782 } 783 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 784 PetscFunctionReturn(0); 785 } 786 787 #if defined(PETSC_USE_DEBUG) 788 #include <../src/sys/totalview/tv_data_display.h> 789 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 790 { 791 TV_add_row("Local rows", "int", &mat->rmap->n); 792 TV_add_row("Local columns", "int", &mat->cmap->n); 793 TV_add_row("Global rows", "int", &mat->rmap->N); 794 TV_add_row("Global columns", "int", &mat->cmap->N); 795 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 796 return TV_format_OK; 797 } 798 #endif 799 800 #undef __FUNCT__ 801 #define __FUNCT__ "MatLoad" 802 /*@C 803 MatLoad - Loads a matrix that has been stored in binary format 804 with MatView(). The matrix format is determined from the options database. 805 Generates a parallel MPI matrix if the communicator has more than one 806 processor. The default matrix type is AIJ. 807 808 Collective on PetscViewer 809 810 Input Parameters: 811 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 812 or some related function before a call to MatLoad() 813 - viewer - binary file viewer, created with PetscViewerBinaryOpen() 814 815 Options Database Keys: 816 Used with block matrix formats (MATSEQBAIJ, ...) to specify 817 block size 818 . -matload_block_size <bs> 819 820 Level: beginner 821 822 Notes: 823 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 824 Mat before calling this routine if you wish to set it from the options database. 825 826 MatLoad() automatically loads into the options database any options 827 given in the file filename.info where filename is the name of the file 828 that was passed to the PetscViewerBinaryOpen(). The options in the info 829 file will be ignored if you use the -viewer_binary_skip_info option. 830 831 If the type or size of newmat is not set before a call to MatLoad, PETSc 832 sets the default matrix type AIJ and sets the local and global sizes. 833 If type and/or size is already set, then the same are used. 834 835 In parallel, each processor can load a subset of rows (or the 836 entire matrix). This routine is especially useful when a large 837 matrix is stored on disk and only part of it is desired on each 838 processor. For example, a parallel solver may access only some of 839 the rows from each processor. The algorithm used here reads 840 relatively small blocks of data rather than reading the entire 841 matrix and then subsetting it. 842 843 Notes for advanced users: 844 Most users should not need to know the details of the binary storage 845 format, since MatLoad() and MatView() completely hide these details. 846 But for anyone who's interested, the standard binary matrix storage 847 format is 848 849 $ int MAT_FILE_CLASSID 850 $ int number of rows 851 $ int number of columns 852 $ int total number of nonzeros 853 $ int *number nonzeros in each row 854 $ int *column indices of all nonzeros (starting index is zero) 855 $ PetscScalar *values of all nonzeros 856 857 PETSc automatically does the byte swapping for 858 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 859 linux, Windows and the paragon; thus if you write your own binary 860 read/write routines you have to swap the bytes; see PetscBinaryRead() 861 and PetscBinaryWrite() to see how this may be done. 862 863 .keywords: matrix, load, binary, input 864 865 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad() 866 867 @*/ 868 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 869 { 870 PetscErrorCode ierr; 871 PetscBool isbinary,flg; 872 873 PetscFunctionBegin; 874 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 875 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 876 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 877 if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 878 879 if (!((PetscObject)newmat)->type_name) { 880 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 881 } 882 883 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 884 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 885 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 886 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 887 888 flg = PETSC_FALSE; 889 ierr = PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,PETSC_NULL);CHKERRQ(ierr); 890 if (flg) { 891 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 892 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 893 } 894 flg = PETSC_FALSE; 895 ierr = PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,PETSC_NULL);CHKERRQ(ierr); 896 if (flg) { 897 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 898 } 899 PetscFunctionReturn(0); 900 } 901 902 #undef __FUNCT__ 903 #define __FUNCT__ "MatDestroy" 904 /*@ 905 MatDestroy - Frees space taken by a matrix. 906 907 Collective on Mat 908 909 Input Parameter: 910 . A - the matrix 911 912 Level: beginner 913 914 @*/ 915 PetscErrorCode MatDestroy(Mat *A) 916 { 917 PetscErrorCode ierr; 918 919 PetscFunctionBegin; 920 if (!*A) PetscFunctionReturn(0); 921 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 922 if (--((PetscObject)(*A))->refct > 0) {*A = PETSC_NULL; PetscFunctionReturn(0);} 923 /* if memory was published with AMS then destroy it */ 924 ierr = PetscObjectDepublish(*A);CHKERRQ(ierr); 925 if ((*A)->ops->destroy) { 926 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 927 } 928 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 929 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 930 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 931 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 932 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 933 PetscFunctionReturn(0); 934 } 935 936 #undef __FUNCT__ 937 #define __FUNCT__ "MatSetValues" 938 /*@ 939 MatSetValues - Inserts or adds a block of values into a matrix. 940 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 941 MUST be called after all calls to MatSetValues() have been completed. 942 943 Not Collective 944 945 Input Parameters: 946 + mat - the matrix 947 . v - a logically two-dimensional array of values 948 . m, idxm - the number of rows and their global indices 949 . n, idxn - the number of columns and their global indices 950 - addv - either ADD_VALUES or INSERT_VALUES, where 951 ADD_VALUES adds values to any existing entries, and 952 INSERT_VALUES replaces existing entries with new values 953 954 Notes: 955 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 956 MatSetUp() before using this routine 957 958 By default the values, v, are row-oriented. See MatSetOption() for other options. 959 960 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 961 options cannot be mixed without intervening calls to the assembly 962 routines. 963 964 MatSetValues() uses 0-based row and column numbers in Fortran 965 as well as in C. 966 967 Negative indices may be passed in idxm and idxn, these rows and columns are 968 simply ignored. This allows easily inserting element stiffness matrices 969 with homogeneous Dirchlet boundary conditions that you don't want represented 970 in the matrix. 971 972 Efficiency Alert: 973 The routine MatSetValuesBlocked() may offer much better efficiency 974 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 975 976 Level: beginner 977 978 Concepts: matrices^putting entries in 979 980 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 981 InsertMode, INSERT_VALUES, ADD_VALUES 982 @*/ 983 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 984 { 985 PetscErrorCode ierr; 986 #if defined(PETSC_USE_DEBUG) 987 PetscInt i,j; 988 #endif 989 990 PetscFunctionBegin; 991 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 992 PetscValidType(mat,1); 993 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 994 PetscValidIntPointer(idxm,3); 995 PetscValidIntPointer(idxn,5); 996 if (v) PetscValidDoublePointer(v,6); 997 MatCheckPreallocated(mat,1); 998 if (mat->insertmode == NOT_SET_VALUES) { 999 mat->insertmode = addv; 1000 } 1001 #if defined(PETSC_USE_DEBUG) 1002 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1003 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1004 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1005 1006 if (v) { 1007 for (i=0; i<m; i++) { 1008 for (j=0; j<n; j++) { 1009 if (PetscIsInfOrNanScalar(v[i*n+j])) 1010 #if defined(PETSC_USE_COMPLEX) 1011 SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G+iG at matrix entry (%D,%D)",PetscRealPart(v[i*n+j]),PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1012 #else 1013 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G at matrix entry (%D,%D)",(PetscReal)v[i*n+j],idxm[i],idxn[j]); 1014 #endif 1015 } 1016 } 1017 } 1018 #endif 1019 1020 if (mat->assembled) { 1021 mat->was_assembled = PETSC_TRUE; 1022 mat->assembled = PETSC_FALSE; 1023 } 1024 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1025 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1026 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1027 #if defined(PETSC_HAVE_CUSP) 1028 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 1029 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 1030 } 1031 #endif 1032 PetscFunctionReturn(0); 1033 } 1034 1035 1036 #undef __FUNCT__ 1037 #define __FUNCT__ "MatSetValuesRowLocal" 1038 /*@ 1039 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1040 values into a matrix 1041 1042 Not Collective 1043 1044 Input Parameters: 1045 + mat - the matrix 1046 . row - the (block) row to set 1047 - v - a logically two-dimensional array of values 1048 1049 Notes: 1050 By the values, v, are column-oriented (for the block version) and sorted 1051 1052 All the nonzeros in the row must be provided 1053 1054 The matrix must have previously had its column indices set 1055 1056 The row must belong to this process 1057 1058 Level: intermediate 1059 1060 Concepts: matrices^putting entries in 1061 1062 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1063 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1064 @*/ 1065 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1066 { 1067 PetscErrorCode ierr; 1068 1069 PetscFunctionBegin; 1070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1071 PetscValidType(mat,1); 1072 PetscValidScalarPointer(v,2); 1073 ierr = MatSetValuesRow(mat, mat->rmap->mapping->indices[row],v);CHKERRQ(ierr); 1074 #if defined(PETSC_HAVE_CUSP) 1075 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 1076 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 1077 } 1078 #endif 1079 PetscFunctionReturn(0); 1080 } 1081 1082 #undef __FUNCT__ 1083 #define __FUNCT__ "MatSetValuesRow" 1084 /*@ 1085 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1086 values into a matrix 1087 1088 Not Collective 1089 1090 Input Parameters: 1091 + mat - the matrix 1092 . row - the (block) row to set 1093 - v - a logically two-dimensional array of values 1094 1095 Notes: 1096 The values, v, are column-oriented for the block version. 1097 1098 All the nonzeros in the row must be provided 1099 1100 THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1101 1102 The row must belong to this process 1103 1104 Level: advanced 1105 1106 Concepts: matrices^putting entries in 1107 1108 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1109 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1110 @*/ 1111 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1112 { 1113 PetscErrorCode ierr; 1114 1115 PetscFunctionBegin; 1116 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1117 PetscValidType(mat,1); 1118 MatCheckPreallocated(mat,1); 1119 PetscValidScalarPointer(v,2); 1120 #if defined(PETSC_USE_DEBUG) 1121 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1122 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1123 #endif 1124 mat->insertmode = INSERT_VALUES; 1125 1126 if (mat->assembled) { 1127 mat->was_assembled = PETSC_TRUE; 1128 mat->assembled = PETSC_FALSE; 1129 } 1130 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1131 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1132 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1133 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1134 #if defined(PETSC_HAVE_CUSP) 1135 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 1136 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 1137 } 1138 #endif 1139 PetscFunctionReturn(0); 1140 } 1141 1142 #undef __FUNCT__ 1143 #define __FUNCT__ "MatSetValuesStencil" 1144 /*@ 1145 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1146 Using structured grid indexing 1147 1148 Not Collective 1149 1150 Input Parameters: 1151 + mat - the matrix 1152 . m - number of rows being entered 1153 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1154 . n - number of columns being entered 1155 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1156 . v - a logically two-dimensional array of values 1157 - addv - either ADD_VALUES or INSERT_VALUES, where 1158 ADD_VALUES adds values to any existing entries, and 1159 INSERT_VALUES replaces existing entries with new values 1160 1161 Notes: 1162 By default the values, v, are row-oriented. See MatSetOption() for other options. 1163 1164 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1165 options cannot be mixed without intervening calls to the assembly 1166 routines. 1167 1168 The grid coordinates are across the entire grid, not just the local portion 1169 1170 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1171 as well as in C. 1172 1173 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1174 1175 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1176 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1177 1178 The columns and rows in the stencil passed in MUST be contained within the 1179 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1180 if you create a DMDA with an overlap of one grid level and on a particular process its first 1181 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1182 first i index you can use in your column and row indices in MatSetStencil() is 5. 1183 1184 In Fortran idxm and idxn should be declared as 1185 $ MatStencil idxm(4,m),idxn(4,n) 1186 and the values inserted using 1187 $ idxm(MatStencil_i,1) = i 1188 $ idxm(MatStencil_j,1) = j 1189 $ idxm(MatStencil_k,1) = k 1190 $ idxm(MatStencil_c,1) = c 1191 etc 1192 1193 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1194 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1195 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1196 DMDA_BOUNDARY_PERIODIC boundary type. 1197 1198 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 1199 a single value per point) you can skip filling those indices. 1200 1201 Inspired by the structured grid interface to the HYPRE package 1202 (http://www.llnl.gov/CASC/hypre) 1203 1204 Efficiency Alert: 1205 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1206 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1207 1208 Level: beginner 1209 1210 Concepts: matrices^putting entries in 1211 1212 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1213 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1214 @*/ 1215 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1216 { 1217 PetscErrorCode ierr; 1218 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1219 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1220 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1221 1222 PetscFunctionBegin; 1223 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1224 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1225 PetscValidType(mat,1); 1226 PetscValidIntPointer(idxm,3); 1227 PetscValidIntPointer(idxn,5); 1228 PetscValidScalarPointer(v,6); 1229 1230 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1231 jdxm = buf; jdxn = buf+m; 1232 } else { 1233 ierr = PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);CHKERRQ(ierr); 1234 jdxm = bufm; jdxn = bufn; 1235 } 1236 for (i=0; i<m; i++) { 1237 for (j=0; j<3-sdim; j++) dxm++; 1238 tmp = *dxm++ - starts[0]; 1239 for (j=0; j<dim-1; j++) { 1240 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 1241 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1242 } 1243 if (mat->stencil.noc) dxm++; 1244 jdxm[i] = tmp; 1245 } 1246 for (i=0; i<n; i++) { 1247 for (j=0; j<3-sdim; j++) dxn++; 1248 tmp = *dxn++ - starts[0]; 1249 for (j=0; j<dim-1; j++) { 1250 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 1251 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1252 } 1253 if (mat->stencil.noc) dxn++; 1254 jdxn[i] = tmp; 1255 } 1256 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1257 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1258 PetscFunctionReturn(0); 1259 } 1260 1261 #undef __FUNCT__ 1262 #define __FUNCT__ "MatSetValuesBlockedStencil" 1263 /*@C 1264 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1265 Using structured grid indexing 1266 1267 Not Collective 1268 1269 Input Parameters: 1270 + mat - the matrix 1271 . m - number of rows being entered 1272 . idxm - grid coordinates for matrix rows being entered 1273 . n - number of columns being entered 1274 . idxn - grid coordinates for matrix columns being entered 1275 . v - a logically two-dimensional array of values 1276 - addv - either ADD_VALUES or INSERT_VALUES, where 1277 ADD_VALUES adds values to any existing entries, and 1278 INSERT_VALUES replaces existing entries with new values 1279 1280 Notes: 1281 By default the values, v, are row-oriented and unsorted. 1282 See MatSetOption() for other options. 1283 1284 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1285 options cannot be mixed without intervening calls to the assembly 1286 routines. 1287 1288 The grid coordinates are across the entire grid, not just the local portion 1289 1290 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1291 as well as in C. 1292 1293 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1294 1295 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1296 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1297 1298 The columns and rows in the stencil passed in MUST be contained within the 1299 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1300 if you create a DMDA with an overlap of one grid level and on a particular process its first 1301 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1302 first i index you can use in your column and row indices in MatSetStencil() is 5. 1303 1304 In Fortran idxm and idxn should be declared as 1305 $ MatStencil idxm(4,m),idxn(4,n) 1306 and the values inserted using 1307 $ idxm(MatStencil_i,1) = i 1308 $ idxm(MatStencil_j,1) = j 1309 $ idxm(MatStencil_k,1) = k 1310 etc 1311 1312 Negative indices may be passed in idxm and idxn, these rows and columns are 1313 simply ignored. This allows easily inserting element stiffness matrices 1314 with homogeneous Dirchlet boundary conditions that you don't want represented 1315 in the matrix. 1316 1317 Inspired by the structured grid interface to the HYPRE package 1318 (http://www.llnl.gov/CASC/hypre) 1319 1320 Level: beginner 1321 1322 Concepts: matrices^putting entries in 1323 1324 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1325 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1326 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1327 @*/ 1328 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1329 { 1330 PetscErrorCode ierr; 1331 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1332 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1333 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1334 1335 PetscFunctionBegin; 1336 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1337 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1338 PetscValidType(mat,1); 1339 PetscValidIntPointer(idxm,3); 1340 PetscValidIntPointer(idxn,5); 1341 PetscValidScalarPointer(v,6); 1342 1343 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1344 jdxm = buf; jdxn = buf+m; 1345 } else { 1346 ierr = PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);CHKERRQ(ierr); 1347 jdxm = bufm; jdxn = bufn; 1348 } 1349 for (i=0; i<m; i++) { 1350 for (j=0; j<3-sdim; j++) dxm++; 1351 tmp = *dxm++ - starts[0]; 1352 for (j=0; j<sdim-1; j++) { 1353 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 1354 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1355 } 1356 dxm++; 1357 jdxm[i] = tmp; 1358 } 1359 for (i=0; i<n; i++) { 1360 for (j=0; j<3-sdim; j++) dxn++; 1361 tmp = *dxn++ - starts[0]; 1362 for (j=0; j<sdim-1; j++) { 1363 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 1364 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1365 } 1366 dxn++; 1367 jdxn[i] = tmp; 1368 } 1369 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1370 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1371 #if defined(PETSC_HAVE_CUSP) 1372 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 1373 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 1374 } 1375 #endif 1376 PetscFunctionReturn(0); 1377 } 1378 1379 #undef __FUNCT__ 1380 #define __FUNCT__ "MatSetStencil" 1381 /*@ 1382 MatSetStencil - Sets the grid information for setting values into a matrix via 1383 MatSetValuesStencil() 1384 1385 Not Collective 1386 1387 Input Parameters: 1388 + mat - the matrix 1389 . dim - dimension of the grid 1, 2, or 3 1390 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1391 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1392 - dof - number of degrees of freedom per node 1393 1394 1395 Inspired by the structured grid interface to the HYPRE package 1396 (www.llnl.gov/CASC/hyper) 1397 1398 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1399 user. 1400 1401 Level: beginner 1402 1403 Concepts: matrices^putting entries in 1404 1405 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1406 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1407 @*/ 1408 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1409 { 1410 PetscInt i; 1411 1412 PetscFunctionBegin; 1413 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1414 PetscValidIntPointer(dims,3); 1415 PetscValidIntPointer(starts,4); 1416 1417 mat->stencil.dim = dim + (dof > 1); 1418 for (i=0; i<dim; i++) { 1419 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1420 mat->stencil.starts[i] = starts[dim-i-1]; 1421 } 1422 mat->stencil.dims[dim] = dof; 1423 mat->stencil.starts[dim] = 0; 1424 mat->stencil.noc = (PetscBool)(dof == 1); 1425 PetscFunctionReturn(0); 1426 } 1427 1428 #undef __FUNCT__ 1429 #define __FUNCT__ "MatSetValuesBlocked" 1430 /*@ 1431 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1432 1433 Not Collective 1434 1435 Input Parameters: 1436 + mat - the matrix 1437 . v - a logically two-dimensional array of values 1438 . m, idxm - the number of block rows and their global block indices 1439 . n, idxn - the number of block columns and their global block indices 1440 - addv - either ADD_VALUES or INSERT_VALUES, where 1441 ADD_VALUES adds values to any existing entries, and 1442 INSERT_VALUES replaces existing entries with new values 1443 1444 Notes: 1445 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1446 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1447 1448 The m and n count the NUMBER of blocks in the row direction and column direction, 1449 NOT the total number of rows/columns; for example, if the block size is 2 and 1450 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1451 The values in idxm would be 1 2; that is the first index for each block divided by 1452 the block size. 1453 1454 Note that you must call MatSetBlockSize() when constructing this matrix (after 1455 preallocating it). 1456 1457 By default the values, v, are row-oriented, so the layout of 1458 v is the same as for MatSetValues(). See MatSetOption() for other options. 1459 1460 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1461 options cannot be mixed without intervening calls to the assembly 1462 routines. 1463 1464 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1465 as well as in C. 1466 1467 Negative indices may be passed in idxm and idxn, these rows and columns are 1468 simply ignored. This allows easily inserting element stiffness matrices 1469 with homogeneous Dirchlet boundary conditions that you don't want represented 1470 in the matrix. 1471 1472 Each time an entry is set within a sparse matrix via MatSetValues(), 1473 internal searching must be done to determine where to place the the 1474 data in the matrix storage space. By instead inserting blocks of 1475 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1476 reduced. 1477 1478 Example: 1479 $ Suppose m=n=2 and block size(bs) = 2 The array is 1480 $ 1481 $ 1 2 | 3 4 1482 $ 5 6 | 7 8 1483 $ - - - | - - - 1484 $ 9 10 | 11 12 1485 $ 13 14 | 15 16 1486 $ 1487 $ v[] should be passed in like 1488 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1489 $ 1490 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1491 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1492 1493 Level: intermediate 1494 1495 Concepts: matrices^putting entries in blocked 1496 1497 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1498 @*/ 1499 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1500 { 1501 PetscErrorCode ierr; 1502 1503 PetscFunctionBegin; 1504 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1505 PetscValidType(mat,1); 1506 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1507 PetscValidIntPointer(idxm,3); 1508 PetscValidIntPointer(idxn,5); 1509 PetscValidScalarPointer(v,6); 1510 MatCheckPreallocated(mat,1); 1511 if (mat->insertmode == NOT_SET_VALUES) { 1512 mat->insertmode = addv; 1513 } 1514 #if defined(PETSC_USE_DEBUG) 1515 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1516 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1517 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1518 #endif 1519 1520 if (mat->assembled) { 1521 mat->was_assembled = PETSC_TRUE; 1522 mat->assembled = PETSC_FALSE; 1523 } 1524 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1525 if (mat->ops->setvaluesblocked) { 1526 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1527 } else { 1528 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1529 PetscInt i,j,bs=mat->rmap->bs; 1530 if ((m+n)*bs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1531 iidxm = buf; iidxn = buf + m*bs; 1532 } else { 1533 ierr = PetscMalloc2(m*bs,PetscInt,&bufr,n*bs,PetscInt,&bufc);CHKERRQ(ierr); 1534 iidxm = bufr; iidxn = bufc; 1535 } 1536 for (i=0; i<m; i++) 1537 for (j=0; j<bs; j++) 1538 iidxm[i*bs+j] = bs*idxm[i] + j; 1539 for (i=0; i<n; i++) 1540 for (j=0; j<bs; j++) 1541 iidxn[i*bs+j] = bs*idxn[i] + j; 1542 ierr = MatSetValues(mat,m*bs,iidxm,n*bs,iidxn,v,addv);CHKERRQ(ierr); 1543 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1544 } 1545 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1546 #if defined(PETSC_HAVE_CUSP) 1547 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 1548 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 1549 } 1550 #endif 1551 PetscFunctionReturn(0); 1552 } 1553 1554 #undef __FUNCT__ 1555 #define __FUNCT__ "MatGetValues" 1556 /*@ 1557 MatGetValues - Gets a block of values from a matrix. 1558 1559 Not Collective; currently only returns a local block 1560 1561 Input Parameters: 1562 + mat - the matrix 1563 . v - a logically two-dimensional array for storing the values 1564 . m, idxm - the number of rows and their global indices 1565 - n, idxn - the number of columns and their global indices 1566 1567 Notes: 1568 The user must allocate space (m*n PetscScalars) for the values, v. 1569 The values, v, are then returned in a row-oriented format, 1570 analogous to that used by default in MatSetValues(). 1571 1572 MatGetValues() uses 0-based row and column numbers in 1573 Fortran as well as in C. 1574 1575 MatGetValues() requires that the matrix has been assembled 1576 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1577 MatSetValues() and MatGetValues() CANNOT be made in succession 1578 without intermediate matrix assembly. 1579 1580 Negative row or column indices will be ignored and those locations in v[] will be 1581 left unchanged. 1582 1583 Level: advanced 1584 1585 Concepts: matrices^accessing values 1586 1587 .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues() 1588 @*/ 1589 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1590 { 1591 PetscErrorCode ierr; 1592 1593 PetscFunctionBegin; 1594 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1595 PetscValidType(mat,1); 1596 if (!m || !n) PetscFunctionReturn(0); 1597 PetscValidIntPointer(idxm,3); 1598 PetscValidIntPointer(idxn,5); 1599 PetscValidScalarPointer(v,6); 1600 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1601 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1602 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1603 MatCheckPreallocated(mat,1); 1604 1605 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1606 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1607 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1608 PetscFunctionReturn(0); 1609 } 1610 1611 #undef __FUNCT__ 1612 #define __FUNCT__ "MatSetValuesBatch" 1613 /*@ 1614 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1615 the same size. Currently, this can only be called once and creates the given matrix. 1616 1617 Not Collective 1618 1619 Input Parameters: 1620 + mat - the matrix 1621 . nb - the number of blocks 1622 . bs - the number of rows (and columns) in each block 1623 . rows - a concatenation of the rows for each block 1624 - v - a concatenation of logically two-dimensional arrays of values 1625 1626 Notes: 1627 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1628 1629 Level: advanced 1630 1631 Concepts: matrices^putting entries in 1632 1633 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1634 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1635 @*/ 1636 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1637 { 1638 PetscErrorCode ierr; 1639 1640 PetscFunctionBegin; 1641 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1642 PetscValidType(mat,1); 1643 PetscValidScalarPointer(rows,4); 1644 PetscValidScalarPointer(v,5); 1645 #if defined(PETSC_USE_DEBUG) 1646 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1647 #endif 1648 1649 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1650 if (mat->ops->setvaluesbatch) { 1651 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1652 } else { 1653 PetscInt b; 1654 for(b = 0; b < nb; ++b) { 1655 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1656 } 1657 } 1658 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1659 PetscFunctionReturn(0); 1660 } 1661 1662 #undef __FUNCT__ 1663 #define __FUNCT__ "MatSetLocalToGlobalMapping" 1664 /*@ 1665 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1666 the routine MatSetValuesLocal() to allow users to insert matrix entries 1667 using a local (per-processor) numbering. 1668 1669 Not Collective 1670 1671 Input Parameters: 1672 + x - the matrix 1673 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() 1674 or ISLocalToGlobalMappingCreateIS() 1675 - cmapping - column mapping 1676 1677 Level: intermediate 1678 1679 Concepts: matrices^local to global mapping 1680 Concepts: local to global mapping^for matrices 1681 1682 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 1683 @*/ 1684 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1685 { 1686 PetscErrorCode ierr; 1687 PetscFunctionBegin; 1688 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 1689 PetscValidType(x,1); 1690 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 1691 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 1692 1693 if (x->ops->setlocaltoglobalmapping) { 1694 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 1695 } else { 1696 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 1697 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 1698 } 1699 PetscFunctionReturn(0); 1700 } 1701 1702 #undef __FUNCT__ 1703 #define __FUNCT__ "MatSetLocalToGlobalMappingBlock" 1704 /*@ 1705 MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use 1706 by the routine MatSetValuesBlockedLocal() to allow users to insert matrix 1707 entries using a local (per-processor) numbering. 1708 1709 Not Collective 1710 1711 Input Parameters: 1712 + x - the matrix 1713 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or 1714 ISLocalToGlobalMappingCreateIS() 1715 - cmapping - column mapping 1716 1717 Level: intermediate 1718 1719 Concepts: matrices^local to global mapping blocked 1720 Concepts: local to global mapping^for matrices, blocked 1721 1722 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(), 1723 MatSetValuesBlocked(), MatSetValuesLocal() 1724 @*/ 1725 PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1726 { 1727 PetscErrorCode ierr; 1728 PetscFunctionBegin; 1729 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 1730 PetscValidType(x,1); 1731 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 1732 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 1733 1734 ierr = PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);CHKERRQ(ierr); 1735 ierr = PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);CHKERRQ(ierr); 1736 PetscFunctionReturn(0); 1737 } 1738 1739 #undef __FUNCT__ 1740 #define __FUNCT__ "MatGetLocalToGlobalMapping" 1741 /*@ 1742 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 1743 1744 Not Collective 1745 1746 Input Parameters: 1747 . A - the matrix 1748 1749 Output Parameters: 1750 + rmapping - row mapping 1751 - cmapping - column mapping 1752 1753 Level: advanced 1754 1755 Concepts: matrices^local to global mapping 1756 Concepts: local to global mapping^for matrices 1757 1758 .seealso: MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock() 1759 @*/ 1760 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 1761 { 1762 PetscFunctionBegin; 1763 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1764 PetscValidType(A,1); 1765 if (rmapping) PetscValidPointer(rmapping,2); 1766 if (cmapping) PetscValidPointer(cmapping,3); 1767 if (rmapping) *rmapping = A->rmap->mapping; 1768 if (cmapping) *cmapping = A->cmap->mapping; 1769 PetscFunctionReturn(0); 1770 } 1771 1772 #undef __FUNCT__ 1773 #define __FUNCT__ "MatGetLocalToGlobalMappingBlock" 1774 /*@ 1775 MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock() 1776 1777 Not Collective 1778 1779 Input Parameters: 1780 . A - the matrix 1781 1782 Output Parameters: 1783 + rmapping - row mapping 1784 - cmapping - column mapping 1785 1786 Level: advanced 1787 1788 Concepts: matrices^local to global mapping blocked 1789 Concepts: local to global mapping^for matrices, blocked 1790 1791 .seealso: MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping() 1792 @*/ 1793 PetscErrorCode MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 1794 { 1795 PetscFunctionBegin; 1796 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 1797 PetscValidType(A,1); 1798 if (rmapping) PetscValidPointer(rmapping,2); 1799 if (cmapping) PetscValidPointer(cmapping,3); 1800 if (rmapping) *rmapping = A->rmap->bmapping; 1801 if (cmapping) *cmapping = A->cmap->bmapping; 1802 PetscFunctionReturn(0); 1803 } 1804 1805 #undef __FUNCT__ 1806 #define __FUNCT__ "MatSetValuesLocal" 1807 /*@ 1808 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 1809 using a local ordering of the nodes. 1810 1811 Not Collective 1812 1813 Input Parameters: 1814 + x - the matrix 1815 . nrow, irow - number of rows and their local indices 1816 . ncol, icol - number of columns and their local indices 1817 . y - a logically two-dimensional array of values 1818 - addv - either INSERT_VALUES or ADD_VALUES, where 1819 ADD_VALUES adds values to any existing entries, and 1820 INSERT_VALUES replaces existing entries with new values 1821 1822 Notes: 1823 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1824 MatSetUp() before using this routine 1825 1826 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 1827 1828 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 1829 options cannot be mixed without intervening calls to the assembly 1830 routines. 1831 1832 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1833 MUST be called after all calls to MatSetValuesLocal() have been completed. 1834 1835 Level: intermediate 1836 1837 Concepts: matrices^putting entries in with local numbering 1838 1839 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 1840 MatSetValueLocal() 1841 @*/ 1842 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 1843 { 1844 PetscErrorCode ierr; 1845 1846 PetscFunctionBegin; 1847 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1848 PetscValidType(mat,1); 1849 MatCheckPreallocated(mat,1); 1850 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 1851 PetscValidIntPointer(irow,3); 1852 PetscValidIntPointer(icol,5); 1853 PetscValidScalarPointer(y,6); 1854 if (mat->insertmode == NOT_SET_VALUES) { 1855 mat->insertmode = addv; 1856 } 1857 #if defined(PETSC_USE_DEBUG) 1858 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1859 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1860 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1861 #endif 1862 1863 if (mat->assembled) { 1864 mat->was_assembled = PETSC_TRUE; 1865 mat->assembled = PETSC_FALSE; 1866 } 1867 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1868 if (mat->ops->setvalueslocal) { 1869 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 1870 } else { 1871 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 1872 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1873 irowm = buf; icolm = buf+nrow; 1874 } else { 1875 ierr = PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);CHKERRQ(ierr); 1876 irowm = bufr; icolm = bufc; 1877 } 1878 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 1879 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 1880 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 1881 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1882 } 1883 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1884 #if defined(PETSC_HAVE_CUSP) 1885 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 1886 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 1887 } 1888 #endif 1889 PetscFunctionReturn(0); 1890 } 1891 1892 #undef __FUNCT__ 1893 #define __FUNCT__ "MatSetValuesBlockedLocal" 1894 /*@ 1895 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 1896 using a local ordering of the nodes a block at a time. 1897 1898 Not Collective 1899 1900 Input Parameters: 1901 + x - the matrix 1902 . nrow, irow - number of rows and their local indices 1903 . ncol, icol - number of columns and their local indices 1904 . y - a logically two-dimensional array of values 1905 - addv - either INSERT_VALUES or ADD_VALUES, where 1906 ADD_VALUES adds values to any existing entries, and 1907 INSERT_VALUES replaces existing entries with new values 1908 1909 Notes: 1910 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1911 MatSetUp() before using this routine 1912 1913 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMappingBlock() 1914 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 1915 1916 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 1917 options cannot be mixed without intervening calls to the assembly 1918 routines. 1919 1920 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1921 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 1922 1923 Level: intermediate 1924 1925 Concepts: matrices^putting blocked values in with local numbering 1926 1927 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(), 1928 MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked() 1929 @*/ 1930 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 1931 { 1932 PetscErrorCode ierr; 1933 1934 PetscFunctionBegin; 1935 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1936 PetscValidType(mat,1); 1937 MatCheckPreallocated(mat,1); 1938 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 1939 PetscValidIntPointer(irow,3); 1940 PetscValidIntPointer(icol,5); 1941 PetscValidScalarPointer(y,6); 1942 if (mat->insertmode == NOT_SET_VALUES) { 1943 mat->insertmode = addv; 1944 } 1945 #if defined(PETSC_USE_DEBUG) 1946 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1947 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1948 if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1949 #endif 1950 1951 if (mat->assembled) { 1952 mat->was_assembled = PETSC_TRUE; 1953 mat->assembled = PETSC_FALSE; 1954 } 1955 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1956 if (mat->ops->setvaluesblockedlocal) { 1957 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 1958 } else { 1959 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 1960 if (mat->rmap->bmapping && mat->cmap->bmapping) { 1961 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1962 irowm = buf; icolm = buf + nrow; 1963 } else { 1964 ierr = PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);CHKERRQ(ierr); 1965 irowm = bufr; icolm = bufc; 1966 } 1967 ierr = ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);CHKERRQ(ierr); 1968 ierr = ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);CHKERRQ(ierr); 1969 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 1970 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1971 } else { 1972 PetscInt i,j,bs=mat->rmap->bs; 1973 if ((nrow+ncol)*bs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1974 irowm = buf; icolm = buf + nrow; 1975 } else { 1976 ierr = PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*bs,PetscInt,&bufc);CHKERRQ(ierr); 1977 irowm = bufr; icolm = bufc; 1978 } 1979 for (i=0; i<nrow; i++) 1980 for (j=0; j<bs; j++) 1981 irowm[i*bs+j] = irow[i]*bs+j; 1982 for (i=0; i<ncol; i++) 1983 for (j=0; j<bs; j++) 1984 icolm[i*bs+j] = icol[i]*bs+j; 1985 ierr = MatSetValuesLocal(mat,nrow*bs,irowm,ncol*bs,icolm,y,addv);CHKERRQ(ierr); 1986 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1987 } 1988 } 1989 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1990 #if defined(PETSC_HAVE_CUSP) 1991 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 1992 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 1993 } 1994 #endif 1995 PetscFunctionReturn(0); 1996 } 1997 1998 #undef __FUNCT__ 1999 #define __FUNCT__ "MatMultDiagonalBlock" 2000 /*@ 2001 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2002 2003 Collective on Mat and Vec 2004 2005 Input Parameters: 2006 + mat - the matrix 2007 - x - the vector to be multiplied 2008 2009 Output Parameters: 2010 . y - the result 2011 2012 Notes: 2013 The vectors x and y cannot be the same. I.e., one cannot 2014 call MatMult(A,y,y). 2015 2016 Level: developer 2017 2018 Concepts: matrix-vector product 2019 2020 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2021 @*/ 2022 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2023 { 2024 PetscErrorCode ierr; 2025 2026 PetscFunctionBegin; 2027 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2028 PetscValidType(mat,1); 2029 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2030 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2031 2032 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2033 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2034 if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2035 MatCheckPreallocated(mat,1); 2036 2037 if (!mat->ops->multdiagonalblock) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2038 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2039 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2040 PetscFunctionReturn(0); 2041 } 2042 2043 /* --------------------------------------------------------*/ 2044 #undef __FUNCT__ 2045 #define __FUNCT__ "MatMult" 2046 /*@ 2047 MatMult - Computes the matrix-vector product, y = Ax. 2048 2049 Neighbor-wise Collective on Mat and Vec 2050 2051 Input Parameters: 2052 + mat - the matrix 2053 - x - the vector to be multiplied 2054 2055 Output Parameters: 2056 . y - the result 2057 2058 Notes: 2059 The vectors x and y cannot be the same. I.e., one cannot 2060 call MatMult(A,y,y). 2061 2062 Level: beginner 2063 2064 Concepts: matrix-vector product 2065 2066 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2067 @*/ 2068 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2069 { 2070 PetscErrorCode ierr; 2071 2072 PetscFunctionBegin; 2073 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2074 PetscValidType(mat,1); 2075 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2076 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2077 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2078 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2079 if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2080 #ifndef PETSC_HAVE_CONSTRAINTS 2081 if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2082 if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2083 if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n); 2084 #endif 2085 VecValidValues(x,2,PETSC_TRUE); 2086 MatCheckPreallocated(mat,1); 2087 2088 if (!mat->ops->mult) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2089 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2090 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2091 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2092 VecValidValues(y,3,PETSC_FALSE); 2093 PetscFunctionReturn(0); 2094 } 2095 2096 #undef __FUNCT__ 2097 #define __FUNCT__ "MatMultTranspose" 2098 /*@ 2099 MatMultTranspose - Computes matrix transpose times a vector. 2100 2101 Neighbor-wise Collective on Mat and Vec 2102 2103 Input Parameters: 2104 + mat - the matrix 2105 - x - the vector to be multilplied 2106 2107 Output Parameters: 2108 . y - the result 2109 2110 Notes: 2111 The vectors x and y cannot be the same. I.e., one cannot 2112 call MatMultTranspose(A,y,y). 2113 2114 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2115 use MatMultHermitianTranspose() 2116 2117 Level: beginner 2118 2119 Concepts: matrix vector product^transpose 2120 2121 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2122 @*/ 2123 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2124 { 2125 PetscErrorCode ierr; 2126 2127 PetscFunctionBegin; 2128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2129 PetscValidType(mat,1); 2130 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2131 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2132 2133 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2134 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2135 if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2136 #ifndef PETSC_HAVE_CONSTRAINTS 2137 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 2138 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 2139 #endif 2140 VecValidValues(x,2,PETSC_TRUE); 2141 MatCheckPreallocated(mat,1); 2142 2143 if (!mat->ops->multtranspose) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined"); 2144 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2145 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2146 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2147 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2148 VecValidValues(y,3,PETSC_FALSE); 2149 PetscFunctionReturn(0); 2150 } 2151 2152 #undef __FUNCT__ 2153 #define __FUNCT__ "MatMultHermitianTranspose" 2154 /*@ 2155 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2156 2157 Neighbor-wise Collective on Mat and Vec 2158 2159 Input Parameters: 2160 + mat - the matrix 2161 - x - the vector to be multilplied 2162 2163 Output Parameters: 2164 . y - the result 2165 2166 Notes: 2167 The vectors x and y cannot be the same. I.e., one cannot 2168 call MatMultHermitianTranspose(A,y,y). 2169 2170 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2171 2172 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2173 2174 Level: beginner 2175 2176 Concepts: matrix vector product^transpose 2177 2178 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2179 @*/ 2180 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2181 { 2182 PetscErrorCode ierr; 2183 2184 PetscFunctionBegin; 2185 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2186 PetscValidType(mat,1); 2187 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2188 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2189 2190 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2191 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2192 if (x == y) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2193 #ifndef PETSC_HAVE_CONSTRAINTS 2194 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 2195 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 2196 #endif 2197 MatCheckPreallocated(mat,1); 2198 2199 if (!mat->ops->multhermitiantranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2200 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2201 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2202 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2203 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2204 PetscFunctionReturn(0); 2205 } 2206 2207 #undef __FUNCT__ 2208 #define __FUNCT__ "MatMultAdd" 2209 /*@ 2210 MatMultAdd - Computes v3 = v2 + A * v1. 2211 2212 Neighbor-wise Collective on Mat and Vec 2213 2214 Input Parameters: 2215 + mat - the matrix 2216 - v1, v2 - the vectors 2217 2218 Output Parameters: 2219 . v3 - the result 2220 2221 Notes: 2222 The vectors v1 and v3 cannot be the same. I.e., one cannot 2223 call MatMultAdd(A,v1,v2,v1). 2224 2225 Level: beginner 2226 2227 Concepts: matrix vector product^addition 2228 2229 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2230 @*/ 2231 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2232 { 2233 PetscErrorCode ierr; 2234 2235 PetscFunctionBegin; 2236 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2237 PetscValidType(mat,1); 2238 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2239 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2240 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2241 2242 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2243 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2244 if (mat->cmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N); 2245 /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N); 2246 if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */ 2247 if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n); 2248 if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n); 2249 if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2250 MatCheckPreallocated(mat,1); 2251 2252 if (!mat->ops->multadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2253 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2254 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2255 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2256 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2257 PetscFunctionReturn(0); 2258 } 2259 2260 #undef __FUNCT__ 2261 #define __FUNCT__ "MatMultTransposeAdd" 2262 /*@ 2263 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2264 2265 Neighbor-wise Collective on Mat and Vec 2266 2267 Input Parameters: 2268 + mat - the matrix 2269 - v1, v2 - the vectors 2270 2271 Output Parameters: 2272 . v3 - the result 2273 2274 Notes: 2275 The vectors v1 and v3 cannot be the same. I.e., one cannot 2276 call MatMultTransposeAdd(A,v1,v2,v1). 2277 2278 Level: beginner 2279 2280 Concepts: matrix vector product^transpose and addition 2281 2282 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2283 @*/ 2284 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2285 { 2286 PetscErrorCode ierr; 2287 2288 PetscFunctionBegin; 2289 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2290 PetscValidType(mat,1); 2291 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2292 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2293 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2294 2295 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2296 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2297 if (!mat->ops->multtransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2298 if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2299 if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N); 2300 if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N); 2301 if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N); 2302 MatCheckPreallocated(mat,1); 2303 2304 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2305 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2306 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2307 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2308 PetscFunctionReturn(0); 2309 } 2310 2311 #undef __FUNCT__ 2312 #define __FUNCT__ "MatMultHermitianTransposeAdd" 2313 /*@ 2314 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2315 2316 Neighbor-wise Collective on Mat and Vec 2317 2318 Input Parameters: 2319 + mat - the matrix 2320 - v1, v2 - the vectors 2321 2322 Output Parameters: 2323 . v3 - the result 2324 2325 Notes: 2326 The vectors v1 and v3 cannot be the same. I.e., one cannot 2327 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2328 2329 Level: beginner 2330 2331 Concepts: matrix vector product^transpose and addition 2332 2333 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2334 @*/ 2335 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2336 { 2337 PetscErrorCode ierr; 2338 2339 PetscFunctionBegin; 2340 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2341 PetscValidType(mat,1); 2342 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2343 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2344 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2345 2346 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2347 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2348 if (!mat->ops->multhermitiantransposeadd) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2349 if (v1 == v3) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2350 if (mat->rmap->N != v1->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N); 2351 if (mat->cmap->N != v2->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N); 2352 if (mat->cmap->N != v3->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N); 2353 MatCheckPreallocated(mat,1); 2354 2355 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2356 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2357 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2358 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2359 PetscFunctionReturn(0); 2360 } 2361 2362 #undef __FUNCT__ 2363 #define __FUNCT__ "MatMultConstrained" 2364 /*@ 2365 MatMultConstrained - The inner multiplication routine for a 2366 constrained matrix P^T A P. 2367 2368 Neighbor-wise Collective on Mat and Vec 2369 2370 Input Parameters: 2371 + mat - the matrix 2372 - x - the vector to be multilplied 2373 2374 Output Parameters: 2375 . y - the result 2376 2377 Notes: 2378 The vectors x and y cannot be the same. I.e., one cannot 2379 call MatMult(A,y,y). 2380 2381 Level: beginner 2382 2383 .keywords: matrix, multiply, matrix-vector product, constraint 2384 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2385 @*/ 2386 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2387 { 2388 PetscErrorCode ierr; 2389 2390 PetscFunctionBegin; 2391 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2392 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2393 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2394 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2395 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2396 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2397 if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2398 if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2399 if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n); 2400 2401 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2402 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2403 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2404 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2405 2406 PetscFunctionReturn(0); 2407 } 2408 2409 #undef __FUNCT__ 2410 #define __FUNCT__ "MatMultTransposeConstrained" 2411 /*@ 2412 MatMultTransposeConstrained - The inner multiplication routine for a 2413 constrained matrix P^T A^T P. 2414 2415 Neighbor-wise Collective on Mat and Vec 2416 2417 Input Parameters: 2418 + mat - the matrix 2419 - x - the vector to be multilplied 2420 2421 Output Parameters: 2422 . y - the result 2423 2424 Notes: 2425 The vectors x and y cannot be the same. I.e., one cannot 2426 call MatMult(A,y,y). 2427 2428 Level: beginner 2429 2430 .keywords: matrix, multiply, matrix-vector product, constraint 2431 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2432 @*/ 2433 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2434 { 2435 PetscErrorCode ierr; 2436 2437 PetscFunctionBegin; 2438 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2439 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2440 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2441 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2442 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2443 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2444 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2445 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2446 2447 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2448 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2449 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2450 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2451 2452 PetscFunctionReturn(0); 2453 } 2454 2455 #undef __FUNCT__ 2456 #define __FUNCT__ "MatGetFactorType" 2457 /*@C 2458 MatGetFactorType - gets the type of factorization it is 2459 2460 Note Collective 2461 as the flag 2462 2463 Input Parameters: 2464 . mat - the matrix 2465 2466 Output Parameters: 2467 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2468 2469 Level: intermediate 2470 2471 .seealso: MatFactorType, MatGetFactor() 2472 @*/ 2473 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2474 { 2475 PetscFunctionBegin; 2476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2477 PetscValidType(mat,1); 2478 *t = mat->factortype; 2479 PetscFunctionReturn(0); 2480 } 2481 2482 /* ------------------------------------------------------------*/ 2483 #undef __FUNCT__ 2484 #define __FUNCT__ "MatGetInfo" 2485 /*@C 2486 MatGetInfo - Returns information about matrix storage (number of 2487 nonzeros, memory, etc.). 2488 2489 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2490 2491 Input Parameters: 2492 . mat - the matrix 2493 2494 Output Parameters: 2495 + flag - flag indicating the type of parameters to be returned 2496 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2497 MAT_GLOBAL_SUM - sum over all processors) 2498 - info - matrix information context 2499 2500 Notes: 2501 The MatInfo context contains a variety of matrix data, including 2502 number of nonzeros allocated and used, number of mallocs during 2503 matrix assembly, etc. Additional information for factored matrices 2504 is provided (such as the fill ratio, number of mallocs during 2505 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2506 when using the runtime options 2507 $ -info -mat_view_info 2508 2509 Example for C/C++ Users: 2510 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2511 data within the MatInfo context. For example, 2512 .vb 2513 MatInfo info; 2514 Mat A; 2515 double mal, nz_a, nz_u; 2516 2517 MatGetInfo(A,MAT_LOCAL,&info); 2518 mal = info.mallocs; 2519 nz_a = info.nz_allocated; 2520 .ve 2521 2522 Example for Fortran Users: 2523 Fortran users should declare info as a double precision 2524 array of dimension MAT_INFO_SIZE, and then extract the parameters 2525 of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h 2526 a complete list of parameter names. 2527 .vb 2528 double precision info(MAT_INFO_SIZE) 2529 double precision mal, nz_a 2530 Mat A 2531 integer ierr 2532 2533 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2534 mal = info(MAT_INFO_MALLOCS) 2535 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2536 .ve 2537 2538 Level: intermediate 2539 2540 Concepts: matrices^getting information on 2541 2542 Developer Note: fortran interface is not autogenerated as the f90 2543 interface defintion cannot be generated correctly [due to MatInfo] 2544 2545 .seealso: MatStashGetInfo() 2546 2547 @*/ 2548 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2549 { 2550 PetscErrorCode ierr; 2551 2552 PetscFunctionBegin; 2553 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2554 PetscValidType(mat,1); 2555 PetscValidPointer(info,3); 2556 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2557 MatCheckPreallocated(mat,1); 2558 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2559 PetscFunctionReturn(0); 2560 } 2561 2562 /* ----------------------------------------------------------*/ 2563 2564 #undef __FUNCT__ 2565 #define __FUNCT__ "MatLUFactor" 2566 /*@C 2567 MatLUFactor - Performs in-place LU factorization of matrix. 2568 2569 Collective on Mat 2570 2571 Input Parameters: 2572 + mat - the matrix 2573 . row - row permutation 2574 . col - column permutation 2575 - info - options for factorization, includes 2576 $ fill - expected fill as ratio of original fill. 2577 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2578 $ Run with the option -info to determine an optimal value to use 2579 2580 Notes: 2581 Most users should employ the simplified KSP interface for linear solvers 2582 instead of working directly with matrix algebra routines such as this. 2583 See, e.g., KSPCreate(). 2584 2585 This changes the state of the matrix to a factored matrix; it cannot be used 2586 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2587 2588 Level: developer 2589 2590 Concepts: matrices^LU factorization 2591 2592 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2593 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2594 2595 Developer Note: fortran interface is not autogenerated as the f90 2596 interface defintion cannot be generated correctly [due to MatFactorInfo] 2597 2598 @*/ 2599 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2600 { 2601 PetscErrorCode ierr; 2602 MatFactorInfo tinfo; 2603 2604 PetscFunctionBegin; 2605 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2606 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2607 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2608 if (info) PetscValidPointer(info,4); 2609 PetscValidType(mat,1); 2610 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2611 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2612 if (!mat->ops->lufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2613 MatCheckPreallocated(mat,1); 2614 if (!info) { 2615 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2616 info = &tinfo; 2617 } 2618 2619 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2620 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2621 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2622 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2623 PetscFunctionReturn(0); 2624 } 2625 2626 #undef __FUNCT__ 2627 #define __FUNCT__ "MatILUFactor" 2628 /*@C 2629 MatILUFactor - Performs in-place ILU factorization of matrix. 2630 2631 Collective on Mat 2632 2633 Input Parameters: 2634 + mat - the matrix 2635 . row - row permutation 2636 . col - column permutation 2637 - info - structure containing 2638 $ levels - number of levels of fill. 2639 $ expected fill - as ratio of original fill. 2640 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2641 missing diagonal entries) 2642 2643 Notes: 2644 Probably really in-place only when level of fill is zero, otherwise allocates 2645 new space to store factored matrix and deletes previous memory. 2646 2647 Most users should employ the simplified KSP interface for linear solvers 2648 instead of working directly with matrix algebra routines such as this. 2649 See, e.g., KSPCreate(). 2650 2651 Level: developer 2652 2653 Concepts: matrices^ILU factorization 2654 2655 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2656 2657 Developer Note: fortran interface is not autogenerated as the f90 2658 interface defintion cannot be generated correctly [due to MatFactorInfo] 2659 2660 @*/ 2661 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2662 { 2663 PetscErrorCode ierr; 2664 2665 PetscFunctionBegin; 2666 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2667 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2668 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2669 PetscValidPointer(info,4); 2670 PetscValidType(mat,1); 2671 if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square"); 2672 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2673 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2674 if (!mat->ops->ilufactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2675 MatCheckPreallocated(mat,1); 2676 2677 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2678 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2679 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2680 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2681 PetscFunctionReturn(0); 2682 } 2683 2684 #undef __FUNCT__ 2685 #define __FUNCT__ "MatLUFactorSymbolic" 2686 /*@C 2687 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2688 Call this routine before calling MatLUFactorNumeric(). 2689 2690 Collective on Mat 2691 2692 Input Parameters: 2693 + fact - the factor matrix obtained with MatGetFactor() 2694 . mat - the matrix 2695 . row, col - row and column permutations 2696 - info - options for factorization, includes 2697 $ fill - expected fill as ratio of original fill. 2698 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2699 $ Run with the option -info to determine an optimal value to use 2700 2701 2702 Notes: 2703 See the <a href="../../docs/manual.pdf">users manual</a> for additional information about 2704 choosing the fill factor for better efficiency. 2705 2706 Most users should employ the simplified KSP interface for linear solvers 2707 instead of working directly with matrix algebra routines such as this. 2708 See, e.g., KSPCreate(). 2709 2710 Level: developer 2711 2712 Concepts: matrices^LU symbolic factorization 2713 2714 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2715 2716 Developer Note: fortran interface is not autogenerated as the f90 2717 interface defintion cannot be generated correctly [due to MatFactorInfo] 2718 2719 @*/ 2720 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 2721 { 2722 PetscErrorCode ierr; 2723 2724 PetscFunctionBegin; 2725 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2726 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2727 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2728 if (info) PetscValidPointer(info,4); 2729 PetscValidType(mat,1); 2730 PetscValidPointer(fact,5); 2731 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2732 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2733 if (!(fact)->ops->lufactorsymbolic) { 2734 const MatSolverPackage spackage; 2735 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 2736 SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 2737 } 2738 MatCheckPreallocated(mat,2); 2739 2740 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 2741 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 2742 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 2743 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 2744 PetscFunctionReturn(0); 2745 } 2746 2747 #undef __FUNCT__ 2748 #define __FUNCT__ "MatLUFactorNumeric" 2749 /*@C 2750 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 2751 Call this routine after first calling MatLUFactorSymbolic(). 2752 2753 Collective on Mat 2754 2755 Input Parameters: 2756 + fact - the factor matrix obtained with MatGetFactor() 2757 . mat - the matrix 2758 - info - options for factorization 2759 2760 Notes: 2761 See MatLUFactor() for in-place factorization. See 2762 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 2763 2764 Most users should employ the simplified KSP interface for linear solvers 2765 instead of working directly with matrix algebra routines such as this. 2766 See, e.g., KSPCreate(). 2767 2768 Level: developer 2769 2770 Concepts: matrices^LU numeric factorization 2771 2772 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 2773 2774 Developer Note: fortran interface is not autogenerated as the f90 2775 interface defintion cannot be generated correctly [due to MatFactorInfo] 2776 2777 @*/ 2778 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 2779 { 2780 PetscErrorCode ierr; 2781 2782 PetscFunctionBegin; 2783 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2784 PetscValidType(mat,1); 2785 PetscValidPointer(fact,2); 2786 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 2787 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2788 if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) { 2789 SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 2790 } 2791 if (!(fact)->ops->lufactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 2792 MatCheckPreallocated(mat,2); 2793 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 2794 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 2795 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 2796 2797 ierr = MatView_Private(fact);CHKERRQ(ierr); 2798 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 2799 PetscFunctionReturn(0); 2800 } 2801 2802 #undef __FUNCT__ 2803 #define __FUNCT__ "MatCholeskyFactor" 2804 /*@C 2805 MatCholeskyFactor - Performs in-place Cholesky factorization of a 2806 symmetric matrix. 2807 2808 Collective on Mat 2809 2810 Input Parameters: 2811 + mat - the matrix 2812 . perm - row and column permutations 2813 - f - expected fill as ratio of original fill 2814 2815 Notes: 2816 See MatLUFactor() for the nonsymmetric case. See also 2817 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 2818 2819 Most users should employ the simplified KSP interface for linear solvers 2820 instead of working directly with matrix algebra routines such as this. 2821 See, e.g., KSPCreate(). 2822 2823 Level: developer 2824 2825 Concepts: matrices^Cholesky factorization 2826 2827 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 2828 MatGetOrdering() 2829 2830 Developer Note: fortran interface is not autogenerated as the f90 2831 interface defintion cannot be generated correctly [due to MatFactorInfo] 2832 2833 @*/ 2834 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 2835 { 2836 PetscErrorCode ierr; 2837 2838 PetscFunctionBegin; 2839 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2840 PetscValidType(mat,1); 2841 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 2842 if (info) PetscValidPointer(info,3); 2843 if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square"); 2844 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2845 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2846 if (!mat->ops->choleskyfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2847 MatCheckPreallocated(mat,1); 2848 2849 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 2850 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 2851 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 2852 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2853 PetscFunctionReturn(0); 2854 } 2855 2856 #undef __FUNCT__ 2857 #define __FUNCT__ "MatCholeskyFactorSymbolic" 2858 /*@C 2859 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 2860 of a symmetric matrix. 2861 2862 Collective on Mat 2863 2864 Input Parameters: 2865 + fact - the factor matrix obtained with MatGetFactor() 2866 . mat - the matrix 2867 . perm - row and column permutations 2868 - info - options for factorization, includes 2869 $ fill - expected fill as ratio of original fill. 2870 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2871 $ Run with the option -info to determine an optimal value to use 2872 2873 Notes: 2874 See MatLUFactorSymbolic() for the nonsymmetric case. See also 2875 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 2876 2877 Most users should employ the simplified KSP interface for linear solvers 2878 instead of working directly with matrix algebra routines such as this. 2879 See, e.g., KSPCreate(). 2880 2881 Level: developer 2882 2883 Concepts: matrices^Cholesky symbolic factorization 2884 2885 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 2886 MatGetOrdering() 2887 2888 Developer Note: fortran interface is not autogenerated as the f90 2889 interface defintion cannot be generated correctly [due to MatFactorInfo] 2890 2891 @*/ 2892 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 2893 { 2894 PetscErrorCode ierr; 2895 2896 PetscFunctionBegin; 2897 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2898 PetscValidType(mat,1); 2899 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 2900 if (info) PetscValidPointer(info,3); 2901 PetscValidPointer(fact,4); 2902 if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"Matrix must be square"); 2903 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2904 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2905 if (!(fact)->ops->choleskyfactorsymbolic) { 2906 const MatSolverPackage spackage; 2907 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 2908 SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 2909 } 2910 MatCheckPreallocated(mat,2); 2911 2912 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 2913 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 2914 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 2915 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 2916 PetscFunctionReturn(0); 2917 } 2918 2919 #undef __FUNCT__ 2920 #define __FUNCT__ "MatCholeskyFactorNumeric" 2921 /*@C 2922 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 2923 of a symmetric matrix. Call this routine after first calling 2924 MatCholeskyFactorSymbolic(). 2925 2926 Collective on Mat 2927 2928 Input Parameters: 2929 + fact - the factor matrix obtained with MatGetFactor() 2930 . mat - the initial matrix 2931 . info - options for factorization 2932 - fact - the symbolic factor of mat 2933 2934 2935 Notes: 2936 Most users should employ the simplified KSP interface for linear solvers 2937 instead of working directly with matrix algebra routines such as this. 2938 See, e.g., KSPCreate(). 2939 2940 Level: developer 2941 2942 Concepts: matrices^Cholesky numeric factorization 2943 2944 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 2945 2946 Developer Note: fortran interface is not autogenerated as the f90 2947 interface defintion cannot be generated correctly [due to MatFactorInfo] 2948 2949 @*/ 2950 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 2951 { 2952 PetscErrorCode ierr; 2953 2954 PetscFunctionBegin; 2955 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2956 PetscValidType(mat,1); 2957 PetscValidPointer(fact,2); 2958 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 2959 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2960 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 2961 if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) { 2962 SETERRQ4(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 2963 } 2964 MatCheckPreallocated(mat,2); 2965 2966 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 2967 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 2968 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 2969 2970 ierr = MatView_Private(fact);CHKERRQ(ierr); 2971 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 2972 PetscFunctionReturn(0); 2973 } 2974 2975 /* ----------------------------------------------------------------*/ 2976 #undef __FUNCT__ 2977 #define __FUNCT__ "MatSolve" 2978 /*@ 2979 MatSolve - Solves A x = b, given a factored matrix. 2980 2981 Neighbor-wise Collective on Mat and Vec 2982 2983 Input Parameters: 2984 + mat - the factored matrix 2985 - b - the right-hand-side vector 2986 2987 Output Parameter: 2988 . x - the result vector 2989 2990 Notes: 2991 The vectors b and x cannot be the same. I.e., one cannot 2992 call MatSolve(A,x,x). 2993 2994 Notes: 2995 Most users should employ the simplified KSP interface for linear solvers 2996 instead of working directly with matrix algebra routines such as this. 2997 See, e.g., KSPCreate(). 2998 2999 Level: developer 3000 3001 Concepts: matrices^triangular solves 3002 3003 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3004 @*/ 3005 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3006 { 3007 PetscErrorCode ierr; 3008 3009 PetscFunctionBegin; 3010 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3011 PetscValidType(mat,1); 3012 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3013 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3014 PetscCheckSameComm(mat,1,b,2); 3015 PetscCheckSameComm(mat,1,x,3); 3016 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3017 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3018 if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3019 if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3020 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3021 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3022 if (!mat->ops->solve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3023 MatCheckPreallocated(mat,1); 3024 3025 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3026 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3027 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3028 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3029 PetscFunctionReturn(0); 3030 } 3031 3032 #undef __FUNCT__ 3033 #define __FUNCT__ "MatMatSolve_Basic" 3034 PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X) 3035 { 3036 PetscErrorCode ierr; 3037 Vec b,x; 3038 PetscInt m,N,i; 3039 PetscScalar *bb,*xx; 3040 PetscBool flg; 3041 3042 PetscFunctionBegin; 3043 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr); 3044 if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3045 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr); 3046 if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3047 3048 ierr = MatGetArray(B,&bb);CHKERRQ(ierr); 3049 ierr = MatGetArray(X,&xx);CHKERRQ(ierr); 3050 ierr = MatGetLocalSize(B,&m,PETSC_NULL);CHKERRQ(ierr); /* number local rows */ 3051 ierr = MatGetSize(B,PETSC_NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3052 ierr = MatGetVecs(A,&x,&b);CHKERRQ(ierr); 3053 for (i=0; i<N; i++) { 3054 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3055 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3056 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3057 ierr = VecResetArray(x);CHKERRQ(ierr); 3058 ierr = VecResetArray(b);CHKERRQ(ierr); 3059 } 3060 ierr = VecDestroy(&b);CHKERRQ(ierr); 3061 ierr = VecDestroy(&x);CHKERRQ(ierr); 3062 ierr = MatRestoreArray(B,&bb);CHKERRQ(ierr); 3063 ierr = MatRestoreArray(X,&xx);CHKERRQ(ierr); 3064 PetscFunctionReturn(0); 3065 } 3066 3067 #undef __FUNCT__ 3068 #define __FUNCT__ "MatMatSolve" 3069 /*@ 3070 MatMatSolve - Solves A X = B, given a factored matrix. 3071 3072 Neighbor-wise Collective on Mat 3073 3074 Input Parameters: 3075 + mat - the factored matrix 3076 - B - the right-hand-side matrix (dense matrix) 3077 3078 Output Parameter: 3079 . X - the result matrix (dense matrix) 3080 3081 Notes: 3082 The matrices b and x cannot be the same. I.e., one cannot 3083 call MatMatSolve(A,x,x). 3084 3085 Notes: 3086 Most users should usually employ the simplified KSP interface for linear solvers 3087 instead of working directly with matrix algebra routines such as this. 3088 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3089 at a time. 3090 3091 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3092 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3093 3094 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3095 3096 Level: developer 3097 3098 Concepts: matrices^triangular solves 3099 3100 .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor() 3101 @*/ 3102 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3103 { 3104 PetscErrorCode ierr; 3105 3106 PetscFunctionBegin; 3107 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3108 PetscValidType(A,1); 3109 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3110 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3111 PetscCheckSameComm(A,1,B,2); 3112 PetscCheckSameComm(A,1,X,3); 3113 if (X == B) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3114 if (!A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3115 if (A->cmap->N != X->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N); 3116 if (A->rmap->N != B->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N); 3117 if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n); 3118 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3119 MatCheckPreallocated(A,1); 3120 3121 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3122 if (!A->ops->matsolve) { 3123 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);CHKERRQ(ierr); 3124 ierr = MatMatSolve_Basic(A,B,X);CHKERRQ(ierr); 3125 } else { 3126 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3127 } 3128 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3129 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3130 PetscFunctionReturn(0); 3131 } 3132 3133 3134 #undef __FUNCT__ 3135 #define __FUNCT__ "MatForwardSolve" 3136 /*@ 3137 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3138 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3139 3140 Neighbor-wise Collective on Mat and Vec 3141 3142 Input Parameters: 3143 + mat - the factored matrix 3144 - b - the right-hand-side vector 3145 3146 Output Parameter: 3147 . x - the result vector 3148 3149 Notes: 3150 MatSolve() should be used for most applications, as it performs 3151 a forward solve followed by a backward solve. 3152 3153 The vectors b and x cannot be the same, i.e., one cannot 3154 call MatForwardSolve(A,x,x). 3155 3156 For matrix in seqsbaij format with block size larger than 1, 3157 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3158 MatForwardSolve() solves U^T*D y = b, and 3159 MatBackwardSolve() solves U x = y. 3160 Thus they do not provide a symmetric preconditioner. 3161 3162 Most users should employ the simplified KSP interface for linear solvers 3163 instead of working directly with matrix algebra routines such as this. 3164 See, e.g., KSPCreate(). 3165 3166 Level: developer 3167 3168 Concepts: matrices^forward solves 3169 3170 .seealso: MatSolve(), MatBackwardSolve() 3171 @*/ 3172 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3173 { 3174 PetscErrorCode ierr; 3175 3176 PetscFunctionBegin; 3177 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3178 PetscValidType(mat,1); 3179 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3180 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3181 PetscCheckSameComm(mat,1,b,2); 3182 PetscCheckSameComm(mat,1,x,3); 3183 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3184 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3185 if (!mat->ops->forwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3186 if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3187 if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3188 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3189 MatCheckPreallocated(mat,1); 3190 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3191 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3192 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3193 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3194 PetscFunctionReturn(0); 3195 } 3196 3197 #undef __FUNCT__ 3198 #define __FUNCT__ "MatBackwardSolve" 3199 /*@ 3200 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3201 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3202 3203 Neighbor-wise Collective on Mat and Vec 3204 3205 Input Parameters: 3206 + mat - the factored matrix 3207 - b - the right-hand-side vector 3208 3209 Output Parameter: 3210 . x - the result vector 3211 3212 Notes: 3213 MatSolve() should be used for most applications, as it performs 3214 a forward solve followed by a backward solve. 3215 3216 The vectors b and x cannot be the same. I.e., one cannot 3217 call MatBackwardSolve(A,x,x). 3218 3219 For matrix in seqsbaij format with block size larger than 1, 3220 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3221 MatForwardSolve() solves U^T*D y = b, and 3222 MatBackwardSolve() solves U x = y. 3223 Thus they do not provide a symmetric preconditioner. 3224 3225 Most users should employ the simplified KSP interface for linear solvers 3226 instead of working directly with matrix algebra routines such as this. 3227 See, e.g., KSPCreate(). 3228 3229 Level: developer 3230 3231 Concepts: matrices^backward solves 3232 3233 .seealso: MatSolve(), MatForwardSolve() 3234 @*/ 3235 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3236 { 3237 PetscErrorCode ierr; 3238 3239 PetscFunctionBegin; 3240 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3241 PetscValidType(mat,1); 3242 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3243 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3244 PetscCheckSameComm(mat,1,b,2); 3245 PetscCheckSameComm(mat,1,x,3); 3246 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3247 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3248 if (!mat->ops->backwardsolve) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3249 if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3250 if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3251 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3252 MatCheckPreallocated(mat,1); 3253 3254 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3255 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3256 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3257 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3258 PetscFunctionReturn(0); 3259 } 3260 3261 #undef __FUNCT__ 3262 #define __FUNCT__ "MatSolveAdd" 3263 /*@ 3264 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3265 3266 Neighbor-wise Collective on Mat and Vec 3267 3268 Input Parameters: 3269 + mat - the factored matrix 3270 . b - the right-hand-side vector 3271 - y - the vector to be added to 3272 3273 Output Parameter: 3274 . x - the result vector 3275 3276 Notes: 3277 The vectors b and x cannot be the same. I.e., one cannot 3278 call MatSolveAdd(A,x,y,x). 3279 3280 Most users should employ the simplified KSP interface for linear solvers 3281 instead of working directly with matrix algebra routines such as this. 3282 See, e.g., KSPCreate(). 3283 3284 Level: developer 3285 3286 Concepts: matrices^triangular solves 3287 3288 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3289 @*/ 3290 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3291 { 3292 PetscScalar one = 1.0; 3293 Vec tmp; 3294 PetscErrorCode ierr; 3295 3296 PetscFunctionBegin; 3297 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3298 PetscValidType(mat,1); 3299 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3300 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3301 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3302 PetscCheckSameComm(mat,1,b,2); 3303 PetscCheckSameComm(mat,1,y,2); 3304 PetscCheckSameComm(mat,1,x,3); 3305 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3306 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3307 if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3308 if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3309 if (mat->rmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 3310 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3311 if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n); 3312 MatCheckPreallocated(mat,1); 3313 3314 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3315 if (mat->ops->solveadd) { 3316 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3317 } else { 3318 /* do the solve then the add manually */ 3319 if (x != y) { 3320 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3321 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3322 } else { 3323 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3324 ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr); 3325 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3326 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3327 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3328 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3329 } 3330 } 3331 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3332 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3333 PetscFunctionReturn(0); 3334 } 3335 3336 #undef __FUNCT__ 3337 #define __FUNCT__ "MatSolveTranspose" 3338 /*@ 3339 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3340 3341 Neighbor-wise Collective on Mat and Vec 3342 3343 Input Parameters: 3344 + mat - the factored matrix 3345 - b - the right-hand-side vector 3346 3347 Output Parameter: 3348 . x - the result vector 3349 3350 Notes: 3351 The vectors b and x cannot be the same. I.e., one cannot 3352 call MatSolveTranspose(A,x,x). 3353 3354 Most users should employ the simplified KSP interface for linear solvers 3355 instead of working directly with matrix algebra routines such as this. 3356 See, e.g., KSPCreate(). 3357 3358 Level: developer 3359 3360 Concepts: matrices^triangular solves 3361 3362 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3363 @*/ 3364 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3365 { 3366 PetscErrorCode ierr; 3367 3368 PetscFunctionBegin; 3369 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3370 PetscValidType(mat,1); 3371 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3372 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3373 PetscCheckSameComm(mat,1,b,2); 3374 PetscCheckSameComm(mat,1,x,3); 3375 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3376 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3377 if (!mat->ops->solvetranspose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3378 if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 3379 if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N); 3380 MatCheckPreallocated(mat,1); 3381 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3382 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3383 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3384 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3385 PetscFunctionReturn(0); 3386 } 3387 3388 #undef __FUNCT__ 3389 #define __FUNCT__ "MatSolveTransposeAdd" 3390 /*@ 3391 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3392 factored matrix. 3393 3394 Neighbor-wise Collective on Mat and Vec 3395 3396 Input Parameters: 3397 + mat - the factored matrix 3398 . b - the right-hand-side vector 3399 - y - the vector to be added to 3400 3401 Output Parameter: 3402 . x - the result vector 3403 3404 Notes: 3405 The vectors b and x cannot be the same. I.e., one cannot 3406 call MatSolveTransposeAdd(A,x,y,x). 3407 3408 Most users should employ the simplified KSP interface for linear solvers 3409 instead of working directly with matrix algebra routines such as this. 3410 See, e.g., KSPCreate(). 3411 3412 Level: developer 3413 3414 Concepts: matrices^triangular solves 3415 3416 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3417 @*/ 3418 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3419 { 3420 PetscScalar one = 1.0; 3421 PetscErrorCode ierr; 3422 Vec tmp; 3423 3424 PetscFunctionBegin; 3425 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3426 PetscValidType(mat,1); 3427 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3428 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3429 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3430 PetscCheckSameComm(mat,1,b,2); 3431 PetscCheckSameComm(mat,1,y,3); 3432 PetscCheckSameComm(mat,1,x,4); 3433 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3434 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3435 if (mat->rmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 3436 if (mat->cmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N); 3437 if (mat->cmap->N != y->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 3438 if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n); 3439 MatCheckPreallocated(mat,1); 3440 3441 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3442 if (mat->ops->solvetransposeadd) { 3443 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3444 } else { 3445 /* do the solve then the add manually */ 3446 if (x != y) { 3447 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3448 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3449 } else { 3450 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3451 ierr = PetscLogObjectParent(mat,tmp);CHKERRQ(ierr); 3452 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3453 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3454 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3455 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3456 } 3457 } 3458 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3459 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3460 PetscFunctionReturn(0); 3461 } 3462 /* ----------------------------------------------------------------*/ 3463 3464 #undef __FUNCT__ 3465 #define __FUNCT__ "MatSOR" 3466 /*@ 3467 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3468 3469 Neighbor-wise Collective on Mat and Vec 3470 3471 Input Parameters: 3472 + mat - the matrix 3473 . b - the right hand side 3474 . omega - the relaxation factor 3475 . flag - flag indicating the type of SOR (see below) 3476 . shift - diagonal shift 3477 . its - the number of iterations 3478 - lits - the number of local iterations 3479 3480 Output Parameters: 3481 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3482 3483 SOR Flags: 3484 . SOR_FORWARD_SWEEP - forward SOR 3485 . SOR_BACKWARD_SWEEP - backward SOR 3486 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3487 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3488 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3489 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3490 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3491 upper/lower triangular part of matrix to 3492 vector (with omega) 3493 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3494 3495 Notes: 3496 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3497 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3498 on each processor. 3499 3500 Application programmers will not generally use MatSOR() directly, 3501 but instead will employ the KSP/PC interface. 3502 3503 Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3504 3505 Notes for Advanced Users: 3506 The flags are implemented as bitwise inclusive or operations. 3507 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3508 to specify a zero initial guess for SSOR. 3509 3510 Most users should employ the simplified KSP interface for linear solvers 3511 instead of working directly with matrix algebra routines such as this. 3512 See, e.g., KSPCreate(). 3513 3514 Vectors x and b CANNOT be the same 3515 3516 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3517 3518 Level: developer 3519 3520 Concepts: matrices^relaxation 3521 Concepts: matrices^SOR 3522 Concepts: matrices^Gauss-Seidel 3523 3524 @*/ 3525 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3526 { 3527 PetscErrorCode ierr; 3528 3529 PetscFunctionBegin; 3530 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3531 PetscValidType(mat,1); 3532 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3533 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3534 PetscCheckSameComm(mat,1,b,2); 3535 PetscCheckSameComm(mat,1,x,8); 3536 if (!mat->ops->sor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3537 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3538 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3539 if (mat->cmap->N != x->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3540 if (mat->rmap->N != b->map->N) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3541 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3542 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3543 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3544 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3545 3546 MatCheckPreallocated(mat,1); 3547 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3548 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3549 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3550 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3551 PetscFunctionReturn(0); 3552 } 3553 3554 #undef __FUNCT__ 3555 #define __FUNCT__ "MatCopy_Basic" 3556 /* 3557 Default matrix copy routine. 3558 */ 3559 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3560 { 3561 PetscErrorCode ierr; 3562 PetscInt i,rstart = 0,rend = 0,nz; 3563 const PetscInt *cwork; 3564 const PetscScalar *vwork; 3565 3566 PetscFunctionBegin; 3567 if (B->assembled) { 3568 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3569 } 3570 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3571 for (i=rstart; i<rend; i++) { 3572 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3573 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3574 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3575 } 3576 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3577 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3578 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 3579 PetscFunctionReturn(0); 3580 } 3581 3582 #undef __FUNCT__ 3583 #define __FUNCT__ "MatCopy" 3584 /*@ 3585 MatCopy - Copys a matrix to another matrix. 3586 3587 Collective on Mat 3588 3589 Input Parameters: 3590 + A - the matrix 3591 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3592 3593 Output Parameter: 3594 . B - where the copy is put 3595 3596 Notes: 3597 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3598 same nonzero pattern or the routine will crash. 3599 3600 MatCopy() copies the matrix entries of a matrix to another existing 3601 matrix (after first zeroing the second matrix). A related routine is 3602 MatConvert(), which first creates a new matrix and then copies the data. 3603 3604 Level: intermediate 3605 3606 Concepts: matrices^copying 3607 3608 .seealso: MatConvert(), MatDuplicate() 3609 3610 @*/ 3611 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3612 { 3613 PetscErrorCode ierr; 3614 PetscInt i; 3615 3616 PetscFunctionBegin; 3617 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3618 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3619 PetscValidType(A,1); 3620 PetscValidType(B,2); 3621 PetscCheckSameComm(A,1,B,2); 3622 MatCheckPreallocated(B,2); 3623 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3624 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3625 if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 3626 MatCheckPreallocated(A,1); 3627 3628 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 3629 if (A->ops->copy) { 3630 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 3631 } else { /* generic conversion */ 3632 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3633 } 3634 3635 B->stencil.dim = A->stencil.dim; 3636 B->stencil.noc = A->stencil.noc; 3637 for (i=0; i<=A->stencil.dim; i++) { 3638 B->stencil.dims[i] = A->stencil.dims[i]; 3639 B->stencil.starts[i] = A->stencil.starts[i]; 3640 } 3641 3642 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 3643 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 3644 PetscFunctionReturn(0); 3645 } 3646 3647 #undef __FUNCT__ 3648 #define __FUNCT__ "MatConvert" 3649 /*@C 3650 MatConvert - Converts a matrix to another matrix, either of the same 3651 or different type. 3652 3653 Collective on Mat 3654 3655 Input Parameters: 3656 + mat - the matrix 3657 . newtype - new matrix type. Use MATSAME to create a new matrix of the 3658 same type as the original matrix. 3659 - reuse - denotes if the destination matrix is to be created or reused. Currently 3660 MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use 3661 MAT_INITIAL_MATRIX. 3662 3663 Output Parameter: 3664 . M - pointer to place new matrix 3665 3666 Notes: 3667 MatConvert() first creates a new matrix and then copies the data from 3668 the first matrix. A related routine is MatCopy(), which copies the matrix 3669 entries of one matrix to another already existing matrix context. 3670 3671 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 3672 the MPI communicator of the generated matrix is always the same as the communicator 3673 of the input matrix. 3674 3675 Level: intermediate 3676 3677 Concepts: matrices^converting between storage formats 3678 3679 .seealso: MatCopy(), MatDuplicate() 3680 @*/ 3681 PetscErrorCode MatConvert(Mat mat, const MatType newtype,MatReuse reuse,Mat *M) 3682 { 3683 PetscErrorCode ierr; 3684 PetscBool sametype,issame,flg; 3685 char convname[256],mtype[256]; 3686 Mat B; 3687 3688 PetscFunctionBegin; 3689 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3690 PetscValidType(mat,1); 3691 PetscValidPointer(M,3); 3692 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3693 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3694 MatCheckPreallocated(mat,1); 3695 ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3696 3697 ierr = PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 3698 if (flg) { 3699 newtype = mtype; 3700 } 3701 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 3702 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 3703 if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently"); 3704 3705 if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 3706 3707 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 3708 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 3709 } else { 3710 PetscErrorCode (*conv)(Mat, const MatType,MatReuse,Mat*)=PETSC_NULL; 3711 const char *prefix[3] = {"seq","mpi",""}; 3712 PetscInt i; 3713 /* 3714 Order of precedence: 3715 1) See if a specialized converter is known to the current matrix. 3716 2) See if a specialized converter is known to the desired matrix class. 3717 3) See if a good general converter is registered for the desired class 3718 (as of 6/27/03 only MATMPIADJ falls into this category). 3719 4) See if a good general converter is known for the current matrix. 3720 5) Use a really basic converter. 3721 */ 3722 3723 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 3724 for (i=0; i<3; i++) { 3725 ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr); 3726 ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr); 3727 ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 3728 ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr); 3729 ierr = PetscStrcat(convname,issame?((PetscObject)mat)->type_name:newtype);CHKERRQ(ierr); 3730 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 3731 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr); 3732 if (conv) goto foundconv; 3733 } 3734 3735 /* 2) See if a specialized converter is known to the desired matrix class. */ 3736 ierr = MatCreate(((PetscObject)mat)->comm,&B);CHKERRQ(ierr); 3737 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 3738 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 3739 for (i=0; i<3; i++) { 3740 ierr = PetscStrcpy(convname,"MatConvert_");CHKERRQ(ierr); 3741 ierr = PetscStrcat(convname,((PetscObject)mat)->type_name);CHKERRQ(ierr); 3742 ierr = PetscStrcat(convname,"_");CHKERRQ(ierr); 3743 ierr = PetscStrcat(convname,prefix[i]);CHKERRQ(ierr); 3744 ierr = PetscStrcat(convname,newtype);CHKERRQ(ierr); 3745 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 3746 ierr = PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);CHKERRQ(ierr); 3747 if (conv) { 3748 ierr = MatDestroy(&B);CHKERRQ(ierr); 3749 goto foundconv; 3750 } 3751 } 3752 3753 /* 3) See if a good general converter is registered for the desired class */ 3754 conv = B->ops->convertfrom; 3755 ierr = MatDestroy(&B);CHKERRQ(ierr); 3756 if (conv) goto foundconv; 3757 3758 /* 4) See if a good general converter is known for the current matrix */ 3759 if (mat->ops->convert) { 3760 conv = mat->ops->convert; 3761 } 3762 if (conv) goto foundconv; 3763 3764 /* 5) Use a really basic converter. */ 3765 conv = MatConvert_Basic; 3766 3767 foundconv: 3768 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 3769 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 3770 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 3771 } 3772 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 3773 3774 /* Copy Mat options */ 3775 if (mat->symmetric){ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 3776 if (mat->hermitian){ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 3777 PetscFunctionReturn(0); 3778 } 3779 3780 #undef __FUNCT__ 3781 #define __FUNCT__ "MatFactorGetSolverPackage" 3782 /*@C 3783 MatFactorGetSolverPackage - Returns name of the package providing the factorization routines 3784 3785 Not Collective 3786 3787 Input Parameter: 3788 . mat - the matrix, must be a factored matrix 3789 3790 Output Parameter: 3791 . type - the string name of the package (do not free this string) 3792 3793 Notes: 3794 In Fortran you pass in a empty string and the package name will be copied into it. 3795 (Make sure the string is long enough) 3796 3797 Level: intermediate 3798 3799 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 3800 @*/ 3801 PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type) 3802 { 3803 PetscErrorCode ierr; 3804 PetscErrorCode (*conv)(Mat,const MatSolverPackage*); 3805 3806 PetscFunctionBegin; 3807 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3808 PetscValidType(mat,1); 3809 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 3810 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",(void (**)(void))&conv);CHKERRQ(ierr); 3811 if (!conv) { 3812 *type = MATSOLVERPETSC; 3813 } else { 3814 ierr = (*conv)(mat,type);CHKERRQ(ierr); 3815 } 3816 PetscFunctionReturn(0); 3817 } 3818 3819 #undef __FUNCT__ 3820 #define __FUNCT__ "MatGetFactor" 3821 /*@C 3822 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 3823 3824 Collective on Mat 3825 3826 Input Parameters: 3827 + mat - the matrix 3828 . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default) 3829 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 3830 3831 Output Parameters: 3832 . f - the factor matrix used with MatXXFactorSymbolic() calls 3833 3834 Notes: 3835 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 3836 such as pastix, superlu, mumps, spooles etc. 3837 3838 PETSc must have been ./configure to use the external solver, using the option --download-package 3839 3840 Level: intermediate 3841 3842 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 3843 @*/ 3844 PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f) 3845 { 3846 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 3847 char convname[256]; 3848 3849 PetscFunctionBegin; 3850 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3851 PetscValidType(mat,1); 3852 3853 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3854 MatCheckPreallocated(mat,1); 3855 3856 ierr = PetscStrcpy(convname,"MatGetFactor_");CHKERRQ(ierr); 3857 ierr = PetscStrcat(convname,type);CHKERRQ(ierr); 3858 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 3859 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr); 3860 if (!conv) { 3861 PetscBool flag; 3862 MPI_Comm comm; 3863 3864 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3865 ierr = PetscStrcasecmp(MATSOLVERPETSC,type,&flag);CHKERRQ(ierr); 3866 if (flag) { 3867 SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]); 3868 } else { 3869 SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type); 3870 } 3871 } 3872 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 3873 PetscFunctionReturn(0); 3874 } 3875 3876 #undef __FUNCT__ 3877 #define __FUNCT__ "MatGetFactorAvailable" 3878 /*@C 3879 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 3880 3881 Not Collective 3882 3883 Input Parameters: 3884 + mat - the matrix 3885 . type - name of solver type, for example, spooles, superlu, plapack, petsc (to use PETSc's default) 3886 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 3887 3888 Output Parameter: 3889 . flg - PETSC_TRUE if the factorization is available 3890 3891 Notes: 3892 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 3893 such as pastix, superlu, mumps, spooles etc. 3894 3895 PETSc must have been ./configure to use the external solver, using the option --download-package 3896 3897 Level: intermediate 3898 3899 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 3900 @*/ 3901 PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg) 3902 { 3903 PetscErrorCode ierr; 3904 char convname[256]; 3905 PetscErrorCode (*conv)(Mat,MatFactorType,PetscBool *); 3906 3907 PetscFunctionBegin; 3908 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3909 PetscValidType(mat,1); 3910 3911 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3912 MatCheckPreallocated(mat,1); 3913 3914 ierr = PetscStrcpy(convname,"MatGetFactorAvailable_");CHKERRQ(ierr); 3915 ierr = PetscStrcat(convname,type);CHKERRQ(ierr); 3916 ierr = PetscStrcat(convname,"_C");CHKERRQ(ierr); 3917 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,(void (**)(void))&conv);CHKERRQ(ierr); 3918 if (!conv) { 3919 *flg = PETSC_FALSE; 3920 } else { 3921 ierr = (*conv)(mat,ftype,flg);CHKERRQ(ierr); 3922 } 3923 PetscFunctionReturn(0); 3924 } 3925 3926 3927 #undef __FUNCT__ 3928 #define __FUNCT__ "MatDuplicate" 3929 /*@ 3930 MatDuplicate - Duplicates a matrix including the non-zero structure. 3931 3932 Collective on Mat 3933 3934 Input Parameters: 3935 + mat - the matrix 3936 - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix 3937 MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them. 3938 3939 Output Parameter: 3940 . M - pointer to place new matrix 3941 3942 Level: intermediate 3943 3944 Concepts: matrices^duplicating 3945 3946 Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 3947 3948 .seealso: MatCopy(), MatConvert() 3949 @*/ 3950 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 3951 { 3952 PetscErrorCode ierr; 3953 Mat B; 3954 PetscInt i; 3955 3956 PetscFunctionBegin; 3957 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3958 PetscValidType(mat,1); 3959 PetscValidPointer(M,3); 3960 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3961 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3962 MatCheckPreallocated(mat,1); 3963 3964 *M = 0; 3965 if (!mat->ops->duplicate) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not written for this matrix type"); 3966 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 3967 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 3968 B = *M; 3969 3970 B->stencil.dim = mat->stencil.dim; 3971 B->stencil.noc = mat->stencil.noc; 3972 for (i=0; i<=mat->stencil.dim; i++) { 3973 B->stencil.dims[i] = mat->stencil.dims[i]; 3974 B->stencil.starts[i] = mat->stencil.starts[i]; 3975 } 3976 3977 B->nooffproczerorows = mat->nooffproczerorows; 3978 B->nooffprocentries = mat->nooffprocentries; 3979 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 3980 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 3981 PetscFunctionReturn(0); 3982 } 3983 3984 #undef __FUNCT__ 3985 #define __FUNCT__ "MatGetDiagonal" 3986 /*@ 3987 MatGetDiagonal - Gets the diagonal of a matrix. 3988 3989 Logically Collective on Mat and Vec 3990 3991 Input Parameters: 3992 + mat - the matrix 3993 - v - the vector for storing the diagonal 3994 3995 Output Parameter: 3996 . v - the diagonal of the matrix 3997 3998 Level: intermediate 3999 4000 Note: 4001 Currently only correct in parallel for square matrices. 4002 4003 Concepts: matrices^accessing diagonals 4004 4005 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs() 4006 @*/ 4007 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4008 { 4009 PetscErrorCode ierr; 4010 4011 PetscFunctionBegin; 4012 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4013 PetscValidType(mat,1); 4014 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4015 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4016 if (!mat->ops->getdiagonal) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4017 MatCheckPreallocated(mat,1); 4018 4019 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4020 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4021 PetscFunctionReturn(0); 4022 } 4023 4024 #undef __FUNCT__ 4025 #define __FUNCT__ "MatGetRowMin" 4026 /*@ 4027 MatGetRowMin - Gets the minimum value (of the real part) of each 4028 row of the matrix 4029 4030 Logically Collective on Mat and Vec 4031 4032 Input Parameters: 4033 . mat - the matrix 4034 4035 Output Parameter: 4036 + v - the vector for storing the maximums 4037 - idx - the indices of the column found for each row (optional) 4038 4039 Level: intermediate 4040 4041 Notes: The result of this call are the same as if one converted the matrix to dense format 4042 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4043 4044 This code is only implemented for a couple of matrix formats. 4045 4046 Concepts: matrices^getting row maximums 4047 4048 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), 4049 MatGetRowMax() 4050 @*/ 4051 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4052 { 4053 PetscErrorCode ierr; 4054 4055 PetscFunctionBegin; 4056 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4057 PetscValidType(mat,1); 4058 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4059 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4060 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4061 MatCheckPreallocated(mat,1); 4062 4063 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4064 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4065 PetscFunctionReturn(0); 4066 } 4067 4068 #undef __FUNCT__ 4069 #define __FUNCT__ "MatGetRowMinAbs" 4070 /*@ 4071 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4072 row of the matrix 4073 4074 Logically Collective on Mat and Vec 4075 4076 Input Parameters: 4077 . mat - the matrix 4078 4079 Output Parameter: 4080 + v - the vector for storing the minimums 4081 - idx - the indices of the column found for each row (or PETSC_NULL if not needed) 4082 4083 Level: intermediate 4084 4085 Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that 4086 row is 0 (the first column). 4087 4088 This code is only implemented for a couple of matrix formats. 4089 4090 Concepts: matrices^getting row maximums 4091 4092 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4093 @*/ 4094 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4095 { 4096 PetscErrorCode ierr; 4097 4098 PetscFunctionBegin; 4099 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4100 PetscValidType(mat,1); 4101 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4102 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4103 if (!mat->ops->getrowminabs) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4104 MatCheckPreallocated(mat,1); 4105 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4106 4107 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4108 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4109 PetscFunctionReturn(0); 4110 } 4111 4112 #undef __FUNCT__ 4113 #define __FUNCT__ "MatGetRowMax" 4114 /*@ 4115 MatGetRowMax - Gets the maximum value (of the real part) of each 4116 row of the matrix 4117 4118 Logically Collective on Mat and Vec 4119 4120 Input Parameters: 4121 . mat - the matrix 4122 4123 Output Parameter: 4124 + v - the vector for storing the maximums 4125 - idx - the indices of the column found for each row (optional) 4126 4127 Level: intermediate 4128 4129 Notes: The result of this call are the same as if one converted the matrix to dense format 4130 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4131 4132 This code is only implemented for a couple of matrix formats. 4133 4134 Concepts: matrices^getting row maximums 4135 4136 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4137 @*/ 4138 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4139 { 4140 PetscErrorCode ierr; 4141 4142 PetscFunctionBegin; 4143 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4144 PetscValidType(mat,1); 4145 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4146 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4147 if (!mat->ops->getrowmax) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4148 MatCheckPreallocated(mat,1); 4149 4150 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4151 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4152 PetscFunctionReturn(0); 4153 } 4154 4155 #undef __FUNCT__ 4156 #define __FUNCT__ "MatGetRowMaxAbs" 4157 /*@ 4158 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4159 row of the matrix 4160 4161 Logically Collective on Mat and Vec 4162 4163 Input Parameters: 4164 . mat - the matrix 4165 4166 Output Parameter: 4167 + v - the vector for storing the maximums 4168 - idx - the indices of the column found for each row (or PETSC_NULL if not needed) 4169 4170 Level: intermediate 4171 4172 Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that 4173 row is 0 (the first column). 4174 4175 This code is only implemented for a couple of matrix formats. 4176 4177 Concepts: matrices^getting row maximums 4178 4179 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin() 4180 @*/ 4181 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4182 { 4183 PetscErrorCode ierr; 4184 4185 PetscFunctionBegin; 4186 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4187 PetscValidType(mat,1); 4188 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4189 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4190 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4191 MatCheckPreallocated(mat,1); 4192 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4193 4194 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4195 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4196 PetscFunctionReturn(0); 4197 } 4198 4199 #undef __FUNCT__ 4200 #define __FUNCT__ "MatGetRowSum" 4201 /*@ 4202 MatGetRowSum - Gets the sum of each row of the matrix 4203 4204 Logically Collective on Mat and Vec 4205 4206 Input Parameters: 4207 . mat - the matrix 4208 4209 Output Parameter: 4210 . v - the vector for storing the sum of rows 4211 4212 Level: intermediate 4213 4214 Notes: This code is slow since it is not currently specialized for different formats 4215 4216 Concepts: matrices^getting row sums 4217 4218 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin() 4219 @*/ 4220 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4221 { 4222 PetscInt start = 0, end = 0, row; 4223 PetscScalar *array; 4224 PetscErrorCode ierr; 4225 4226 PetscFunctionBegin; 4227 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4228 PetscValidType(mat,1); 4229 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4230 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4231 MatCheckPreallocated(mat,1); 4232 ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr); 4233 ierr = VecGetArray(v, &array);CHKERRQ(ierr); 4234 for(row = start; row < end; ++row) { 4235 PetscInt ncols, col; 4236 const PetscInt *cols; 4237 const PetscScalar *vals; 4238 4239 array[row - start] = 0.0; 4240 ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr); 4241 for(col = 0; col < ncols; col++) { 4242 array[row - start] += vals[col]; 4243 } 4244 ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr); 4245 } 4246 ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4247 ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr); 4248 PetscFunctionReturn(0); 4249 } 4250 4251 #undef __FUNCT__ 4252 #define __FUNCT__ "MatTranspose" 4253 /*@ 4254 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4255 4256 Collective on Mat 4257 4258 Input Parameter: 4259 + mat - the matrix to transpose 4260 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 4261 4262 Output Parameters: 4263 . B - the transpose 4264 4265 Notes: 4266 If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat); 4267 4268 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4269 4270 Level: intermediate 4271 4272 Concepts: matrices^transposing 4273 4274 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4275 @*/ 4276 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4277 { 4278 PetscErrorCode ierr; 4279 4280 PetscFunctionBegin; 4281 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4282 PetscValidType(mat,1); 4283 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4284 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4285 if (!mat->ops->transpose) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4286 MatCheckPreallocated(mat,1); 4287 4288 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4289 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4290 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4291 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4292 PetscFunctionReturn(0); 4293 } 4294 4295 #undef __FUNCT__ 4296 #define __FUNCT__ "MatIsTranspose" 4297 /*@ 4298 MatIsTranspose - Test whether a matrix is another one's transpose, 4299 or its own, in which case it tests symmetry. 4300 4301 Collective on Mat 4302 4303 Input Parameter: 4304 + A - the matrix to test 4305 - B - the matrix to test against, this can equal the first parameter 4306 4307 Output Parameters: 4308 . flg - the result 4309 4310 Notes: 4311 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4312 has a running time of the order of the number of nonzeros; the parallel 4313 test involves parallel copies of the block-offdiagonal parts of the matrix. 4314 4315 Level: intermediate 4316 4317 Concepts: matrices^transposing, matrix^symmetry 4318 4319 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4320 @*/ 4321 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4322 { 4323 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *); 4324 4325 PetscFunctionBegin; 4326 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4327 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4328 PetscValidPointer(flg,3); 4329 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",(void (**)(void))&f);CHKERRQ(ierr); 4330 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",(void (**)(void))&g);CHKERRQ(ierr); 4331 *flg = PETSC_FALSE; 4332 if (f && g) { 4333 if (f == g) { 4334 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4335 } else { 4336 SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4337 } 4338 } else { 4339 const MatType mattype; 4340 if (!f) {ierr = MatGetType(A,&mattype);CHKERRQ(ierr);} 4341 else {ierr = MatGetType(B,&mattype);CHKERRQ(ierr);} 4342 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4343 } 4344 PetscFunctionReturn(0); 4345 } 4346 4347 #undef __FUNCT__ 4348 #define __FUNCT__ "MatHermitianTranspose" 4349 /*@ 4350 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4351 4352 Collective on Mat 4353 4354 Input Parameter: 4355 + mat - the matrix to transpose and complex conjugate 4356 - reuse - store the transpose matrix in the provided B 4357 4358 Output Parameters: 4359 . B - the Hermitian 4360 4361 Notes: 4362 If you pass in &mat for B the Hermitian will be done in place 4363 4364 Level: intermediate 4365 4366 Concepts: matrices^transposing, complex conjugatex 4367 4368 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4369 @*/ 4370 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4371 { 4372 PetscErrorCode ierr; 4373 4374 PetscFunctionBegin; 4375 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4376 #if defined(PETSC_USE_COMPLEX) 4377 ierr = MatConjugate(*B);CHKERRQ(ierr); 4378 #endif 4379 PetscFunctionReturn(0); 4380 } 4381 4382 #undef __FUNCT__ 4383 #define __FUNCT__ "MatIsHermitianTranspose" 4384 /*@ 4385 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4386 4387 Collective on Mat 4388 4389 Input Parameter: 4390 + A - the matrix to test 4391 - B - the matrix to test against, this can equal the first parameter 4392 4393 Output Parameters: 4394 . flg - the result 4395 4396 Notes: 4397 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4398 has a running time of the order of the number of nonzeros; the parallel 4399 test involves parallel copies of the block-offdiagonal parts of the matrix. 4400 4401 Level: intermediate 4402 4403 Concepts: matrices^transposing, matrix^symmetry 4404 4405 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4406 @*/ 4407 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4408 { 4409 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool *),(*g)(Mat,Mat,PetscReal,PetscBool *); 4410 4411 PetscFunctionBegin; 4412 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4413 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4414 PetscValidPointer(flg,3); 4415 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",(void (**)(void))&f);CHKERRQ(ierr); 4416 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",(void (**)(void))&g);CHKERRQ(ierr); 4417 if (f && g) { 4418 if (f==g) { 4419 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4420 } else { 4421 SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4422 } 4423 } 4424 PetscFunctionReturn(0); 4425 } 4426 4427 #undef __FUNCT__ 4428 #define __FUNCT__ "MatPermute" 4429 /*@ 4430 MatPermute - Creates a new matrix with rows and columns permuted from the 4431 original. 4432 4433 Collective on Mat 4434 4435 Input Parameters: 4436 + mat - the matrix to permute 4437 . row - row permutation, each processor supplies only the permutation for its rows 4438 - col - column permutation, each processor needs the entire column permutation, that is 4439 this is the same size as the total number of columns in the matrix. It can often 4440 be obtained with ISAllGather() on the row permutation 4441 4442 Output Parameters: 4443 . B - the permuted matrix 4444 4445 Level: advanced 4446 4447 Concepts: matrices^permuting 4448 4449 .seealso: MatGetOrdering(), ISAllGather() 4450 4451 @*/ 4452 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4453 { 4454 PetscErrorCode ierr; 4455 4456 PetscFunctionBegin; 4457 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4458 PetscValidType(mat,1); 4459 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4460 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4461 PetscValidPointer(B,4); 4462 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4463 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4464 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4465 MatCheckPreallocated(mat,1); 4466 4467 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 4468 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 4469 PetscFunctionReturn(0); 4470 } 4471 4472 #undef __FUNCT__ 4473 #define __FUNCT__ "MatEqual" 4474 /*@ 4475 MatEqual - Compares two matrices. 4476 4477 Collective on Mat 4478 4479 Input Parameters: 4480 + A - the first matrix 4481 - B - the second matrix 4482 4483 Output Parameter: 4484 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 4485 4486 Level: intermediate 4487 4488 Concepts: matrices^equality between 4489 @*/ 4490 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 4491 { 4492 PetscErrorCode ierr; 4493 4494 PetscFunctionBegin; 4495 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4496 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4497 PetscValidType(A,1); 4498 PetscValidType(B,2); 4499 PetscValidIntPointer(flg,3); 4500 PetscCheckSameComm(A,1,B,2); 4501 MatCheckPreallocated(B,2); 4502 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4503 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4504 if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 4505 if (!A->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 4506 if (!B->ops->equal) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 4507 if (A->ops->equal != B->ops->equal) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 4508 MatCheckPreallocated(A,1); 4509 4510 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 4511 PetscFunctionReturn(0); 4512 } 4513 4514 #undef __FUNCT__ 4515 #define __FUNCT__ "MatDiagonalScale" 4516 /*@ 4517 MatDiagonalScale - Scales a matrix on the left and right by diagonal 4518 matrices that are stored as vectors. Either of the two scaling 4519 matrices can be PETSC_NULL. 4520 4521 Collective on Mat 4522 4523 Input Parameters: 4524 + mat - the matrix to be scaled 4525 . l - the left scaling vector (or PETSC_NULL) 4526 - r - the right scaling vector (or PETSC_NULL) 4527 4528 Notes: 4529 MatDiagonalScale() computes A = LAR, where 4530 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 4531 The L scales the rows of the matrix, the R scales the columns of the matrix. 4532 4533 Level: intermediate 4534 4535 Concepts: matrices^diagonal scaling 4536 Concepts: diagonal scaling of matrices 4537 4538 .seealso: MatScale() 4539 @*/ 4540 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 4541 { 4542 PetscErrorCode ierr; 4543 4544 PetscFunctionBegin; 4545 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4546 PetscValidType(mat,1); 4547 if (!mat->ops->diagonalscale) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4548 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 4549 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 4550 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4551 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4552 MatCheckPreallocated(mat,1); 4553 4554 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4555 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 4556 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4557 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 4558 #if defined(PETSC_HAVE_CUSP) 4559 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 4560 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 4561 } 4562 #endif 4563 PetscFunctionReturn(0); 4564 } 4565 4566 #undef __FUNCT__ 4567 #define __FUNCT__ "MatScale" 4568 /*@ 4569 MatScale - Scales all elements of a matrix by a given number. 4570 4571 Logically Collective on Mat 4572 4573 Input Parameters: 4574 + mat - the matrix to be scaled 4575 - a - the scaling value 4576 4577 Output Parameter: 4578 . mat - the scaled matrix 4579 4580 Level: intermediate 4581 4582 Concepts: matrices^scaling all entries 4583 4584 .seealso: MatDiagonalScale() 4585 @*/ 4586 PetscErrorCode MatScale(Mat mat,PetscScalar a) 4587 { 4588 PetscErrorCode ierr; 4589 4590 PetscFunctionBegin; 4591 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4592 PetscValidType(mat,1); 4593 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4594 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4595 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4596 PetscValidLogicalCollectiveScalar(mat,a,2); 4597 MatCheckPreallocated(mat,1); 4598 4599 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4600 if (a != (PetscScalar)1.0) { 4601 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 4602 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 4603 } 4604 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4605 #if defined(PETSC_HAVE_CUSP) 4606 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 4607 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 4608 } 4609 #endif 4610 PetscFunctionReturn(0); 4611 } 4612 4613 #undef __FUNCT__ 4614 #define __FUNCT__ "MatNorm" 4615 /*@ 4616 MatNorm - Calculates various norms of a matrix. 4617 4618 Collective on Mat 4619 4620 Input Parameters: 4621 + mat - the matrix 4622 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 4623 4624 Output Parameters: 4625 . nrm - the resulting norm 4626 4627 Level: intermediate 4628 4629 Concepts: matrices^norm 4630 Concepts: norm^of matrix 4631 @*/ 4632 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 4633 { 4634 PetscErrorCode ierr; 4635 4636 PetscFunctionBegin; 4637 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4638 PetscValidType(mat,1); 4639 PetscValidScalarPointer(nrm,3); 4640 4641 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4642 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4643 if (!mat->ops->norm) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4644 MatCheckPreallocated(mat,1); 4645 4646 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 4647 PetscFunctionReturn(0); 4648 } 4649 4650 /* 4651 This variable is used to prevent counting of MatAssemblyBegin() that 4652 are called from within a MatAssemblyEnd(). 4653 */ 4654 static PetscInt MatAssemblyEnd_InUse = 0; 4655 #undef __FUNCT__ 4656 #define __FUNCT__ "MatAssemblyBegin" 4657 /*@ 4658 MatAssemblyBegin - Begins assembling the matrix. This routine should 4659 be called after completing all calls to MatSetValues(). 4660 4661 Collective on Mat 4662 4663 Input Parameters: 4664 + mat - the matrix 4665 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 4666 4667 Notes: 4668 MatSetValues() generally caches the values. The matrix is ready to 4669 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 4670 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 4671 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 4672 using the matrix. 4673 4674 Level: beginner 4675 4676 Concepts: matrices^assembling 4677 4678 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 4679 @*/ 4680 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 4681 { 4682 PetscErrorCode ierr; 4683 4684 PetscFunctionBegin; 4685 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4686 PetscValidType(mat,1); 4687 MatCheckPreallocated(mat,1); 4688 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 4689 if (mat->assembled) { 4690 mat->was_assembled = PETSC_TRUE; 4691 mat->assembled = PETSC_FALSE; 4692 } 4693 if (!MatAssemblyEnd_InUse) { 4694 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 4695 if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 4696 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 4697 } else { 4698 if (mat->ops->assemblybegin){ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 4699 } 4700 PetscFunctionReturn(0); 4701 } 4702 4703 #undef __FUNCT__ 4704 #define __FUNCT__ "MatAssembled" 4705 /*@ 4706 MatAssembled - Indicates if a matrix has been assembled and is ready for 4707 use; for example, in matrix-vector product. 4708 4709 Not Collective 4710 4711 Input Parameter: 4712 . mat - the matrix 4713 4714 Output Parameter: 4715 . assembled - PETSC_TRUE or PETSC_FALSE 4716 4717 Level: advanced 4718 4719 Concepts: matrices^assembled? 4720 4721 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 4722 @*/ 4723 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 4724 { 4725 PetscFunctionBegin; 4726 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4727 PetscValidType(mat,1); 4728 PetscValidPointer(assembled,2); 4729 *assembled = mat->assembled; 4730 PetscFunctionReturn(0); 4731 } 4732 4733 #undef __FUNCT__ 4734 #define __FUNCT__ "MatView_Private" 4735 /* 4736 Processes command line options to determine if/how a matrix 4737 is to be viewed. Called by MatAssemblyEnd() and MatLoad(). 4738 */ 4739 PetscErrorCode MatView_Private(Mat mat) 4740 { 4741 PetscErrorCode ierr; 4742 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flg4 = PETSC_FALSE,flg6 = PETSC_FALSE,flg7 = PETSC_FALSE,flg8 = PETSC_FALSE; 4743 static PetscBool incall = PETSC_FALSE; 4744 #if defined(PETSC_USE_SOCKET_VIEWER) 4745 PetscBool flg5 = PETSC_FALSE; 4746 #endif 4747 4748 PetscFunctionBegin; 4749 if (incall) PetscFunctionReturn(0); 4750 incall = PETSC_TRUE; 4751 ierr = PetscObjectOptionsBegin((PetscObject)mat);CHKERRQ(ierr); 4752 ierr = PetscOptionsBool("-mat_view_info","Information on matrix size","MatView",flg1,&flg1,PETSC_NULL);CHKERRQ(ierr); 4753 ierr = PetscOptionsBool("-mat_view_info_detailed","Nonzeros in the matrix","MatView",flg2,&flg2,PETSC_NULL);CHKERRQ(ierr); 4754 ierr = PetscOptionsBool("-mat_view","Print matrix to stdout","MatView",flg3,&flg3,PETSC_NULL);CHKERRQ(ierr); 4755 ierr = PetscOptionsBool("-mat_view_matlab","Print matrix to stdout in a format Matlab can read","MatView",flg4,&flg4,PETSC_NULL);CHKERRQ(ierr); 4756 #if defined(PETSC_USE_SOCKET_VIEWER) 4757 ierr = PetscOptionsBool("-mat_view_socket","Send matrix to socket (can be read from matlab)","MatView",flg5,&flg5,PETSC_NULL);CHKERRQ(ierr); 4758 #endif 4759 ierr = PetscOptionsBool("-mat_view_binary","Save matrix to file in binary format","MatView",flg6,&flg6,PETSC_NULL);CHKERRQ(ierr); 4760 ierr = PetscOptionsBool("-mat_view_draw","Draw the matrix nonzero structure","MatView",flg7,&flg7,PETSC_NULL);CHKERRQ(ierr); 4761 ierr = PetscOptionsEnd();CHKERRQ(ierr); 4762 4763 if (flg1) { 4764 PetscViewer viewer; 4765 4766 ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr); 4767 ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); 4768 ierr = MatView(mat,viewer);CHKERRQ(ierr); 4769 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4770 } 4771 if (flg2) { 4772 PetscViewer viewer; 4773 4774 ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr); 4775 ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); 4776 ierr = MatView(mat,viewer);CHKERRQ(ierr); 4777 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4778 } 4779 if (flg3) { 4780 PetscViewer viewer; 4781 4782 ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr); 4783 ierr = MatView(mat,viewer);CHKERRQ(ierr); 4784 } 4785 if (flg4) { 4786 PetscViewer viewer; 4787 4788 ierr = PetscViewerASCIIGetStdout(((PetscObject)mat)->comm,&viewer);CHKERRQ(ierr); 4789 ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4790 ierr = MatView(mat,viewer);CHKERRQ(ierr); 4791 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4792 } 4793 #if defined(PETSC_USE_SOCKET_VIEWER) 4794 if (flg5) { 4795 ierr = MatView(mat,PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr); 4796 ierr = PetscViewerFlush(PETSC_VIEWER_SOCKET_(((PetscObject)mat)->comm));CHKERRQ(ierr); 4797 } 4798 #endif 4799 if (flg6) { 4800 ierr = MatView(mat,PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr); 4801 ierr = PetscViewerFlush(PETSC_VIEWER_BINARY_(((PetscObject)mat)->comm));CHKERRQ(ierr); 4802 } 4803 if (flg7) { 4804 ierr = PetscOptionsGetBool(((PetscObject)mat)->prefix,"-mat_view_contour",&flg8,PETSC_NULL);CHKERRQ(ierr); 4805 if (flg8) { 4806 PetscViewerPushFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm),PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 4807 } 4808 ierr = MatView(mat,PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr); 4809 ierr = PetscViewerFlush(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr); 4810 if (flg8) { 4811 PetscViewerPopFormat(PETSC_VIEWER_DRAW_(((PetscObject)mat)->comm));CHKERRQ(ierr); 4812 } 4813 } 4814 incall = PETSC_FALSE; 4815 PetscFunctionReturn(0); 4816 } 4817 4818 #undef __FUNCT__ 4819 #define __FUNCT__ "MatAssemblyEnd" 4820 /*@ 4821 MatAssemblyEnd - Completes assembling the matrix. This routine should 4822 be called after MatAssemblyBegin(). 4823 4824 Collective on Mat 4825 4826 Input Parameters: 4827 + mat - the matrix 4828 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 4829 4830 Options Database Keys: 4831 + -mat_view_info - Prints info on matrix at conclusion of MatEndAssembly() 4832 . -mat_view_info_detailed - Prints more detailed info 4833 . -mat_view - Prints matrix in ASCII format 4834 . -mat_view_matlab - Prints matrix in Matlab format 4835 . -mat_view_draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 4836 . -display <name> - Sets display name (default is host) 4837 . -draw_pause <sec> - Sets number of seconds to pause after display 4838 . -mat_view_socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>) 4839 . -viewer_socket_machine <machine> 4840 . -viewer_socket_port <port> 4841 . -mat_view_binary - save matrix to file in binary format 4842 - -viewer_binary_filename <name> 4843 4844 Notes: 4845 MatSetValues() generally caches the values. The matrix is ready to 4846 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 4847 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 4848 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 4849 using the matrix. 4850 4851 Level: beginner 4852 4853 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), MatView(), MatAssembled(), PetscViewerSocketOpen() 4854 @*/ 4855 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 4856 { 4857 PetscErrorCode ierr; 4858 static PetscInt inassm = 0; 4859 PetscBool flg = PETSC_FALSE; 4860 4861 PetscFunctionBegin; 4862 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4863 PetscValidType(mat,1); 4864 4865 inassm++; 4866 MatAssemblyEnd_InUse++; 4867 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 4868 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 4869 if (mat->ops->assemblyend) { 4870 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 4871 } 4872 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 4873 } else { 4874 if (mat->ops->assemblyend) { 4875 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 4876 } 4877 } 4878 4879 /* Flush assembly is not a true assembly */ 4880 if (type != MAT_FLUSH_ASSEMBLY) { 4881 mat->assembled = PETSC_TRUE; mat->num_ass++; 4882 } 4883 mat->insertmode = NOT_SET_VALUES; 4884 MatAssemblyEnd_InUse--; 4885 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 4886 if (!mat->symmetric_eternal) { 4887 mat->symmetric_set = PETSC_FALSE; 4888 mat->hermitian_set = PETSC_FALSE; 4889 mat->structurally_symmetric_set = PETSC_FALSE; 4890 } 4891 #if defined(PETSC_HAVE_CUSP) 4892 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 4893 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 4894 } 4895 #endif 4896 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 4897 ierr = MatView_Private(mat);CHKERRQ(ierr); 4898 ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr); 4899 if (flg) { 4900 PetscReal tol = 0.0; 4901 ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr); 4902 ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr); 4903 if (flg) { 4904 ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr); 4905 } else { 4906 ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr); 4907 } 4908 } 4909 } 4910 inassm--; 4911 PetscFunctionReturn(0); 4912 } 4913 4914 #undef __FUNCT__ 4915 #define __FUNCT__ "MatSetOption" 4916 /*@ 4917 MatSetOption - Sets a parameter option for a matrix. Some options 4918 may be specific to certain storage formats. Some options 4919 determine how values will be inserted (or added). Sorted, 4920 row-oriented input will generally assemble the fastest. The default 4921 is row-oriented. 4922 4923 Logically Collective on Mat 4924 4925 Input Parameters: 4926 + mat - the matrix 4927 . option - the option, one of those listed below (and possibly others), 4928 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 4929 4930 Options Describing Matrix Structure: 4931 + MAT_SPD - symmetric positive definite 4932 - MAT_SYMMETRIC - symmetric in terms of both structure and value 4933 . MAT_HERMITIAN - transpose is the complex conjugation 4934 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 4935 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 4936 you set to be kept with all future use of the matrix 4937 including after MatAssemblyBegin/End() which could 4938 potentially change the symmetry structure, i.e. you 4939 KNOW the matrix will ALWAYS have the property you set. 4940 4941 4942 Options For Use with MatSetValues(): 4943 Insert a logically dense subblock, which can be 4944 . MAT_ROW_ORIENTED - row-oriented (default) 4945 4946 Note these options reflect the data you pass in with MatSetValues(); it has 4947 nothing to do with how the data is stored internally in the matrix 4948 data structure. 4949 4950 When (re)assembling a matrix, we can restrict the input for 4951 efficiency/debugging purposes. These options include 4952 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be 4953 allowed if they generate a new nonzero 4954 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 4955 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 4956 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 4957 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 4958 + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 4959 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 4960 performance for very large process counts. 4961 4962 Notes: 4963 Some options are relevant only for particular matrix types and 4964 are thus ignored by others. Other options are not supported by 4965 certain matrix types and will generate an error message if set. 4966 4967 If using a Fortran 77 module to compute a matrix, one may need to 4968 use the column-oriented option (or convert to the row-oriented 4969 format). 4970 4971 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 4972 that would generate a new entry in the nonzero structure is instead 4973 ignored. Thus, if memory has not alredy been allocated for this particular 4974 data, then the insertion is ignored. For dense matrices, in which 4975 the entire array is allocated, no entries are ever ignored. 4976 Set after the first MatAssemblyEnd() 4977 4978 MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion 4979 that would generate a new entry in the nonzero structure instead produces 4980 an error. (Currently supported for AIJ and BAIJ formats only.) 4981 This is a useful flag when using SAME_NONZERO_PATTERN in calling 4982 KSPSetOperators() to ensure that the nonzero pattern truely does 4983 remain unchanged. Set after the first MatAssemblyEnd() 4984 4985 MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion 4986 that would generate a new entry that has not been preallocated will 4987 instead produce an error. (Currently supported for AIJ and BAIJ formats 4988 only.) This is a useful flag when debugging matrix memory preallocation. 4989 4990 MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 4991 other processors should be dropped, rather than stashed. 4992 This is useful if you know that the "owning" processor is also 4993 always generating the correct matrix entries, so that PETSc need 4994 not transfer duplicate entries generated on another processor. 4995 4996 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 4997 searches during matrix assembly. When this flag is set, the hash table 4998 is created during the first Matrix Assembly. This hash table is 4999 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5000 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5001 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5002 supported by MATMPIBAIJ format only. 5003 5004 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5005 are kept in the nonzero structure 5006 5007 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5008 a zero location in the matrix 5009 5010 MAT_USE_INODES - indicates using inode version of the code - works with AIJ and 5011 ROWBS matrix types 5012 5013 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5014 zero row routines and thus improves performance for very large process counts. 5015 5016 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5017 part of the matrix (since they should match the upper triangular part). 5018 5019 Notes: Can only be called after MatSetSizes() and MatSetType() have been set. 5020 5021 Level: intermediate 5022 5023 Concepts: matrices^setting options 5024 5025 @*/ 5026 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5027 { 5028 PetscErrorCode ierr; 5029 5030 PetscFunctionBegin; 5031 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5032 PetscValidType(mat,1); 5033 PetscValidLogicalCollectiveEnum(mat,op,2); 5034 PetscValidLogicalCollectiveBool(mat,flg,3); 5035 5036 if (((int) op) < 0 || ((int) op) >= NUM_MAT_OPTIONS) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5037 if (!((PetscObject)mat)->type_name) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()"); 5038 5039 switch (op) { 5040 case MAT_NO_OFF_PROC_ENTRIES: 5041 mat->nooffprocentries = flg; 5042 PetscFunctionReturn(0); 5043 break; 5044 case MAT_NO_OFF_PROC_ZERO_ROWS: 5045 mat->nooffproczerorows = flg; 5046 PetscFunctionReturn(0); 5047 break; 5048 case MAT_SPD: 5049 mat->spd_set = PETSC_TRUE; 5050 mat->spd = flg; 5051 if (flg) { 5052 mat->symmetric = PETSC_TRUE; 5053 mat->structurally_symmetric = PETSC_TRUE; 5054 mat->symmetric_set = PETSC_TRUE; 5055 mat->structurally_symmetric_set = PETSC_TRUE; 5056 } 5057 break; 5058 case MAT_SYMMETRIC: 5059 mat->symmetric = flg; 5060 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5061 mat->symmetric_set = PETSC_TRUE; 5062 mat->structurally_symmetric_set = flg; 5063 break; 5064 case MAT_HERMITIAN: 5065 mat->hermitian = flg; 5066 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5067 mat->hermitian_set = PETSC_TRUE; 5068 mat->structurally_symmetric_set = flg; 5069 break; 5070 case MAT_STRUCTURALLY_SYMMETRIC: 5071 mat->structurally_symmetric = flg; 5072 mat->structurally_symmetric_set = PETSC_TRUE; 5073 break; 5074 case MAT_SYMMETRY_ETERNAL: 5075 mat->symmetric_eternal = flg; 5076 break; 5077 default: 5078 break; 5079 } 5080 if (mat->ops->setoption) { 5081 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5082 } 5083 PetscFunctionReturn(0); 5084 } 5085 5086 #undef __FUNCT__ 5087 #define __FUNCT__ "MatZeroEntries" 5088 /*@ 5089 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5090 this routine retains the old nonzero structure. 5091 5092 Logically Collective on Mat 5093 5094 Input Parameters: 5095 . mat - the matrix 5096 5097 Level: intermediate 5098 5099 Notes: If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase. 5100 See the Performance chapter of the users manual for information on preallocating matrices. 5101 5102 Concepts: matrices^zeroing 5103 5104 .seealso: MatZeroRows() 5105 @*/ 5106 PetscErrorCode MatZeroEntries(Mat mat) 5107 { 5108 PetscErrorCode ierr; 5109 5110 PetscFunctionBegin; 5111 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5112 PetscValidType(mat,1); 5113 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5114 if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled"); 5115 if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5116 MatCheckPreallocated(mat,1); 5117 5118 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5119 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5120 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5121 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5122 #if defined(PETSC_HAVE_CUSP) 5123 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5124 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5125 } 5126 #endif 5127 PetscFunctionReturn(0); 5128 } 5129 5130 #undef __FUNCT__ 5131 #define __FUNCT__ "MatZeroRowsColumns" 5132 /*@C 5133 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5134 of a set of rows and columns of a matrix. 5135 5136 Collective on Mat 5137 5138 Input Parameters: 5139 + mat - the matrix 5140 . numRows - the number of rows to remove 5141 . rows - the global row indices 5142 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5143 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5144 - b - optional vector of right hand side, that will be adjusted by provided solution 5145 5146 Notes: 5147 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5148 5149 The user can set a value in the diagonal entry (or for the AIJ and 5150 row formats can optionally remove the main diagonal entry from the 5151 nonzero structure as well, by passing 0.0 as the final argument). 5152 5153 For the parallel case, all processes that share the matrix (i.e., 5154 those in the communicator used for matrix creation) MUST call this 5155 routine, regardless of whether any rows being zeroed are owned by 5156 them. 5157 5158 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5159 list only rows local to itself). 5160 5161 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5162 5163 Level: intermediate 5164 5165 Concepts: matrices^zeroing rows 5166 5167 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS() 5168 @*/ 5169 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5170 { 5171 PetscErrorCode ierr; 5172 5173 PetscFunctionBegin; 5174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5175 PetscValidType(mat,1); 5176 if (numRows) PetscValidIntPointer(rows,3); 5177 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5178 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5179 if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5180 MatCheckPreallocated(mat,1); 5181 5182 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5183 ierr = MatView_Private(mat);CHKERRQ(ierr); 5184 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5185 #if defined(PETSC_HAVE_CUSP) 5186 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5187 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5188 } 5189 #endif 5190 PetscFunctionReturn(0); 5191 } 5192 5193 #undef __FUNCT__ 5194 #define __FUNCT__ "MatZeroRowsColumnsIS" 5195 /*@C 5196 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5197 of a set of rows and columns of a matrix. 5198 5199 Collective on Mat 5200 5201 Input Parameters: 5202 + mat - the matrix 5203 . is - the rows to zero 5204 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5205 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5206 - b - optional vector of right hand side, that will be adjusted by provided solution 5207 5208 Notes: 5209 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5210 5211 The user can set a value in the diagonal entry (or for the AIJ and 5212 row formats can optionally remove the main diagonal entry from the 5213 nonzero structure as well, by passing 0.0 as the final argument). 5214 5215 For the parallel case, all processes that share the matrix (i.e., 5216 those in the communicator used for matrix creation) MUST call this 5217 routine, regardless of whether any rows being zeroed are owned by 5218 them. 5219 5220 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5221 list only rows local to itself). 5222 5223 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5224 5225 Level: intermediate 5226 5227 Concepts: matrices^zeroing rows 5228 5229 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns() 5230 @*/ 5231 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5232 { 5233 PetscErrorCode ierr; 5234 PetscInt numRows; 5235 const PetscInt *rows; 5236 5237 PetscFunctionBegin; 5238 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5239 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5240 PetscValidType(mat,1); 5241 PetscValidType(is,2); 5242 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5243 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5244 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5245 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5246 PetscFunctionReturn(0); 5247 } 5248 5249 #undef __FUNCT__ 5250 #define __FUNCT__ "MatZeroRows" 5251 /*@C 5252 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5253 of a set of rows of a matrix. 5254 5255 Collective on Mat 5256 5257 Input Parameters: 5258 + mat - the matrix 5259 . numRows - the number of rows to remove 5260 . rows - the global row indices 5261 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5262 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5263 - b - optional vector of right hand side, that will be adjusted by provided solution 5264 5265 Notes: 5266 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5267 but does not release memory. For the dense and block diagonal 5268 formats this does not alter the nonzero structure. 5269 5270 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5271 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5272 merely zeroed. 5273 5274 The user can set a value in the diagonal entry (or for the AIJ and 5275 row formats can optionally remove the main diagonal entry from the 5276 nonzero structure as well, by passing 0.0 as the final argument). 5277 5278 For the parallel case, all processes that share the matrix (i.e., 5279 those in the communicator used for matrix creation) MUST call this 5280 routine, regardless of whether any rows being zeroed are owned by 5281 them. 5282 5283 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5284 list only rows local to itself). 5285 5286 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5287 owns that are to be zeroed. This saves a global synchronization in the implementation. 5288 5289 Level: intermediate 5290 5291 Concepts: matrices^zeroing rows 5292 5293 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5294 @*/ 5295 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5296 { 5297 PetscErrorCode ierr; 5298 5299 PetscFunctionBegin; 5300 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5301 PetscValidType(mat,1); 5302 if (numRows) PetscValidIntPointer(rows,3); 5303 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5304 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5305 if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5306 MatCheckPreallocated(mat,1); 5307 5308 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5309 ierr = MatView_Private(mat);CHKERRQ(ierr); 5310 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5311 #if defined(PETSC_HAVE_CUSP) 5312 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5313 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5314 } 5315 #endif 5316 PetscFunctionReturn(0); 5317 } 5318 5319 #undef __FUNCT__ 5320 #define __FUNCT__ "MatZeroRowsIS" 5321 /*@C 5322 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5323 of a set of rows of a matrix. 5324 5325 Collective on Mat 5326 5327 Input Parameters: 5328 + mat - the matrix 5329 . is - index set of rows to remove 5330 . diag - value put in all diagonals of eliminated rows 5331 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5332 - b - optional vector of right hand side, that will be adjusted by provided solution 5333 5334 Notes: 5335 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5336 but does not release memory. For the dense and block diagonal 5337 formats this does not alter the nonzero structure. 5338 5339 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5340 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5341 merely zeroed. 5342 5343 The user can set a value in the diagonal entry (or for the AIJ and 5344 row formats can optionally remove the main diagonal entry from the 5345 nonzero structure as well, by passing 0.0 as the final argument). 5346 5347 For the parallel case, all processes that share the matrix (i.e., 5348 those in the communicator used for matrix creation) MUST call this 5349 routine, regardless of whether any rows being zeroed are owned by 5350 them. 5351 5352 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5353 list only rows local to itself). 5354 5355 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5356 owns that are to be zeroed. This saves a global synchronization in the implementation. 5357 5358 Level: intermediate 5359 5360 Concepts: matrices^zeroing rows 5361 5362 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5363 @*/ 5364 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5365 { 5366 PetscInt numRows; 5367 const PetscInt *rows; 5368 PetscErrorCode ierr; 5369 5370 PetscFunctionBegin; 5371 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5372 PetscValidType(mat,1); 5373 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5374 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5375 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5376 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5377 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5378 PetscFunctionReturn(0); 5379 } 5380 5381 #undef __FUNCT__ 5382 #define __FUNCT__ "MatZeroRowsStencil" 5383 /*@C 5384 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5385 of a set of rows of a matrix. These rows must be local to the process. 5386 5387 Collective on Mat 5388 5389 Input Parameters: 5390 + mat - the matrix 5391 . numRows - the number of rows to remove 5392 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5393 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5394 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5395 - b - optional vector of right hand side, that will be adjusted by provided solution 5396 5397 Notes: 5398 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5399 but does not release memory. For the dense and block diagonal 5400 formats this does not alter the nonzero structure. 5401 5402 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5403 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5404 merely zeroed. 5405 5406 The user can set a value in the diagonal entry (or for the AIJ and 5407 row formats can optionally remove the main diagonal entry from the 5408 nonzero structure as well, by passing 0.0 as the final argument). 5409 5410 For the parallel case, all processes that share the matrix (i.e., 5411 those in the communicator used for matrix creation) MUST call this 5412 routine, regardless of whether any rows being zeroed are owned by 5413 them. 5414 5415 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5416 list only rows local to itself). 5417 5418 The grid coordinates are across the entire grid, not just the local portion 5419 5420 In Fortran idxm and idxn should be declared as 5421 $ MatStencil idxm(4,m) 5422 and the values inserted using 5423 $ idxm(MatStencil_i,1) = i 5424 $ idxm(MatStencil_j,1) = j 5425 $ idxm(MatStencil_k,1) = k 5426 $ idxm(MatStencil_c,1) = c 5427 etc 5428 5429 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5430 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5431 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5432 DMDA_BOUNDARY_PERIODIC boundary type. 5433 5434 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 5435 a single value per point) you can skip filling those indices. 5436 5437 Level: intermediate 5438 5439 Concepts: matrices^zeroing rows 5440 5441 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5442 @*/ 5443 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5444 { 5445 PetscInt dim = mat->stencil.dim; 5446 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5447 PetscInt *dims = mat->stencil.dims+1; 5448 PetscInt *starts = mat->stencil.starts; 5449 PetscInt *dxm = (PetscInt *) rows; 5450 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5451 PetscErrorCode ierr; 5452 5453 PetscFunctionBegin; 5454 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5455 PetscValidType(mat,1); 5456 if (numRows) PetscValidIntPointer(rows,3); 5457 5458 ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr); 5459 for(i = 0; i < numRows; ++i) { 5460 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5461 for(j = 0; j < 3-sdim; ++j) dxm++; 5462 /* Local index in X dir */ 5463 tmp = *dxm++ - starts[0]; 5464 /* Loop over remaining dimensions */ 5465 for(j = 0; j < dim-1; ++j) { 5466 /* If nonlocal, set index to be negative */ 5467 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5468 /* Update local index */ 5469 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5470 } 5471 /* Skip component slot if necessary */ 5472 if (mat->stencil.noc) dxm++; 5473 /* Local row number */ 5474 if (tmp >= 0) { 5475 jdxm[numNewRows++] = tmp; 5476 } 5477 } 5478 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5479 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5480 PetscFunctionReturn(0); 5481 } 5482 5483 #undef __FUNCT__ 5484 #define __FUNCT__ "MatZeroRowsColumnsStencil" 5485 /*@C 5486 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5487 of a set of rows and columns of a matrix. 5488 5489 Collective on Mat 5490 5491 Input Parameters: 5492 + mat - the matrix 5493 . numRows - the number of rows/columns to remove 5494 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5495 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5496 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5497 - b - optional vector of right hand side, that will be adjusted by provided solution 5498 5499 Notes: 5500 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5501 but does not release memory. For the dense and block diagonal 5502 formats this does not alter the nonzero structure. 5503 5504 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5505 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5506 merely zeroed. 5507 5508 The user can set a value in the diagonal entry (or for the AIJ and 5509 row formats can optionally remove the main diagonal entry from the 5510 nonzero structure as well, by passing 0.0 as the final argument). 5511 5512 For the parallel case, all processes that share the matrix (i.e., 5513 those in the communicator used for matrix creation) MUST call this 5514 routine, regardless of whether any rows being zeroed are owned by 5515 them. 5516 5517 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5518 list only rows local to itself, but the row/column numbers are given in local numbering). 5519 5520 The grid coordinates are across the entire grid, not just the local portion 5521 5522 In Fortran idxm and idxn should be declared as 5523 $ MatStencil idxm(4,m) 5524 and the values inserted using 5525 $ idxm(MatStencil_i,1) = i 5526 $ idxm(MatStencil_j,1) = j 5527 $ idxm(MatStencil_k,1) = k 5528 $ idxm(MatStencil_c,1) = c 5529 etc 5530 5531 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5532 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5533 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5534 DMDA_BOUNDARY_PERIODIC boundary type. 5535 5536 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 5537 a single value per point) you can skip filling those indices. 5538 5539 Level: intermediate 5540 5541 Concepts: matrices^zeroing rows 5542 5543 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5544 @*/ 5545 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5546 { 5547 PetscInt dim = mat->stencil.dim; 5548 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5549 PetscInt *dims = mat->stencil.dims+1; 5550 PetscInt *starts = mat->stencil.starts; 5551 PetscInt *dxm = (PetscInt *) rows; 5552 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5553 PetscErrorCode ierr; 5554 5555 PetscFunctionBegin; 5556 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5557 PetscValidType(mat,1); 5558 if (numRows) PetscValidIntPointer(rows,3); 5559 5560 ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr); 5561 for(i = 0; i < numRows; ++i) { 5562 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5563 for(j = 0; j < 3-sdim; ++j) dxm++; 5564 /* Local index in X dir */ 5565 tmp = *dxm++ - starts[0]; 5566 /* Loop over remaining dimensions */ 5567 for(j = 0; j < dim-1; ++j) { 5568 /* If nonlocal, set index to be negative */ 5569 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5570 /* Update local index */ 5571 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5572 } 5573 /* Skip component slot if necessary */ 5574 if (mat->stencil.noc) dxm++; 5575 /* Local row number */ 5576 if (tmp >= 0) { 5577 jdxm[numNewRows++] = tmp; 5578 } 5579 } 5580 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5581 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5582 PetscFunctionReturn(0); 5583 } 5584 5585 #undef __FUNCT__ 5586 #define __FUNCT__ "MatZeroRowsLocal" 5587 /*@C 5588 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 5589 of a set of rows of a matrix; using local numbering of rows. 5590 5591 Collective on Mat 5592 5593 Input Parameters: 5594 + mat - the matrix 5595 . numRows - the number of rows to remove 5596 . rows - the global row indices 5597 . diag - value put in all diagonals of eliminated rows 5598 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5599 - b - optional vector of right hand side, that will be adjusted by provided solution 5600 5601 Notes: 5602 Before calling MatZeroRowsLocal(), the user must first set the 5603 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5604 5605 For the AIJ matrix formats this removes the old nonzero structure, 5606 but does not release memory. For the dense and block diagonal 5607 formats this does not alter the nonzero structure. 5608 5609 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5610 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5611 merely zeroed. 5612 5613 The user can set a value in the diagonal entry (or for the AIJ and 5614 row formats can optionally remove the main diagonal entry from the 5615 nonzero structure as well, by passing 0.0 as the final argument). 5616 5617 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5618 owns that are to be zeroed. This saves a global synchronization in the implementation. 5619 5620 Level: intermediate 5621 5622 Concepts: matrices^zeroing 5623 5624 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5625 @*/ 5626 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5627 { 5628 PetscErrorCode ierr; 5629 PetscMPIInt size; 5630 5631 PetscFunctionBegin; 5632 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5633 PetscValidType(mat,1); 5634 if (numRows) PetscValidIntPointer(rows,3); 5635 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5636 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5637 MatCheckPreallocated(mat,1); 5638 5639 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 5640 if (mat->ops->zerorowslocal) { 5641 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5642 } else if (size == 1) { 5643 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5644 } else { 5645 IS is, newis; 5646 const PetscInt *newRows; 5647 5648 if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 5649 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 5650 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 5651 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 5652 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 5653 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 5654 ierr = ISDestroy(&newis);CHKERRQ(ierr); 5655 ierr = ISDestroy(&is);CHKERRQ(ierr); 5656 } 5657 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5658 #if defined(PETSC_HAVE_CUSP) 5659 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5660 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5661 } 5662 #endif 5663 PetscFunctionReturn(0); 5664 } 5665 5666 #undef __FUNCT__ 5667 #define __FUNCT__ "MatZeroRowsLocalIS" 5668 /*@C 5669 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 5670 of a set of rows of a matrix; using local numbering of rows. 5671 5672 Collective on Mat 5673 5674 Input Parameters: 5675 + mat - the matrix 5676 . is - index set of rows to remove 5677 . diag - value put in all diagonals of eliminated rows 5678 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5679 - b - optional vector of right hand side, that will be adjusted by provided solution 5680 5681 Notes: 5682 Before calling MatZeroRowsLocalIS(), the user must first set the 5683 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5684 5685 For the AIJ matrix formats this removes the old nonzero structure, 5686 but does not release memory. For the dense and block diagonal 5687 formats this does not alter the nonzero structure. 5688 5689 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5690 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5691 merely zeroed. 5692 5693 The user can set a value in the diagonal entry (or for the AIJ and 5694 row formats can optionally remove the main diagonal entry from the 5695 nonzero structure as well, by passing 0.0 as the final argument). 5696 5697 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5698 owns that are to be zeroed. This saves a global synchronization in the implementation. 5699 5700 Level: intermediate 5701 5702 Concepts: matrices^zeroing 5703 5704 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5705 @*/ 5706 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5707 { 5708 PetscErrorCode ierr; 5709 PetscInt numRows; 5710 const PetscInt *rows; 5711 5712 PetscFunctionBegin; 5713 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5714 PetscValidType(mat,1); 5715 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5716 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5717 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5718 MatCheckPreallocated(mat,1); 5719 5720 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5721 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5722 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5723 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5724 PetscFunctionReturn(0); 5725 } 5726 5727 #undef __FUNCT__ 5728 #define __FUNCT__ "MatZeroRowsColumnsLocal" 5729 /*@C 5730 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 5731 of a set of rows and columns of a matrix; using local numbering of rows. 5732 5733 Collective on Mat 5734 5735 Input Parameters: 5736 + mat - the matrix 5737 . numRows - the number of rows to remove 5738 . rows - the global row indices 5739 . diag - value put in all diagonals of eliminated rows 5740 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5741 - b - optional vector of right hand side, that will be adjusted by provided solution 5742 5743 Notes: 5744 Before calling MatZeroRowsColumnsLocal(), the user must first set the 5745 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5746 5747 The user can set a value in the diagonal entry (or for the AIJ and 5748 row formats can optionally remove the main diagonal entry from the 5749 nonzero structure as well, by passing 0.0 as the final argument). 5750 5751 Level: intermediate 5752 5753 Concepts: matrices^zeroing 5754 5755 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5756 @*/ 5757 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5758 { 5759 PetscErrorCode ierr; 5760 PetscMPIInt size; 5761 5762 PetscFunctionBegin; 5763 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5764 PetscValidType(mat,1); 5765 if (numRows) PetscValidIntPointer(rows,3); 5766 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5767 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5768 MatCheckPreallocated(mat,1); 5769 5770 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 5771 if (size == 1) { 5772 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5773 } else { 5774 IS is, newis; 5775 const PetscInt *newRows; 5776 5777 if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 5778 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 5779 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 5780 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 5781 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 5782 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 5783 ierr = ISDestroy(&newis);CHKERRQ(ierr); 5784 ierr = ISDestroy(&is);CHKERRQ(ierr); 5785 } 5786 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5787 #if defined(PETSC_HAVE_CUSP) 5788 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5789 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5790 } 5791 #endif 5792 PetscFunctionReturn(0); 5793 } 5794 5795 #undef __FUNCT__ 5796 #define __FUNCT__ "MatZeroRowsColumnsLocalIS" 5797 /*@C 5798 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 5799 of a set of rows and columns of a matrix; using local numbering of rows. 5800 5801 Collective on Mat 5802 5803 Input Parameters: 5804 + mat - the matrix 5805 . is - index set of rows to remove 5806 . diag - value put in all diagonals of eliminated rows 5807 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5808 - b - optional vector of right hand side, that will be adjusted by provided solution 5809 5810 Notes: 5811 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 5812 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5813 5814 The user can set a value in the diagonal entry (or for the AIJ and 5815 row formats can optionally remove the main diagonal entry from the 5816 nonzero structure as well, by passing 0.0 as the final argument). 5817 5818 Level: intermediate 5819 5820 Concepts: matrices^zeroing 5821 5822 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5823 @*/ 5824 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5825 { 5826 PetscErrorCode ierr; 5827 PetscInt numRows; 5828 const PetscInt *rows; 5829 5830 PetscFunctionBegin; 5831 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5832 PetscValidType(mat,1); 5833 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5834 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5835 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5836 MatCheckPreallocated(mat,1); 5837 5838 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5839 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5840 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5841 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5842 PetscFunctionReturn(0); 5843 } 5844 5845 #undef __FUNCT__ 5846 #define __FUNCT__ "MatGetSize" 5847 /*@ 5848 MatGetSize - Returns the numbers of rows and columns in a matrix. 5849 5850 Not Collective 5851 5852 Input Parameter: 5853 . mat - the matrix 5854 5855 Output Parameters: 5856 + m - the number of global rows 5857 - n - the number of global columns 5858 5859 Note: both output parameters can be PETSC_NULL on input. 5860 5861 Level: beginner 5862 5863 Concepts: matrices^size 5864 5865 .seealso: MatGetLocalSize() 5866 @*/ 5867 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt* n) 5868 { 5869 PetscFunctionBegin; 5870 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5871 if (m) *m = mat->rmap->N; 5872 if (n) *n = mat->cmap->N; 5873 PetscFunctionReturn(0); 5874 } 5875 5876 #undef __FUNCT__ 5877 #define __FUNCT__ "MatGetLocalSize" 5878 /*@ 5879 MatGetLocalSize - Returns the number of rows and columns in a matrix 5880 stored locally. This information may be implementation dependent, so 5881 use with care. 5882 5883 Not Collective 5884 5885 Input Parameters: 5886 . mat - the matrix 5887 5888 Output Parameters: 5889 + m - the number of local rows 5890 - n - the number of local columns 5891 5892 Note: both output parameters can be PETSC_NULL on input. 5893 5894 Level: beginner 5895 5896 Concepts: matrices^local size 5897 5898 .seealso: MatGetSize() 5899 @*/ 5900 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt* n) 5901 { 5902 PetscFunctionBegin; 5903 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5904 if (m) PetscValidIntPointer(m,2); 5905 if (n) PetscValidIntPointer(n,3); 5906 if (m) *m = mat->rmap->n; 5907 if (n) *n = mat->cmap->n; 5908 PetscFunctionReturn(0); 5909 } 5910 5911 #undef __FUNCT__ 5912 #define __FUNCT__ "MatGetOwnershipRangeColumn" 5913 /*@ 5914 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 5915 this processor. (The columns of the "diagonal block") 5916 5917 Not Collective, unless matrix has not been allocated, then collective on Mat 5918 5919 Input Parameters: 5920 . mat - the matrix 5921 5922 Output Parameters: 5923 + m - the global index of the first local column 5924 - n - one more than the global index of the last local column 5925 5926 Notes: both output parameters can be PETSC_NULL on input. 5927 5928 Level: developer 5929 5930 Concepts: matrices^column ownership 5931 5932 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 5933 5934 @*/ 5935 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt* n) 5936 { 5937 5938 PetscFunctionBegin; 5939 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5940 PetscValidType(mat,1); 5941 if (m) PetscValidIntPointer(m,2); 5942 if (n) PetscValidIntPointer(n,3); 5943 MatCheckPreallocated(mat,1); 5944 if (m) *m = mat->cmap->rstart; 5945 if (n) *n = mat->cmap->rend; 5946 PetscFunctionReturn(0); 5947 } 5948 5949 #undef __FUNCT__ 5950 #define __FUNCT__ "MatGetOwnershipRange" 5951 /*@ 5952 MatGetOwnershipRange - Returns the range of matrix rows owned by 5953 this processor, assuming that the matrix is laid out with the first 5954 n1 rows on the first processor, the next n2 rows on the second, etc. 5955 For certain parallel layouts this range may not be well defined. 5956 5957 Not Collective, unless matrix has not been allocated, then collective on Mat 5958 5959 Input Parameters: 5960 . mat - the matrix 5961 5962 Output Parameters: 5963 + m - the global index of the first local row 5964 - n - one more than the global index of the last local row 5965 5966 Note: both output parameters can be PETSC_NULL on input. 5967 5968 Level: beginner 5969 5970 Concepts: matrices^row ownership 5971 5972 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 5973 5974 @*/ 5975 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt* n) 5976 { 5977 5978 PetscFunctionBegin; 5979 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5980 PetscValidType(mat,1); 5981 if (m) PetscValidIntPointer(m,2); 5982 if (n) PetscValidIntPointer(n,3); 5983 MatCheckPreallocated(mat,1); 5984 if (m) *m = mat->rmap->rstart; 5985 if (n) *n = mat->rmap->rend; 5986 PetscFunctionReturn(0); 5987 } 5988 5989 #undef __FUNCT__ 5990 #define __FUNCT__ "MatGetOwnershipRanges" 5991 /*@C 5992 MatGetOwnershipRanges - Returns the range of matrix rows owned by 5993 each process 5994 5995 Not Collective, unless matrix has not been allocated, then collective on Mat 5996 5997 Input Parameters: 5998 . mat - the matrix 5999 6000 Output Parameters: 6001 . ranges - start of each processors portion plus one more then the total length at the end 6002 6003 Level: beginner 6004 6005 Concepts: matrices^row ownership 6006 6007 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6008 6009 @*/ 6010 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6011 { 6012 PetscErrorCode ierr; 6013 6014 PetscFunctionBegin; 6015 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6016 PetscValidType(mat,1); 6017 MatCheckPreallocated(mat,1); 6018 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6019 PetscFunctionReturn(0); 6020 } 6021 6022 #undef __FUNCT__ 6023 #define __FUNCT__ "MatGetOwnershipRangesColumn" 6024 /*@C 6025 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6026 this processor. (The columns of the "diagonal blocks" for each process) 6027 6028 Not Collective, unless matrix has not been allocated, then collective on Mat 6029 6030 Input Parameters: 6031 . mat - the matrix 6032 6033 Output Parameters: 6034 . ranges - start of each processors portion plus one more then the total length at the end 6035 6036 Level: beginner 6037 6038 Concepts: matrices^column ownership 6039 6040 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6041 6042 @*/ 6043 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6044 { 6045 PetscErrorCode ierr; 6046 6047 PetscFunctionBegin; 6048 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6049 PetscValidType(mat,1); 6050 MatCheckPreallocated(mat,1); 6051 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6052 PetscFunctionReturn(0); 6053 } 6054 6055 #undef __FUNCT__ 6056 #define __FUNCT__ "MatILUFactorSymbolic" 6057 /*@C 6058 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6059 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6060 to complete the factorization. 6061 6062 Collective on Mat 6063 6064 Input Parameters: 6065 + mat - the matrix 6066 . row - row permutation 6067 . column - column permutation 6068 - info - structure containing 6069 $ levels - number of levels of fill. 6070 $ expected fill - as ratio of original fill. 6071 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6072 missing diagonal entries) 6073 6074 Output Parameters: 6075 . fact - new matrix that has been symbolically factored 6076 6077 Notes: 6078 See the <a href="../../docs/manual.pdf">users manual</a> for additional information about 6079 choosing the fill factor for better efficiency. 6080 6081 Most users should employ the simplified KSP interface for linear solvers 6082 instead of working directly with matrix algebra routines such as this. 6083 See, e.g., KSPCreate(). 6084 6085 Level: developer 6086 6087 Concepts: matrices^symbolic LU factorization 6088 Concepts: matrices^factorization 6089 Concepts: LU^symbolic factorization 6090 6091 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6092 MatGetOrdering(), MatFactorInfo 6093 6094 Developer Note: fortran interface is not autogenerated as the f90 6095 interface defintion cannot be generated correctly [due to MatFactorInfo] 6096 6097 @*/ 6098 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6099 { 6100 PetscErrorCode ierr; 6101 6102 PetscFunctionBegin; 6103 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6104 PetscValidType(mat,1); 6105 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6106 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6107 PetscValidPointer(info,4); 6108 PetscValidPointer(fact,5); 6109 if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6110 if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill); 6111 if (!(fact)->ops->ilufactorsymbolic) { 6112 const MatSolverPackage spackage; 6113 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6114 SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6115 } 6116 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6117 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6118 MatCheckPreallocated(mat,2); 6119 6120 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6121 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6122 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6123 PetscFunctionReturn(0); 6124 } 6125 6126 #undef __FUNCT__ 6127 #define __FUNCT__ "MatICCFactorSymbolic" 6128 /*@C 6129 MatICCFactorSymbolic - Performs symbolic incomplete 6130 Cholesky factorization for a symmetric matrix. Use 6131 MatCholeskyFactorNumeric() to complete the factorization. 6132 6133 Collective on Mat 6134 6135 Input Parameters: 6136 + mat - the matrix 6137 . perm - row and column permutation 6138 - info - structure containing 6139 $ levels - number of levels of fill. 6140 $ expected fill - as ratio of original fill. 6141 6142 Output Parameter: 6143 . fact - the factored matrix 6144 6145 Notes: 6146 Most users should employ the KSP interface for linear solvers 6147 instead of working directly with matrix algebra routines such as this. 6148 See, e.g., KSPCreate(). 6149 6150 Level: developer 6151 6152 Concepts: matrices^symbolic incomplete Cholesky factorization 6153 Concepts: matrices^factorization 6154 Concepts: Cholsky^symbolic factorization 6155 6156 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6157 6158 Developer Note: fortran interface is not autogenerated as the f90 6159 interface defintion cannot be generated correctly [due to MatFactorInfo] 6160 6161 @*/ 6162 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6163 { 6164 PetscErrorCode ierr; 6165 6166 PetscFunctionBegin; 6167 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6168 PetscValidType(mat,1); 6169 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6170 PetscValidPointer(info,3); 6171 PetscValidPointer(fact,4); 6172 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6173 if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6174 if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill); 6175 if (!(fact)->ops->iccfactorsymbolic) { 6176 const MatSolverPackage spackage; 6177 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6178 SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6179 } 6180 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6181 MatCheckPreallocated(mat,2); 6182 6183 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6184 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6185 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6186 PetscFunctionReturn(0); 6187 } 6188 6189 #undef __FUNCT__ 6190 #define __FUNCT__ "MatGetArray" 6191 /*@C 6192 MatGetArray - Returns a pointer to the element values in the matrix. 6193 The result of this routine is dependent on the underlying matrix data 6194 structure, and may not even work for certain matrix types. You MUST 6195 call MatRestoreArray() when you no longer need to access the array. 6196 6197 Not Collective 6198 6199 Input Parameter: 6200 . mat - the matrix 6201 6202 Output Parameter: 6203 . v - the location of the values 6204 6205 6206 Fortran Note: 6207 This routine is used differently from Fortran, e.g., 6208 .vb 6209 Mat mat 6210 PetscScalar mat_array(1) 6211 PetscOffset i_mat 6212 PetscErrorCode ierr 6213 call MatGetArray(mat,mat_array,i_mat,ierr) 6214 6215 C Access first local entry in matrix; note that array is 6216 C treated as one dimensional 6217 value = mat_array(i_mat + 1) 6218 6219 [... other code ...] 6220 call MatRestoreArray(mat,mat_array,i_mat,ierr) 6221 .ve 6222 6223 See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> and 6224 src/mat/examples/tests for details. 6225 6226 Level: advanced 6227 6228 Concepts: matrices^access array 6229 6230 .seealso: MatRestoreArray(), MatGetArrayF90(), MatGetRowIJ() 6231 @*/ 6232 PetscErrorCode MatGetArray(Mat mat,PetscScalar *v[]) 6233 { 6234 PetscErrorCode ierr; 6235 6236 PetscFunctionBegin; 6237 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6238 PetscValidType(mat,1); 6239 PetscValidPointer(v,2); 6240 if (!mat->ops->getarray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6241 MatCheckPreallocated(mat,1); 6242 ierr = (*mat->ops->getarray)(mat,v);CHKERRQ(ierr); 6243 CHKMEMQ; 6244 PetscFunctionReturn(0); 6245 } 6246 6247 #undef __FUNCT__ 6248 #define __FUNCT__ "MatRestoreArray" 6249 /*@C 6250 MatRestoreArray - Restores the matrix after MatGetArray() has been called. 6251 6252 Not Collective 6253 6254 Input Parameter: 6255 + mat - the matrix 6256 - v - the location of the values 6257 6258 Fortran Note: 6259 This routine is used differently from Fortran, e.g., 6260 .vb 6261 Mat mat 6262 PetscScalar mat_array(1) 6263 PetscOffset i_mat 6264 PetscErrorCode ierr 6265 call MatGetArray(mat,mat_array,i_mat,ierr) 6266 6267 C Access first local entry in matrix; note that array is 6268 C treated as one dimensional 6269 value = mat_array(i_mat + 1) 6270 6271 [... other code ...] 6272 call MatRestoreArray(mat,mat_array,i_mat,ierr) 6273 .ve 6274 6275 See the <a href="../../docs/manual.pdf#ch_fortran">Fortran chapter of the users manual</a> 6276 src/mat/examples/tests for details 6277 6278 Level: advanced 6279 6280 .seealso: MatGetArray(), MatRestoreArrayF90() 6281 @*/ 6282 PetscErrorCode MatRestoreArray(Mat mat,PetscScalar *v[]) 6283 { 6284 PetscErrorCode ierr; 6285 6286 PetscFunctionBegin; 6287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6288 PetscValidType(mat,1); 6289 PetscValidPointer(v,2); 6290 CHKMEMQ; 6291 if (!mat->ops->restorearray) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6292 ierr = (*mat->ops->restorearray)(mat,v);CHKERRQ(ierr); 6293 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6294 #if defined(PETSC_HAVE_CUSP) 6295 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 6296 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 6297 } 6298 #endif 6299 PetscFunctionReturn(0); 6300 } 6301 6302 #undef __FUNCT__ 6303 #define __FUNCT__ "MatGetSubMatrices" 6304 /*@C 6305 MatGetSubMatrices - Extracts several submatrices from a matrix. If submat 6306 points to an array of valid matrices, they may be reused to store the new 6307 submatrices. 6308 6309 Collective on Mat 6310 6311 Input Parameters: 6312 + mat - the matrix 6313 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6314 . irow, icol - index sets of rows and columns to extract (must be sorted) 6315 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6316 6317 Output Parameter: 6318 . submat - the array of submatrices 6319 6320 Notes: 6321 MatGetSubMatrices() can extract ONLY sequential submatrices 6322 (from both sequential and parallel matrices). Use MatGetSubMatrix() 6323 to extract a parallel submatrix. 6324 6325 Currently both row and column indices must be sorted to guarantee 6326 correctness with all matrix types. 6327 6328 When extracting submatrices from a parallel matrix, each processor can 6329 form a different submatrix by setting the rows and columns of its 6330 individual index sets according to the local submatrix desired. 6331 6332 When finished using the submatrices, the user should destroy 6333 them with MatDestroyMatrices(). 6334 6335 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6336 original matrix has not changed from that last call to MatGetSubMatrices(). 6337 6338 This routine creates the matrices in submat; you should NOT create them before 6339 calling it. It also allocates the array of matrix pointers submat. 6340 6341 For BAIJ matrices the index sets must respect the block structure, that is if they 6342 request one row/column in a block, they must request all rows/columns that are in 6343 that block. For example, if the block size is 2 you cannot request just row 0 and 6344 column 0. 6345 6346 Fortran Note: 6347 The Fortran interface is slightly different from that given below; it 6348 requires one to pass in as submat a Mat (integer) array of size at least m. 6349 6350 Level: advanced 6351 6352 Concepts: matrices^accessing submatrices 6353 Concepts: submatrices 6354 6355 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6356 @*/ 6357 PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6358 { 6359 PetscErrorCode ierr; 6360 PetscInt i; 6361 PetscBool eq; 6362 6363 PetscFunctionBegin; 6364 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6365 PetscValidType(mat,1); 6366 if (n) { 6367 PetscValidPointer(irow,3); 6368 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6369 PetscValidPointer(icol,4); 6370 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6371 } 6372 PetscValidPointer(submat,6); 6373 if (n && scall == MAT_REUSE_MATRIX) { 6374 PetscValidPointer(*submat,6); 6375 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6376 } 6377 if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6378 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6379 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6380 MatCheckPreallocated(mat,1); 6381 6382 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6383 ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6384 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6385 for (i=0; i<n; i++) { 6386 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6387 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6388 if (eq) { 6389 if (mat->symmetric){ 6390 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6391 } else if (mat->hermitian) { 6392 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6393 } else if (mat->structurally_symmetric) { 6394 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6395 } 6396 } 6397 } 6398 } 6399 PetscFunctionReturn(0); 6400 } 6401 6402 #undef __FUNCT__ 6403 #define __FUNCT__ "MatGetSubMatricesParallel" 6404 PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6405 { 6406 PetscErrorCode ierr; 6407 PetscInt i; 6408 PetscBool eq; 6409 6410 PetscFunctionBegin; 6411 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6412 PetscValidType(mat,1); 6413 if (n) { 6414 PetscValidPointer(irow,3); 6415 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6416 PetscValidPointer(icol,4); 6417 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6418 } 6419 PetscValidPointer(submat,6); 6420 if (n && scall == MAT_REUSE_MATRIX) { 6421 PetscValidPointer(*submat,6); 6422 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6423 } 6424 if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6425 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6426 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6427 MatCheckPreallocated(mat,1); 6428 6429 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6430 ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6431 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6432 for (i=0; i<n; i++) { 6433 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6434 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6435 if (eq) { 6436 if (mat->symmetric){ 6437 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6438 } else if (mat->hermitian) { 6439 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6440 } else if (mat->structurally_symmetric) { 6441 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6442 } 6443 } 6444 } 6445 } 6446 PetscFunctionReturn(0); 6447 } 6448 6449 #undef __FUNCT__ 6450 #define __FUNCT__ "MatDestroyMatrices" 6451 /*@C 6452 MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices(). 6453 6454 Collective on Mat 6455 6456 Input Parameters: 6457 + n - the number of local matrices 6458 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6459 sequence of MatGetSubMatrices()) 6460 6461 Level: advanced 6462 6463 Notes: Frees not only the matrices, but also the array that contains the matrices 6464 In Fortran will not free the array. 6465 6466 .seealso: MatGetSubMatrices() 6467 @*/ 6468 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6469 { 6470 PetscErrorCode ierr; 6471 PetscInt i; 6472 6473 PetscFunctionBegin; 6474 if (!*mat) PetscFunctionReturn(0); 6475 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6476 PetscValidPointer(mat,2); 6477 for (i=0; i<n; i++) { 6478 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6479 } 6480 /* memory is allocated even if n = 0 */ 6481 ierr = PetscFree(*mat);CHKERRQ(ierr); 6482 *mat = PETSC_NULL; 6483 PetscFunctionReturn(0); 6484 } 6485 6486 #undef __FUNCT__ 6487 #define __FUNCT__ "MatGetSeqNonzeroStructure" 6488 /*@C 6489 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6490 6491 Collective on Mat 6492 6493 Input Parameters: 6494 . mat - the matrix 6495 6496 Output Parameter: 6497 . matstruct - the sequential matrix with the nonzero structure of mat 6498 6499 Level: intermediate 6500 6501 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices() 6502 @*/ 6503 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6504 { 6505 PetscErrorCode ierr; 6506 6507 PetscFunctionBegin; 6508 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6509 PetscValidPointer(matstruct,2); 6510 6511 PetscValidType(mat,1); 6512 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6513 MatCheckPreallocated(mat,1); 6514 6515 if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6516 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6517 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6518 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6519 PetscFunctionReturn(0); 6520 } 6521 6522 #undef __FUNCT__ 6523 #define __FUNCT__ "MatDestroySeqNonzeroStructure" 6524 /*@C 6525 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6526 6527 Collective on Mat 6528 6529 Input Parameters: 6530 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6531 sequence of MatGetSequentialNonzeroStructure()) 6532 6533 Level: advanced 6534 6535 Notes: Frees not only the matrices, but also the array that contains the matrices 6536 6537 .seealso: MatGetSeqNonzeroStructure() 6538 @*/ 6539 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6540 { 6541 PetscErrorCode ierr; 6542 6543 PetscFunctionBegin; 6544 PetscValidPointer(mat,1); 6545 ierr = MatDestroy(mat);CHKERRQ(ierr); 6546 PetscFunctionReturn(0); 6547 } 6548 6549 #undef __FUNCT__ 6550 #define __FUNCT__ "MatIncreaseOverlap" 6551 /*@ 6552 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6553 replaces the index sets by larger ones that represent submatrices with 6554 additional overlap. 6555 6556 Collective on Mat 6557 6558 Input Parameters: 6559 + mat - the matrix 6560 . n - the number of index sets 6561 . is - the array of index sets (these index sets will changed during the call) 6562 - ov - the additional overlap requested 6563 6564 Level: developer 6565 6566 Concepts: overlap 6567 Concepts: ASM^computing overlap 6568 6569 .seealso: MatGetSubMatrices() 6570 @*/ 6571 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6572 { 6573 PetscErrorCode ierr; 6574 6575 PetscFunctionBegin; 6576 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6577 PetscValidType(mat,1); 6578 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6579 if (n) { 6580 PetscValidPointer(is,3); 6581 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6582 } 6583 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6584 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6585 MatCheckPreallocated(mat,1); 6586 6587 if (!ov) PetscFunctionReturn(0); 6588 if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6589 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6590 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6591 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6592 PetscFunctionReturn(0); 6593 } 6594 6595 #undef __FUNCT__ 6596 #define __FUNCT__ "MatGetBlockSize" 6597 /*@ 6598 MatGetBlockSize - Returns the matrix block size; useful especially for the 6599 block row and block diagonal formats. 6600 6601 Not Collective 6602 6603 Input Parameter: 6604 . mat - the matrix 6605 6606 Output Parameter: 6607 . bs - block size 6608 6609 Notes: 6610 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ 6611 6612 Level: intermediate 6613 6614 Concepts: matrices^block size 6615 6616 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 6617 @*/ 6618 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 6619 { 6620 6621 PetscFunctionBegin; 6622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6623 PetscValidType(mat,1); 6624 PetscValidIntPointer(bs,2); 6625 MatCheckPreallocated(mat,1); 6626 *bs = mat->rmap->bs; 6627 PetscFunctionReturn(0); 6628 } 6629 6630 #undef __FUNCT__ 6631 #define __FUNCT__ "MatGetBlockSizes" 6632 /*@ 6633 MatGetBlockSizes - Returns the matrix block row and column sizes; 6634 useful especially for the block row and block diagonal formats. 6635 6636 Not Collective 6637 6638 Input Parameter: 6639 . mat - the matrix 6640 6641 Output Parameter: 6642 . rbs - row block size 6643 . cbs - coumn block size 6644 6645 Notes: 6646 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ 6647 6648 Level: intermediate 6649 6650 Concepts: matrices^block size 6651 6652 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6653 @*/ 6654 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 6655 { 6656 6657 PetscFunctionBegin; 6658 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6659 PetscValidType(mat,1); 6660 if(rbs) PetscValidIntPointer(rbs,2); 6661 if(cbs) PetscValidIntPointer(cbs,3); 6662 MatCheckPreallocated(mat,1); 6663 if(rbs) *rbs = mat->rmap->bs; 6664 if(cbs) *cbs = mat->cmap->bs; 6665 PetscFunctionReturn(0); 6666 } 6667 6668 #undef __FUNCT__ 6669 #define __FUNCT__ "MatSetBlockSize" 6670 /*@ 6671 MatSetBlockSize - Sets the matrix block size. 6672 6673 Logically Collective on Mat 6674 6675 Input Parameters: 6676 + mat - the matrix 6677 - bs - block size 6678 6679 Notes: 6680 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 6681 6682 Level: intermediate 6683 6684 Concepts: matrices^block size 6685 6686 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6687 @*/ 6688 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 6689 { 6690 PetscErrorCode ierr; 6691 6692 PetscFunctionBegin; 6693 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6694 PetscValidLogicalCollectiveInt(mat,bs,2); 6695 ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr); 6696 ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr); 6697 PetscFunctionReturn(0); 6698 } 6699 6700 #undef __FUNCT__ 6701 #define __FUNCT__ "MatSetBlockSizes" 6702 /*@ 6703 MatSetBlockSizes - Sets the matrix block row and column sizes. 6704 6705 Logically Collective on Mat 6706 6707 Input Parameters: 6708 + mat - the matrix 6709 - rbs - row block size 6710 - cbs - column block size 6711 6712 Notes: 6713 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 6714 6715 Level: intermediate 6716 6717 Concepts: matrices^block size 6718 6719 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6720 @*/ 6721 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 6722 { 6723 PetscErrorCode ierr; 6724 6725 PetscFunctionBegin; 6726 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6727 PetscValidLogicalCollectiveInt(mat,rbs,2); 6728 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 6729 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 6730 PetscFunctionReturn(0); 6731 } 6732 6733 #undef __FUNCT__ 6734 #define __FUNCT__ "MatGetRowIJ" 6735 /*@C 6736 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 6737 6738 Collective on Mat 6739 6740 Input Parameters: 6741 + mat - the matrix 6742 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 6743 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 6744 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6745 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6746 always used. 6747 6748 Output Parameters: 6749 + n - number of rows in the (possibly compressed) matrix 6750 . ia - the row pointers [of length n+1] 6751 . ja - the column indices 6752 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 6753 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 6754 6755 Level: developer 6756 6757 Notes: You CANNOT change any of the ia[] or ja[] values. 6758 6759 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values 6760 6761 Fortran Node 6762 6763 In Fortran use 6764 $ PetscInt ia(1), ja(1) 6765 $ PetscOffset iia, jja 6766 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 6767 $ 6768 $ or 6769 $ 6770 $ PetscScalar, pointer :: xx_v(:) 6771 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 6772 6773 6774 Acess the ith and jth entries via ia(iia + i) and ja(jja + j) 6775 6776 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatGetArray() 6777 @*/ 6778 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done) 6779 { 6780 PetscErrorCode ierr; 6781 6782 PetscFunctionBegin; 6783 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6784 PetscValidType(mat,1); 6785 PetscValidIntPointer(n,4); 6786 if (ia) PetscValidIntPointer(ia,5); 6787 if (ja) PetscValidIntPointer(ja,6); 6788 PetscValidIntPointer(done,7); 6789 MatCheckPreallocated(mat,1); 6790 if (!mat->ops->getrowij) *done = PETSC_FALSE; 6791 else { 6792 *done = PETSC_TRUE; 6793 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 6794 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6795 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 6796 } 6797 PetscFunctionReturn(0); 6798 } 6799 6800 #undef __FUNCT__ 6801 #define __FUNCT__ "MatGetColumnIJ" 6802 /*@C 6803 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 6804 6805 Collective on Mat 6806 6807 Input Parameters: 6808 + mat - the matrix 6809 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6810 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6811 symmetrized 6812 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6813 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6814 always used. 6815 6816 Output Parameters: 6817 + n - number of columns in the (possibly compressed) matrix 6818 . ia - the column pointers 6819 . ja - the row indices 6820 - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 6821 6822 Level: developer 6823 6824 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 6825 @*/ 6826 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done) 6827 { 6828 PetscErrorCode ierr; 6829 6830 PetscFunctionBegin; 6831 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6832 PetscValidType(mat,1); 6833 PetscValidIntPointer(n,4); 6834 if (ia) PetscValidIntPointer(ia,5); 6835 if (ja) PetscValidIntPointer(ja,6); 6836 PetscValidIntPointer(done,7); 6837 MatCheckPreallocated(mat,1); 6838 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 6839 else { 6840 *done = PETSC_TRUE; 6841 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6842 } 6843 PetscFunctionReturn(0); 6844 } 6845 6846 #undef __FUNCT__ 6847 #define __FUNCT__ "MatRestoreRowIJ" 6848 /*@C 6849 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 6850 MatGetRowIJ(). 6851 6852 Collective on Mat 6853 6854 Input Parameters: 6855 + mat - the matrix 6856 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6857 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6858 symmetrized 6859 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6860 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6861 always used. 6862 6863 Output Parameters: 6864 + n - size of (possibly compressed) matrix 6865 . ia - the row pointers 6866 . ja - the column indices 6867 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 6868 6869 Level: developer 6870 6871 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 6872 @*/ 6873 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done) 6874 { 6875 PetscErrorCode ierr; 6876 6877 PetscFunctionBegin; 6878 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6879 PetscValidType(mat,1); 6880 if (ia) PetscValidIntPointer(ia,5); 6881 if (ja) PetscValidIntPointer(ja,6); 6882 PetscValidIntPointer(done,7); 6883 MatCheckPreallocated(mat,1); 6884 6885 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 6886 else { 6887 *done = PETSC_TRUE; 6888 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6889 } 6890 PetscFunctionReturn(0); 6891 } 6892 6893 #undef __FUNCT__ 6894 #define __FUNCT__ "MatRestoreColumnIJ" 6895 /*@C 6896 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 6897 MatGetColumnIJ(). 6898 6899 Collective on Mat 6900 6901 Input Parameters: 6902 + mat - the matrix 6903 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6904 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6905 symmetrized 6906 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6907 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6908 always used. 6909 6910 Output Parameters: 6911 + n - size of (possibly compressed) matrix 6912 . ia - the column pointers 6913 . ja - the row indices 6914 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 6915 6916 Level: developer 6917 6918 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 6919 @*/ 6920 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt* ja[],PetscBool *done) 6921 { 6922 PetscErrorCode ierr; 6923 6924 PetscFunctionBegin; 6925 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6926 PetscValidType(mat,1); 6927 if (ia) PetscValidIntPointer(ia,5); 6928 if (ja) PetscValidIntPointer(ja,6); 6929 PetscValidIntPointer(done,7); 6930 MatCheckPreallocated(mat,1); 6931 6932 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 6933 else { 6934 *done = PETSC_TRUE; 6935 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6936 } 6937 PetscFunctionReturn(0); 6938 } 6939 6940 #undef __FUNCT__ 6941 #define __FUNCT__ "MatColoringPatch" 6942 /*@C 6943 MatColoringPatch -Used inside matrix coloring routines that 6944 use MatGetRowIJ() and/or MatGetColumnIJ(). 6945 6946 Collective on Mat 6947 6948 Input Parameters: 6949 + mat - the matrix 6950 . ncolors - max color value 6951 . n - number of entries in colorarray 6952 - colorarray - array indicating color for each column 6953 6954 Output Parameters: 6955 . iscoloring - coloring generated using colorarray information 6956 6957 Level: developer 6958 6959 .seealso: MatGetRowIJ(), MatGetColumnIJ() 6960 6961 @*/ 6962 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 6963 { 6964 PetscErrorCode ierr; 6965 6966 PetscFunctionBegin; 6967 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6968 PetscValidType(mat,1); 6969 PetscValidIntPointer(colorarray,4); 6970 PetscValidPointer(iscoloring,5); 6971 MatCheckPreallocated(mat,1); 6972 6973 if (!mat->ops->coloringpatch){ 6974 ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 6975 } else { 6976 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 6977 } 6978 PetscFunctionReturn(0); 6979 } 6980 6981 6982 #undef __FUNCT__ 6983 #define __FUNCT__ "MatSetUnfactored" 6984 /*@ 6985 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 6986 6987 Logically Collective on Mat 6988 6989 Input Parameter: 6990 . mat - the factored matrix to be reset 6991 6992 Notes: 6993 This routine should be used only with factored matrices formed by in-place 6994 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 6995 format). This option can save memory, for example, when solving nonlinear 6996 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 6997 ILU(0) preconditioner. 6998 6999 Note that one can specify in-place ILU(0) factorization by calling 7000 .vb 7001 PCType(pc,PCILU); 7002 PCFactorSeUseInPlace(pc); 7003 .ve 7004 or by using the options -pc_type ilu -pc_factor_in_place 7005 7006 In-place factorization ILU(0) can also be used as a local 7007 solver for the blocks within the block Jacobi or additive Schwarz 7008 methods (runtime option: -sub_pc_factor_in_place). See the discussion 7009 of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting 7010 local solver options. 7011 7012 Most users should employ the simplified KSP interface for linear solvers 7013 instead of working directly with matrix algebra routines such as this. 7014 See, e.g., KSPCreate(). 7015 7016 Level: developer 7017 7018 .seealso: PCFactorSetUseInPlace() 7019 7020 Concepts: matrices^unfactored 7021 7022 @*/ 7023 PetscErrorCode MatSetUnfactored(Mat mat) 7024 { 7025 PetscErrorCode ierr; 7026 7027 PetscFunctionBegin; 7028 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7029 PetscValidType(mat,1); 7030 MatCheckPreallocated(mat,1); 7031 mat->factortype = MAT_FACTOR_NONE; 7032 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7033 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7034 PetscFunctionReturn(0); 7035 } 7036 7037 /*MC 7038 MatGetArrayF90 - Accesses a matrix array from Fortran90. 7039 7040 Synopsis: 7041 MatGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7042 7043 Not collective 7044 7045 Input Parameter: 7046 . x - matrix 7047 7048 Output Parameters: 7049 + xx_v - the Fortran90 pointer to the array 7050 - ierr - error code 7051 7052 Example of Usage: 7053 .vb 7054 PetscScalar, pointer xx_v(:,:) 7055 .... 7056 call MatGetArrayF90(x,xx_v,ierr) 7057 a = xx_v(3) 7058 call MatRestoreArrayF90(x,xx_v,ierr) 7059 .ve 7060 7061 Notes: 7062 Not yet supported for all F90 compilers 7063 7064 Level: advanced 7065 7066 .seealso: MatRestoreArrayF90(), MatGetArray(), MatRestoreArray() 7067 7068 Concepts: matrices^accessing array 7069 7070 M*/ 7071 7072 /*MC 7073 MatRestoreArrayF90 - Restores a matrix array that has been 7074 accessed with MatGetArrayF90(). 7075 7076 Synopsis: 7077 MatRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7078 7079 Not collective 7080 7081 Input Parameters: 7082 + x - matrix 7083 - xx_v - the Fortran90 pointer to the array 7084 7085 Output Parameter: 7086 . ierr - error code 7087 7088 Example of Usage: 7089 .vb 7090 PetscScalar, pointer xx_v(:) 7091 .... 7092 call MatGetArrayF90(x,xx_v,ierr) 7093 a = xx_v(3) 7094 call MatRestoreArrayF90(x,xx_v,ierr) 7095 .ve 7096 7097 Notes: 7098 Not yet supported for all F90 compilers 7099 7100 Level: advanced 7101 7102 .seealso: MatGetArrayF90(), MatGetArray(), MatRestoreArray() 7103 7104 M*/ 7105 7106 7107 #undef __FUNCT__ 7108 #define __FUNCT__ "MatGetSubMatrix" 7109 /*@ 7110 MatGetSubMatrix - Gets a single submatrix on the same number of processors 7111 as the original matrix. 7112 7113 Collective on Mat 7114 7115 Input Parameters: 7116 + mat - the original matrix 7117 . isrow - parallel IS containing the rows this processor should obtain 7118 . iscol - parallel IS containing all columns you wish to keep. Each process should list the columns that will be in IT's "diagonal part" in the new matrix. 7119 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7120 7121 Output Parameter: 7122 . newmat - the new submatrix, of the same type as the old 7123 7124 Level: advanced 7125 7126 Notes: 7127 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7128 7129 The rows in isrow will be sorted into the same order as the original matrix on each process. 7130 7131 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7132 the MatGetSubMatrix() routine will create the newmat for you. Any additional calls 7133 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7134 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7135 you are finished using it. 7136 7137 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7138 the input matrix. 7139 7140 If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran). 7141 7142 Example usage: 7143 Consider the following 8x8 matrix with 34 non-zero values, that is 7144 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7145 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7146 as follows: 7147 7148 .vb 7149 1 2 0 | 0 3 0 | 0 4 7150 Proc0 0 5 6 | 7 0 0 | 8 0 7151 9 0 10 | 11 0 0 | 12 0 7152 ------------------------------------- 7153 13 0 14 | 15 16 17 | 0 0 7154 Proc1 0 18 0 | 19 20 21 | 0 0 7155 0 0 0 | 22 23 0 | 24 0 7156 ------------------------------------- 7157 Proc2 25 26 27 | 0 0 28 | 29 0 7158 30 0 0 | 31 32 33 | 0 34 7159 .ve 7160 7161 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7162 7163 .vb 7164 2 0 | 0 3 0 | 0 7165 Proc0 5 6 | 7 0 0 | 8 7166 ------------------------------- 7167 Proc1 18 0 | 19 20 21 | 0 7168 ------------------------------- 7169 Proc2 26 27 | 0 0 28 | 29 7170 0 0 | 31 32 33 | 0 7171 .ve 7172 7173 7174 Concepts: matrices^submatrices 7175 7176 .seealso: MatGetSubMatrices() 7177 @*/ 7178 PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7179 { 7180 PetscErrorCode ierr; 7181 PetscMPIInt size; 7182 Mat *local; 7183 IS iscoltmp; 7184 7185 PetscFunctionBegin; 7186 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7187 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7188 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7189 PetscValidPointer(newmat,5); 7190 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7191 PetscValidType(mat,1); 7192 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7193 MatCheckPreallocated(mat,1); 7194 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 7195 7196 if (!iscol) { 7197 ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7198 } else { 7199 iscoltmp = iscol; 7200 } 7201 7202 /* if original matrix is on just one processor then use submatrix generated */ 7203 if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7204 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7205 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7206 PetscFunctionReturn(0); 7207 } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) { 7208 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7209 *newmat = *local; 7210 ierr = PetscFree(local);CHKERRQ(ierr); 7211 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7212 PetscFunctionReturn(0); 7213 } else if (!mat->ops->getsubmatrix) { 7214 /* Create a new matrix type that implements the operation using the full matrix */ 7215 switch (cll) { 7216 case MAT_INITIAL_MATRIX: 7217 ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7218 break; 7219 case MAT_REUSE_MATRIX: 7220 ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7221 break; 7222 default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7223 } 7224 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7225 PetscFunctionReturn(0); 7226 } 7227 7228 if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7229 ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7230 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7231 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7232 PetscFunctionReturn(0); 7233 } 7234 7235 #undef __FUNCT__ 7236 #define __FUNCT__ "MatStashSetInitialSize" 7237 /*@ 7238 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7239 used during the assembly process to store values that belong to 7240 other processors. 7241 7242 Not Collective 7243 7244 Input Parameters: 7245 + mat - the matrix 7246 . size - the initial size of the stash. 7247 - bsize - the initial size of the block-stash(if used). 7248 7249 Options Database Keys: 7250 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7251 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7252 7253 Level: intermediate 7254 7255 Notes: 7256 The block-stash is used for values set with MatSetValuesBlocked() while 7257 the stash is used for values set with MatSetValues() 7258 7259 Run with the option -info and look for output of the form 7260 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7261 to determine the appropriate value, MM, to use for size and 7262 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7263 to determine the value, BMM to use for bsize 7264 7265 Concepts: stash^setting matrix size 7266 Concepts: matrices^stash 7267 7268 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7269 7270 @*/ 7271 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7272 { 7273 PetscErrorCode ierr; 7274 7275 PetscFunctionBegin; 7276 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7277 PetscValidType(mat,1); 7278 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7279 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7280 PetscFunctionReturn(0); 7281 } 7282 7283 #undef __FUNCT__ 7284 #define __FUNCT__ "MatInterpolateAdd" 7285 /*@ 7286 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7287 the matrix 7288 7289 Neighbor-wise Collective on Mat 7290 7291 Input Parameters: 7292 + mat - the matrix 7293 . x,y - the vectors 7294 - w - where the result is stored 7295 7296 Level: intermediate 7297 7298 Notes: 7299 w may be the same vector as y. 7300 7301 This allows one to use either the restriction or interpolation (its transpose) 7302 matrix to do the interpolation 7303 7304 Concepts: interpolation 7305 7306 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7307 7308 @*/ 7309 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7310 { 7311 PetscErrorCode ierr; 7312 PetscInt M,N,Ny; 7313 7314 PetscFunctionBegin; 7315 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7316 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7317 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7318 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7319 PetscValidType(A,1); 7320 MatCheckPreallocated(A,1); 7321 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7322 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7323 if (M == Ny) { 7324 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7325 } else { 7326 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7327 } 7328 PetscFunctionReturn(0); 7329 } 7330 7331 #undef __FUNCT__ 7332 #define __FUNCT__ "MatInterpolate" 7333 /*@ 7334 MatInterpolate - y = A*x or A'*x depending on the shape of 7335 the matrix 7336 7337 Neighbor-wise Collective on Mat 7338 7339 Input Parameters: 7340 + mat - the matrix 7341 - x,y - the vectors 7342 7343 Level: intermediate 7344 7345 Notes: 7346 This allows one to use either the restriction or interpolation (its transpose) 7347 matrix to do the interpolation 7348 7349 Concepts: matrices^interpolation 7350 7351 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7352 7353 @*/ 7354 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 7355 { 7356 PetscErrorCode ierr; 7357 PetscInt M,N,Ny; 7358 7359 PetscFunctionBegin; 7360 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7361 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7362 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7363 PetscValidType(A,1); 7364 MatCheckPreallocated(A,1); 7365 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7366 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7367 if (M == Ny) { 7368 ierr = MatMult(A,x,y);CHKERRQ(ierr); 7369 } else { 7370 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 7371 } 7372 PetscFunctionReturn(0); 7373 } 7374 7375 #undef __FUNCT__ 7376 #define __FUNCT__ "MatRestrict" 7377 /*@ 7378 MatRestrict - y = A*x or A'*x 7379 7380 Neighbor-wise Collective on Mat 7381 7382 Input Parameters: 7383 + mat - the matrix 7384 - x,y - the vectors 7385 7386 Level: intermediate 7387 7388 Notes: 7389 This allows one to use either the restriction or interpolation (its transpose) 7390 matrix to do the restriction 7391 7392 Concepts: matrices^restriction 7393 7394 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 7395 7396 @*/ 7397 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 7398 { 7399 PetscErrorCode ierr; 7400 PetscInt M,N,Ny; 7401 7402 PetscFunctionBegin; 7403 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7404 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7405 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7406 PetscValidType(A,1); 7407 MatCheckPreallocated(A,1); 7408 7409 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7410 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7411 if (M == Ny) { 7412 ierr = MatMult(A,x,y);CHKERRQ(ierr); 7413 } else { 7414 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 7415 } 7416 PetscFunctionReturn(0); 7417 } 7418 7419 #undef __FUNCT__ 7420 #define __FUNCT__ "MatGetNullSpace" 7421 /*@ 7422 MatGetNullSpace - retrieves the null space to a matrix. 7423 7424 Logically Collective on Mat and MatNullSpace 7425 7426 Input Parameters: 7427 + mat - the matrix 7428 - nullsp - the null space object 7429 7430 Level: developer 7431 7432 Notes: 7433 This null space is used by solvers. Overwrites any previous null space that may have been attached 7434 7435 Concepts: null space^attaching to matrix 7436 7437 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace() 7438 @*/ 7439 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 7440 { 7441 PetscFunctionBegin; 7442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7443 PetscValidType(mat,1); 7444 PetscValidPointer(nullsp,2); 7445 *nullsp = mat->nullsp; 7446 PetscFunctionReturn(0); 7447 } 7448 7449 #undef __FUNCT__ 7450 #define __FUNCT__ "MatSetNullSpace" 7451 /*@ 7452 MatSetNullSpace - attaches a null space to a matrix. 7453 This null space will be removed from the resulting vector whenever 7454 MatMult() is called 7455 7456 Logically Collective on Mat and MatNullSpace 7457 7458 Input Parameters: 7459 + mat - the matrix 7460 - nullsp - the null space object 7461 7462 Level: advanced 7463 7464 Notes: 7465 This null space is used by solvers. Overwrites any previous null space that may have been attached 7466 7467 Concepts: null space^attaching to matrix 7468 7469 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace() 7470 @*/ 7471 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 7472 { 7473 PetscErrorCode ierr; 7474 7475 PetscFunctionBegin; 7476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7477 PetscValidType(mat,1); 7478 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 7479 MatCheckPreallocated(mat,1); 7480 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 7481 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 7482 mat->nullsp = nullsp; 7483 PetscFunctionReturn(0); 7484 } 7485 7486 #undef __FUNCT__ 7487 #define __FUNCT__ "MatSetNearNullSpace" 7488 /*@ 7489 MatSetNearNullSpace - attaches a null space to a matrix. 7490 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 7491 7492 Logically Collective on Mat and MatNullSpace 7493 7494 Input Parameters: 7495 + mat - the matrix 7496 - nullsp - the null space object 7497 7498 Level: advanced 7499 7500 Notes: 7501 Overwrites any previous near null space that may have been attached 7502 7503 Concepts: null space^attaching to matrix 7504 7505 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace() 7506 @*/ 7507 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 7508 { 7509 PetscErrorCode ierr; 7510 7511 PetscFunctionBegin; 7512 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7513 PetscValidType(mat,1); 7514 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 7515 MatCheckPreallocated(mat,1); 7516 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 7517 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 7518 mat->nearnullsp = nullsp; 7519 PetscFunctionReturn(0); 7520 } 7521 7522 #undef __FUNCT__ 7523 #define __FUNCT__ "MatGetNearNullSpace" 7524 /*@ 7525 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 7526 7527 Not Collective 7528 7529 Input Parameters: 7530 . mat - the matrix 7531 7532 Output Parameters: 7533 . nullsp - the null space object, PETSC_NULL if not set 7534 7535 Level: developer 7536 7537 Concepts: null space^attaching to matrix 7538 7539 .seealso: MatSetNearNullSpace(), MatGetNullSpace() 7540 @*/ 7541 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 7542 { 7543 7544 PetscFunctionBegin; 7545 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7546 PetscValidType(mat,1); 7547 PetscValidPointer(nullsp,2); 7548 MatCheckPreallocated(mat,1); 7549 *nullsp = mat->nearnullsp; 7550 PetscFunctionReturn(0); 7551 } 7552 7553 #undef __FUNCT__ 7554 #define __FUNCT__ "MatICCFactor" 7555 /*@C 7556 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 7557 7558 Collective on Mat 7559 7560 Input Parameters: 7561 + mat - the matrix 7562 . row - row/column permutation 7563 . fill - expected fill factor >= 1.0 7564 - level - level of fill, for ICC(k) 7565 7566 Notes: 7567 Probably really in-place only when level of fill is zero, otherwise allocates 7568 new space to store factored matrix and deletes previous memory. 7569 7570 Most users should employ the simplified KSP interface for linear solvers 7571 instead of working directly with matrix algebra routines such as this. 7572 See, e.g., KSPCreate(). 7573 7574 Level: developer 7575 7576 Concepts: matrices^incomplete Cholesky factorization 7577 Concepts: Cholesky factorization 7578 7579 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 7580 7581 Developer Note: fortran interface is not autogenerated as the f90 7582 interface defintion cannot be generated correctly [due to MatFactorInfo] 7583 7584 @*/ 7585 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info) 7586 { 7587 PetscErrorCode ierr; 7588 7589 PetscFunctionBegin; 7590 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7591 PetscValidType(mat,1); 7592 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 7593 PetscValidPointer(info,3); 7594 if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square"); 7595 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7596 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7597 if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7598 MatCheckPreallocated(mat,1); 7599 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 7600 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7601 PetscFunctionReturn(0); 7602 } 7603 7604 #undef __FUNCT__ 7605 #define __FUNCT__ "MatSetValuesAdic" 7606 /*@ 7607 MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix. 7608 7609 Not Collective 7610 7611 Input Parameters: 7612 + mat - the matrix 7613 - v - the values compute with ADIC 7614 7615 Level: developer 7616 7617 Notes: 7618 Must call MatSetColoring() before using this routine. Also this matrix must already 7619 have its nonzero pattern determined. 7620 7621 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 7622 MatSetValues(), MatSetColoring(), MatSetValuesAdifor() 7623 @*/ 7624 PetscErrorCode MatSetValuesAdic(Mat mat,void *v) 7625 { 7626 PetscErrorCode ierr; 7627 7628 PetscFunctionBegin; 7629 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7630 PetscValidType(mat,1); 7631 PetscValidPointer(mat,2); 7632 7633 if (!mat->assembled) { 7634 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7635 } 7636 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7637 if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7638 ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr); 7639 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7640 ierr = MatView_Private(mat);CHKERRQ(ierr); 7641 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7642 PetscFunctionReturn(0); 7643 } 7644 7645 7646 #undef __FUNCT__ 7647 #define __FUNCT__ "MatSetColoring" 7648 /*@ 7649 MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic() 7650 7651 Not Collective 7652 7653 Input Parameters: 7654 + mat - the matrix 7655 - coloring - the coloring 7656 7657 Level: developer 7658 7659 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 7660 MatSetValues(), MatSetValuesAdic() 7661 @*/ 7662 PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring) 7663 { 7664 PetscErrorCode ierr; 7665 7666 PetscFunctionBegin; 7667 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7668 PetscValidType(mat,1); 7669 PetscValidPointer(coloring,2); 7670 7671 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7672 if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7673 ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr); 7674 PetscFunctionReturn(0); 7675 } 7676 7677 #undef __FUNCT__ 7678 #define __FUNCT__ "MatSetValuesAdifor" 7679 /*@ 7680 MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix. 7681 7682 Not Collective 7683 7684 Input Parameters: 7685 + mat - the matrix 7686 . nl - leading dimension of v 7687 - v - the values compute with ADIFOR 7688 7689 Level: developer 7690 7691 Notes: 7692 Must call MatSetColoring() before using this routine. Also this matrix must already 7693 have its nonzero pattern determined. 7694 7695 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 7696 MatSetValues(), MatSetColoring() 7697 @*/ 7698 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v) 7699 { 7700 PetscErrorCode ierr; 7701 7702 PetscFunctionBegin; 7703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7704 PetscValidType(mat,1); 7705 PetscValidPointer(v,3); 7706 7707 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7708 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7709 if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7710 ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr); 7711 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7712 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7713 PetscFunctionReturn(0); 7714 } 7715 7716 #undef __FUNCT__ 7717 #define __FUNCT__ "MatDiagonalScaleLocal" 7718 /*@ 7719 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 7720 ghosted ones. 7721 7722 Not Collective 7723 7724 Input Parameters: 7725 + mat - the matrix 7726 - diag = the diagonal values, including ghost ones 7727 7728 Level: developer 7729 7730 Notes: Works only for MPIAIJ and MPIBAIJ matrices 7731 7732 .seealso: MatDiagonalScale() 7733 @*/ 7734 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 7735 { 7736 PetscErrorCode ierr; 7737 PetscMPIInt size; 7738 7739 PetscFunctionBegin; 7740 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7741 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 7742 PetscValidType(mat,1); 7743 7744 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7745 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 7746 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 7747 if (size == 1) { 7748 PetscInt n,m; 7749 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 7750 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 7751 if (m == n) { 7752 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 7753 } else { 7754 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 7755 } 7756 } else { 7757 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 7758 } 7759 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 7760 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7761 PetscFunctionReturn(0); 7762 } 7763 7764 #undef __FUNCT__ 7765 #define __FUNCT__ "MatGetInertia" 7766 /*@ 7767 MatGetInertia - Gets the inertia from a factored matrix 7768 7769 Collective on Mat 7770 7771 Input Parameter: 7772 . mat - the matrix 7773 7774 Output Parameters: 7775 + nneg - number of negative eigenvalues 7776 . nzero - number of zero eigenvalues 7777 - npos - number of positive eigenvalues 7778 7779 Level: advanced 7780 7781 Notes: Matrix must have been factored by MatCholeskyFactor() 7782 7783 7784 @*/ 7785 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 7786 { 7787 PetscErrorCode ierr; 7788 7789 PetscFunctionBegin; 7790 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7791 PetscValidType(mat,1); 7792 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 7793 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 7794 if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7795 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 7796 PetscFunctionReturn(0); 7797 } 7798 7799 /* ----------------------------------------------------------------*/ 7800 #undef __FUNCT__ 7801 #define __FUNCT__ "MatSolves" 7802 /*@C 7803 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 7804 7805 Neighbor-wise Collective on Mat and Vecs 7806 7807 Input Parameters: 7808 + mat - the factored matrix 7809 - b - the right-hand-side vectors 7810 7811 Output Parameter: 7812 . x - the result vectors 7813 7814 Notes: 7815 The vectors b and x cannot be the same. I.e., one cannot 7816 call MatSolves(A,x,x). 7817 7818 Notes: 7819 Most users should employ the simplified KSP interface for linear solvers 7820 instead of working directly with matrix algebra routines such as this. 7821 See, e.g., KSPCreate(). 7822 7823 Level: developer 7824 7825 Concepts: matrices^triangular solves 7826 7827 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 7828 @*/ 7829 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 7830 { 7831 PetscErrorCode ierr; 7832 7833 PetscFunctionBegin; 7834 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7835 PetscValidType(mat,1); 7836 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 7837 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 7838 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 7839 7840 if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7841 MatCheckPreallocated(mat,1); 7842 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 7843 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 7844 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 7845 PetscFunctionReturn(0); 7846 } 7847 7848 #undef __FUNCT__ 7849 #define __FUNCT__ "MatIsSymmetric" 7850 /*@ 7851 MatIsSymmetric - Test whether a matrix is symmetric 7852 7853 Collective on Mat 7854 7855 Input Parameter: 7856 + A - the matrix to test 7857 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 7858 7859 Output Parameters: 7860 . flg - the result 7861 7862 Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 7863 7864 Level: intermediate 7865 7866 Concepts: matrix^symmetry 7867 7868 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 7869 @*/ 7870 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 7871 { 7872 PetscErrorCode ierr; 7873 7874 PetscFunctionBegin; 7875 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7876 PetscValidPointer(flg,2); 7877 7878 if (!A->symmetric_set) { 7879 if (!A->ops->issymmetric) { 7880 const MatType mattype; 7881 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7882 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 7883 } 7884 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 7885 if (!tol) { 7886 A->symmetric_set = PETSC_TRUE; 7887 A->symmetric = *flg; 7888 if (A->symmetric) { 7889 A->structurally_symmetric_set = PETSC_TRUE; 7890 A->structurally_symmetric = PETSC_TRUE; 7891 } 7892 } 7893 } else if (A->symmetric) { 7894 *flg = PETSC_TRUE; 7895 } else if (!tol) { 7896 *flg = PETSC_FALSE; 7897 } else { 7898 if (!A->ops->issymmetric) { 7899 const MatType mattype; 7900 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7901 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 7902 } 7903 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 7904 } 7905 PetscFunctionReturn(0); 7906 } 7907 7908 #undef __FUNCT__ 7909 #define __FUNCT__ "MatIsHermitian" 7910 /*@ 7911 MatIsHermitian - Test whether a matrix is Hermitian 7912 7913 Collective on Mat 7914 7915 Input Parameter: 7916 + A - the matrix to test 7917 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 7918 7919 Output Parameters: 7920 . flg - the result 7921 7922 Level: intermediate 7923 7924 Concepts: matrix^symmetry 7925 7926 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 7927 MatIsSymmetricKnown(), MatIsSymmetric() 7928 @*/ 7929 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 7930 { 7931 PetscErrorCode ierr; 7932 7933 PetscFunctionBegin; 7934 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7935 PetscValidPointer(flg,2); 7936 7937 if (!A->hermitian_set) { 7938 if (!A->ops->ishermitian) { 7939 const MatType mattype; 7940 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7941 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 7942 } 7943 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 7944 if (!tol) { 7945 A->hermitian_set = PETSC_TRUE; 7946 A->hermitian = *flg; 7947 if (A->hermitian) { 7948 A->structurally_symmetric_set = PETSC_TRUE; 7949 A->structurally_symmetric = PETSC_TRUE; 7950 } 7951 } 7952 } else if (A->hermitian) { 7953 *flg = PETSC_TRUE; 7954 } else if (!tol) { 7955 *flg = PETSC_FALSE; 7956 } else { 7957 if (!A->ops->ishermitian) { 7958 const MatType mattype; 7959 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7960 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 7961 } 7962 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 7963 } 7964 PetscFunctionReturn(0); 7965 } 7966 7967 #undef __FUNCT__ 7968 #define __FUNCT__ "MatIsSymmetricKnown" 7969 /*@ 7970 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 7971 7972 Not Collective 7973 7974 Input Parameter: 7975 . A - the matrix to check 7976 7977 Output Parameters: 7978 + set - if the symmetric flag is set (this tells you if the next flag is valid) 7979 - flg - the result 7980 7981 Level: advanced 7982 7983 Concepts: matrix^symmetry 7984 7985 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 7986 if you want it explicitly checked 7987 7988 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 7989 @*/ 7990 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 7991 { 7992 PetscFunctionBegin; 7993 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7994 PetscValidPointer(set,2); 7995 PetscValidPointer(flg,3); 7996 if (A->symmetric_set) { 7997 *set = PETSC_TRUE; 7998 *flg = A->symmetric; 7999 } else { 8000 *set = PETSC_FALSE; 8001 } 8002 PetscFunctionReturn(0); 8003 } 8004 8005 #undef __FUNCT__ 8006 #define __FUNCT__ "MatIsHermitianKnown" 8007 /*@ 8008 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8009 8010 Not Collective 8011 8012 Input Parameter: 8013 . A - the matrix to check 8014 8015 Output Parameters: 8016 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8017 - flg - the result 8018 8019 Level: advanced 8020 8021 Concepts: matrix^symmetry 8022 8023 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8024 if you want it explicitly checked 8025 8026 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8027 @*/ 8028 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8029 { 8030 PetscFunctionBegin; 8031 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8032 PetscValidPointer(set,2); 8033 PetscValidPointer(flg,3); 8034 if (A->hermitian_set) { 8035 *set = PETSC_TRUE; 8036 *flg = A->hermitian; 8037 } else { 8038 *set = PETSC_FALSE; 8039 } 8040 PetscFunctionReturn(0); 8041 } 8042 8043 #undef __FUNCT__ 8044 #define __FUNCT__ "MatIsStructurallySymmetric" 8045 /*@ 8046 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8047 8048 Collective on Mat 8049 8050 Input Parameter: 8051 . A - the matrix to test 8052 8053 Output Parameters: 8054 . flg - the result 8055 8056 Level: intermediate 8057 8058 Concepts: matrix^symmetry 8059 8060 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8061 @*/ 8062 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8063 { 8064 PetscErrorCode ierr; 8065 8066 PetscFunctionBegin; 8067 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8068 PetscValidPointer(flg,2); 8069 if (!A->structurally_symmetric_set) { 8070 if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8071 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8072 A->structurally_symmetric_set = PETSC_TRUE; 8073 } 8074 *flg = A->structurally_symmetric; 8075 PetscFunctionReturn(0); 8076 } 8077 8078 #undef __FUNCT__ 8079 #define __FUNCT__ "MatStashGetInfo" 8080 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*); 8081 /*@ 8082 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8083 to be communicated to other processors during the MatAssemblyBegin/End() process 8084 8085 Not collective 8086 8087 Input Parameter: 8088 . vec - the vector 8089 8090 Output Parameters: 8091 + nstash - the size of the stash 8092 . reallocs - the number of additional mallocs incurred. 8093 . bnstash - the size of the block stash 8094 - breallocs - the number of additional mallocs incurred.in the block stash 8095 8096 Level: advanced 8097 8098 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8099 8100 @*/ 8101 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8102 { 8103 PetscErrorCode ierr; 8104 PetscFunctionBegin; 8105 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8106 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8107 PetscFunctionReturn(0); 8108 } 8109 8110 #undef __FUNCT__ 8111 #define __FUNCT__ "MatGetVecs" 8112 /*@C 8113 MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 8114 parallel layout 8115 8116 Collective on Mat 8117 8118 Input Parameter: 8119 . mat - the matrix 8120 8121 Output Parameter: 8122 + right - (optional) vector that the matrix can be multiplied against 8123 - left - (optional) vector that the matrix vector product can be stored in 8124 8125 Level: advanced 8126 8127 .seealso: MatCreate() 8128 @*/ 8129 PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left) 8130 { 8131 PetscErrorCode ierr; 8132 8133 PetscFunctionBegin; 8134 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8135 PetscValidType(mat,1); 8136 MatCheckPreallocated(mat,1); 8137 if (mat->ops->getvecs) { 8138 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8139 } else { 8140 PetscMPIInt size; 8141 ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr); 8142 if (right) { 8143 ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr); 8144 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8145 ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr); 8146 ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr); 8147 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8148 } 8149 if (left) { 8150 ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr); 8151 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8152 ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr); 8153 ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr); 8154 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8155 } 8156 } 8157 PetscFunctionReturn(0); 8158 } 8159 8160 #undef __FUNCT__ 8161 #define __FUNCT__ "MatFactorInfoInitialize" 8162 /*@C 8163 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8164 with default values. 8165 8166 Not Collective 8167 8168 Input Parameters: 8169 . info - the MatFactorInfo data structure 8170 8171 8172 Notes: The solvers are generally used through the KSP and PC objects, for example 8173 PCLU, PCILU, PCCHOLESKY, PCICC 8174 8175 Level: developer 8176 8177 .seealso: MatFactorInfo 8178 8179 Developer Note: fortran interface is not autogenerated as the f90 8180 interface defintion cannot be generated correctly [due to MatFactorInfo] 8181 8182 @*/ 8183 8184 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8185 { 8186 PetscErrorCode ierr; 8187 8188 PetscFunctionBegin; 8189 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8190 PetscFunctionReturn(0); 8191 } 8192 8193 #undef __FUNCT__ 8194 #define __FUNCT__ "MatPtAP" 8195 /*@ 8196 MatPtAP - Creates the matrix product C = P^T * A * P 8197 8198 Neighbor-wise Collective on Mat 8199 8200 Input Parameters: 8201 + A - the matrix 8202 . P - the projection matrix 8203 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8204 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)) 8205 8206 Output Parameters: 8207 . C - the product matrix 8208 8209 Notes: 8210 C will be created and must be destroyed by the user with MatDestroy(). 8211 8212 This routine is currently only implemented for pairs of AIJ matrices and classes 8213 which inherit from AIJ. 8214 8215 Level: intermediate 8216 8217 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 8218 @*/ 8219 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 8220 { 8221 PetscErrorCode ierr; 8222 8223 PetscFunctionBegin; 8224 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8225 PetscValidType(A,1); 8226 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8227 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8228 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8229 PetscValidType(P,2); 8230 MatCheckPreallocated(P,2); 8231 if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8232 if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8233 PetscValidPointer(C,3); 8234 if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 8235 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8236 MatCheckPreallocated(A,1); 8237 8238 if (!A->ops->ptap) { 8239 const MatType mattype; 8240 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8241 SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support PtAP",mattype); 8242 } 8243 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8244 ierr = (*A->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 8245 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8246 PetscFunctionReturn(0); 8247 } 8248 8249 #undef __FUNCT__ 8250 #define __FUNCT__ "MatPtAPNumeric" 8251 /*@ 8252 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 8253 8254 Neighbor-wise Collective on Mat 8255 8256 Input Parameters: 8257 + A - the matrix 8258 - P - the projection matrix 8259 8260 Output Parameters: 8261 . C - the product matrix 8262 8263 Notes: 8264 C must have been created by calling MatPtAPSymbolic and must be destroyed by 8265 the user using MatDeatroy(). 8266 8267 This routine is currently only implemented for pairs of AIJ matrices and classes 8268 which inherit from AIJ. C will be of type MATAIJ. 8269 8270 Level: intermediate 8271 8272 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 8273 @*/ 8274 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 8275 { 8276 PetscErrorCode ierr; 8277 8278 PetscFunctionBegin; 8279 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8280 PetscValidType(A,1); 8281 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8282 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8283 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8284 PetscValidType(P,2); 8285 MatCheckPreallocated(P,2); 8286 if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8287 if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8288 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8289 PetscValidType(C,3); 8290 MatCheckPreallocated(C,3); 8291 if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8292 if (P->cmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N); 8293 if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 8294 if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 8295 if (P->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N); 8296 MatCheckPreallocated(A,1); 8297 8298 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8299 ierr = (*A->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 8300 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8301 PetscFunctionReturn(0); 8302 } 8303 8304 #undef __FUNCT__ 8305 #define __FUNCT__ "MatPtAPSymbolic" 8306 /*@ 8307 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 8308 8309 Neighbor-wise Collective on Mat 8310 8311 Input Parameters: 8312 + A - the matrix 8313 - P - the projection matrix 8314 8315 Output Parameters: 8316 . C - the (i,j) structure of the product matrix 8317 8318 Notes: 8319 C will be created and must be destroyed by the user with MatDestroy(). 8320 8321 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 8322 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 8323 this (i,j) structure by calling MatPtAPNumeric(). 8324 8325 Level: intermediate 8326 8327 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 8328 @*/ 8329 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 8330 { 8331 PetscErrorCode ierr; 8332 8333 PetscFunctionBegin; 8334 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8335 PetscValidType(A,1); 8336 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8337 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8338 if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8339 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8340 PetscValidType(P,2); 8341 MatCheckPreallocated(P,2); 8342 if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8343 if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8344 PetscValidPointer(C,3); 8345 8346 if (P->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 8347 if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 8348 MatCheckPreallocated(A,1); 8349 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 8350 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 8351 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 8352 8353 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 8354 8355 PetscFunctionReturn(0); 8356 } 8357 8358 #undef __FUNCT__ 8359 #define __FUNCT__ "MatRARt" 8360 /*@ 8361 MatRARt - Creates the matrix product C = R * A * R^T 8362 8363 Neighbor-wise Collective on Mat 8364 8365 Input Parameters: 8366 + A - the matrix 8367 . R - the projection matrix 8368 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8369 - fill - expected fill as ratio of nnz(C)/nnz(A) 8370 8371 Output Parameters: 8372 . C - the product matrix 8373 8374 Notes: 8375 C will be created and must be destroyed by the user with MatDestroy(). 8376 8377 This routine is currently only implemented for pairs of AIJ matrices and classes 8378 which inherit from AIJ. 8379 8380 Level: intermediate 8381 8382 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 8383 @*/ 8384 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 8385 { 8386 PetscErrorCode ierr; 8387 8388 PetscFunctionBegin; 8389 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8390 PetscValidType(A,1); 8391 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8392 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8393 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8394 PetscValidType(R,2); 8395 MatCheckPreallocated(R,2); 8396 if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8397 if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8398 PetscValidPointer(C,3); 8399 if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)R)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 8400 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8401 MatCheckPreallocated(A,1); 8402 8403 if (!A->ops->rart) { 8404 const MatType mattype; 8405 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8406 SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype); 8407 } 8408 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 8409 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 8410 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 8411 PetscFunctionReturn(0); 8412 } 8413 8414 #undef __FUNCT__ 8415 #define __FUNCT__ "MatRARtNumeric" 8416 /*@ 8417 MatRARtNumeric - Computes the matrix product C = R * A * R^T 8418 8419 Neighbor-wise Collective on Mat 8420 8421 Input Parameters: 8422 + A - the matrix 8423 - R - the projection matrix 8424 8425 Output Parameters: 8426 . C - the product matrix 8427 8428 Notes: 8429 C must have been created by calling MatRARtSymbolic and must be destroyed by 8430 the user using MatDeatroy(). 8431 8432 This routine is currently only implemented for pairs of AIJ matrices and classes 8433 which inherit from AIJ. C will be of type MATAIJ. 8434 8435 Level: intermediate 8436 8437 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 8438 @*/ 8439 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 8440 { 8441 PetscErrorCode ierr; 8442 8443 PetscFunctionBegin; 8444 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8445 PetscValidType(A,1); 8446 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8447 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8448 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8449 PetscValidType(R,2); 8450 MatCheckPreallocated(R,2); 8451 if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8452 if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8453 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8454 PetscValidType(C,3); 8455 MatCheckPreallocated(C,3); 8456 if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8457 if (R->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N); 8458 if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 8459 if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 8460 if (R->rmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N); 8461 MatCheckPreallocated(A,1); 8462 8463 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 8464 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 8465 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 8466 PetscFunctionReturn(0); 8467 } 8468 8469 #undef __FUNCT__ 8470 #define __FUNCT__ "MatRARtSymbolic" 8471 /*@ 8472 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 8473 8474 Neighbor-wise Collective on Mat 8475 8476 Input Parameters: 8477 + A - the matrix 8478 - R - the projection matrix 8479 8480 Output Parameters: 8481 . C - the (i,j) structure of the product matrix 8482 8483 Notes: 8484 C will be created and must be destroyed by the user with MatDestroy(). 8485 8486 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 8487 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 8488 this (i,j) structure by calling MatRARtNumeric(). 8489 8490 Level: intermediate 8491 8492 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 8493 @*/ 8494 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 8495 { 8496 PetscErrorCode ierr; 8497 8498 PetscFunctionBegin; 8499 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8500 PetscValidType(A,1); 8501 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8502 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8503 if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8504 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8505 PetscValidType(R,2); 8506 MatCheckPreallocated(R,2); 8507 if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8508 if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8509 PetscValidPointer(C,3); 8510 8511 if (R->cmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 8512 if (A->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 8513 MatCheckPreallocated(A,1); 8514 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 8515 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 8516 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 8517 8518 ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); 8519 PetscFunctionReturn(0); 8520 } 8521 8522 extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...); 8523 8524 #undef __FUNCT__ 8525 #define __FUNCT__ "MatMatMult" 8526 /*@ 8527 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 8528 8529 Neighbor-wise Collective on Mat 8530 8531 Input Parameters: 8532 + A - the left matrix 8533 . B - the right matrix 8534 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8535 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 8536 if the result is a dense matrix this is irrelevent 8537 8538 Output Parameters: 8539 . C - the product matrix 8540 8541 Notes: 8542 Unless scall is MAT_REUSE_MATRIX C will be created. 8543 8544 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8545 8546 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8547 actually needed. 8548 8549 If you have many matrices with the same non-zero structure to multiply, you 8550 should either 8551 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 8552 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 8553 8554 Level: intermediate 8555 8556 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 8557 @*/ 8558 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8559 { 8560 PetscErrorCode ierr; 8561 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8562 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8563 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL; 8564 8565 PetscFunctionBegin; 8566 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8567 PetscValidType(A,1); 8568 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8569 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8570 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8571 PetscValidType(B,2); 8572 MatCheckPreallocated(B,2); 8573 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8574 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8575 PetscValidPointer(C,3); 8576 if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 8577 if (scall == MAT_REUSE_MATRIX){ 8578 PetscValidPointer(*C,5); 8579 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 8580 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8581 ierr = (*(*C)->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr); 8582 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8583 } 8584 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8585 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8586 MatCheckPreallocated(A,1); 8587 8588 fA = A->ops->matmult; 8589 fB = B->ops->matmult; 8590 if (fB == fA) { 8591 if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 8592 mult = fB; 8593 } else { 8594 /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */ 8595 char multname[256]; 8596 ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr); 8597 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8598 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 8599 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8600 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 8601 ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr); 8602 if(!mult){ 8603 /* dual dispatch using MatQueryOp */ 8604 ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr); 8605 if (!mult) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 8606 } 8607 } 8608 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8609 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 8610 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8611 PetscFunctionReturn(0); 8612 } 8613 8614 #undef __FUNCT__ 8615 #define __FUNCT__ "MatMatMultSymbolic" 8616 /*@ 8617 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 8618 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 8619 8620 Neighbor-wise Collective on Mat 8621 8622 Input Parameters: 8623 + A - the left matrix 8624 . B - the right matrix 8625 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 8626 if C is a dense matrix this is irrelevent 8627 8628 Output Parameters: 8629 . C - the product matrix 8630 8631 Notes: 8632 Unless scall is MAT_REUSE_MATRIX C will be created. 8633 8634 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8635 actually needed. 8636 8637 This routine is currently implemented for 8638 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 8639 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 8640 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 8641 8642 Level: intermediate 8643 8644 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 8645 We should incorporate them into PETSc. 8646 8647 .seealso: MatMatMult(), MatMatMultNumeric() 8648 @*/ 8649 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 8650 { 8651 PetscErrorCode ierr; 8652 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *); 8653 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *); 8654 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL; 8655 8656 PetscFunctionBegin; 8657 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8658 PetscValidType(A,1); 8659 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8660 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8661 8662 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8663 PetscValidType(B,2); 8664 MatCheckPreallocated(B,2); 8665 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8666 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8667 PetscValidPointer(C,3); 8668 8669 if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 8670 if (fill == PETSC_DEFAULT) fill = 2.0; 8671 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8672 MatCheckPreallocated(A,1); 8673 8674 Asymbolic = A->ops->matmultsymbolic; 8675 Bsymbolic = B->ops->matmultsymbolic; 8676 if (Asymbolic == Bsymbolic){ 8677 if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 8678 symbolic = Bsymbolic; 8679 } else { /* dispatch based on the type of A and B */ 8680 char symbolicname[256]; 8681 ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr); 8682 ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8683 ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr); 8684 ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8685 ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr); 8686 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr); 8687 if (!symbolic) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 8688 } 8689 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8690 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 8691 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8692 PetscFunctionReturn(0); 8693 } 8694 8695 #undef __FUNCT__ 8696 #define __FUNCT__ "MatMatMultNumeric" 8697 /*@ 8698 MatMatMultNumeric - Performs the numeric matrix-matrix product. 8699 Call this routine after first calling MatMatMultSymbolic(). 8700 8701 Neighbor-wise Collective on Mat 8702 8703 Input Parameters: 8704 + A - the left matrix 8705 - B - the right matrix 8706 8707 Output Parameters: 8708 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 8709 8710 Notes: 8711 C must have been created with MatMatMultSymbolic(). 8712 8713 This routine is currently implemented for 8714 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 8715 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 8716 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 8717 8718 Level: intermediate 8719 8720 .seealso: MatMatMult(), MatMatMultSymbolic() 8721 @*/ 8722 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 8723 { 8724 PetscErrorCode ierr; 8725 PetscErrorCode (*Anumeric)(Mat,Mat,Mat); 8726 PetscErrorCode (*Bnumeric)(Mat,Mat,Mat); 8727 PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL; 8728 8729 PetscFunctionBegin; 8730 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8731 PetscValidType(A,1); 8732 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8733 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8734 8735 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8736 PetscValidType(B,2); 8737 MatCheckPreallocated(B,2); 8738 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8739 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8740 8741 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8742 PetscValidType(C,3); 8743 MatCheckPreallocated(C,3); 8744 if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8745 if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8746 8747 if (B->cmap->N!=C->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,C->cmap->N); 8748 if (B->rmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 8749 if (A->rmap->N!=C->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",A->rmap->N,C->rmap->N); 8750 MatCheckPreallocated(A,1); 8751 8752 Anumeric = A->ops->matmultnumeric; 8753 Bnumeric = B->ops->matmultnumeric; 8754 if (Anumeric == Bnumeric){ 8755 if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name); 8756 numeric = Bnumeric; 8757 } else { 8758 char numericname[256]; 8759 ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr); 8760 ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8761 ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr); 8762 ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8763 ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr); 8764 ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr); 8765 if (!numeric) 8766 SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatMultNumeric requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 8767 } 8768 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8769 ierr = (*numeric)(A,B,C);CHKERRQ(ierr); 8770 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8771 PetscFunctionReturn(0); 8772 } 8773 8774 #undef __FUNCT__ 8775 #define __FUNCT__ "MatMatTransposeMult" 8776 /*@ 8777 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 8778 8779 Neighbor-wise Collective on Mat 8780 8781 Input Parameters: 8782 + A - the left matrix 8783 . B - the right matrix 8784 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8785 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 8786 8787 Output Parameters: 8788 . C - the product matrix 8789 8790 Notes: 8791 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 8792 8793 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8794 8795 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8796 actually needed. 8797 8798 This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ. 8799 8800 Level: intermediate 8801 8802 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 8803 @*/ 8804 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8805 { 8806 PetscErrorCode ierr; 8807 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8808 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8809 8810 PetscFunctionBegin; 8811 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8812 PetscValidType(A,1); 8813 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8814 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8815 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8816 PetscValidType(B,2); 8817 MatCheckPreallocated(B,2); 8818 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8819 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8820 PetscValidPointer(C,3); 8821 if (B->cmap->N!=A->cmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N); 8822 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8823 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8824 MatCheckPreallocated(A,1); 8825 8826 fA = A->ops->mattransposemult; 8827 if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 8828 fB = B->ops->mattransposemult; 8829 if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 8830 if (fB!=fA) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 8831 8832 if (scall == MAT_INITIAL_MATRIX){ 8833 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8834 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 8835 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8836 } 8837 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 8838 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 8839 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 8840 PetscFunctionReturn(0); 8841 } 8842 8843 #undef __FUNCT__ 8844 #define __FUNCT__ "MatTransposeMatMult" 8845 /*@ 8846 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 8847 8848 Neighbor-wise Collective on Mat 8849 8850 Input Parameters: 8851 + A - the left matrix 8852 . B - the right matrix 8853 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8854 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 8855 8856 Output Parameters: 8857 . C - the product matrix 8858 8859 Notes: 8860 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 8861 8862 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8863 8864 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8865 actually needed. 8866 8867 This routine is currently only implemented for pairs of SeqAIJ matrices and pairs of SeqDense matrices and classes 8868 which inherit from SeqAIJ. C will be of type MATSEQAIJ. 8869 8870 Level: intermediate 8871 8872 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 8873 @*/ 8874 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8875 { 8876 PetscErrorCode ierr; 8877 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8878 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8879 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*); 8880 8881 PetscFunctionBegin; 8882 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8883 PetscValidType(A,1); 8884 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8885 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8886 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8887 PetscValidType(B,2); 8888 MatCheckPreallocated(B,2); 8889 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8890 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8891 PetscValidPointer(C,3); 8892 if (B->rmap->N!=A->rmap->N) SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N); 8893 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8894 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8895 MatCheckPreallocated(A,1); 8896 8897 fA = A->ops->transposematmult; 8898 if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 8899 fB = B->ops->transposematmult; 8900 if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name); 8901 if (fB==fA) { 8902 transposematmult = fA; 8903 } 8904 else { 8905 /* dual dispatch using MatQueryOp */ 8906 ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr); 8907 if(!transposematmult) 8908 SETERRQ2(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 8909 } 8910 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 8911 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 8912 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 8913 PetscFunctionReturn(0); 8914 } 8915 8916 #undef __FUNCT__ 8917 #define __FUNCT__ "MatGetRedundantMatrix" 8918 /*@C 8919 MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 8920 8921 Collective on Mat 8922 8923 Input Parameters: 8924 + mat - the matrix 8925 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 8926 . subcomm - MPI communicator split from the communicator where mat resides in 8927 . mlocal_red - number of local rows of the redundant matrix 8928 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8929 8930 Output Parameter: 8931 . matredundant - redundant matrix 8932 8933 Notes: 8934 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 8935 original matrix has not changed from that last call to MatGetRedundantMatrix(). 8936 8937 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 8938 calling it. 8939 8940 Only MPIAIJ matrix is supported. 8941 8942 Level: advanced 8943 8944 Concepts: subcommunicator 8945 Concepts: duplicate matrix 8946 8947 .seealso: MatDestroy() 8948 @*/ 8949 PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant) 8950 { 8951 PetscErrorCode ierr; 8952 8953 PetscFunctionBegin; 8954 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8955 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 8956 PetscValidPointer(*matredundant,6); 8957 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6); 8958 } 8959 if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8960 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8961 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8962 MatCheckPreallocated(mat,1); 8963 8964 ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr); 8965 ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr); 8966 ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr); 8967 PetscFunctionReturn(0); 8968 } 8969 8970 #undef __FUNCT__ 8971 #define __FUNCT__ "MatGetMultiProcBlock" 8972 /*@C 8973 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 8974 a given 'mat' object. Each submatrix can span multiple procs. 8975 8976 Collective on Mat 8977 8978 Input Parameters: 8979 + mat - the matrix 8980 . subcomm - the subcommunicator obtained by com_split(comm) 8981 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8982 8983 Output Parameter: 8984 . subMat - 'parallel submatrices each spans a given subcomm 8985 8986 Notes: 8987 The submatrix partition across processors is dicated by 'subComm' a 8988 communicator obtained by com_split(comm). The comm_split 8989 is not restriced to be grouped with consequitive original ranks. 8990 8991 Due the comm_split() usage, the parallel layout of the submatrices 8992 map directly to the layout of the original matrix [wrt the local 8993 row,col partitioning]. So the original 'DiagonalMat' naturally maps 8994 into the 'DiagonalMat' of the subMat, hence it is used directly from 8995 the subMat. However the offDiagMat looses some columns - and this is 8996 reconstructed with MatSetValues() 8997 8998 Level: advanced 8999 9000 Concepts: subcommunicator 9001 Concepts: submatrices 9002 9003 .seealso: MatGetSubMatrices() 9004 @*/ 9005 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat) 9006 { 9007 PetscErrorCode ierr; 9008 PetscMPIInt commsize,subCommSize; 9009 9010 PetscFunctionBegin; 9011 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr); 9012 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 9013 if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 9014 9015 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9016 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 9017 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9018 PetscFunctionReturn(0); 9019 } 9020 9021 #undef __FUNCT__ 9022 #define __FUNCT__ "MatGetLocalSubMatrix" 9023 /*@ 9024 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9025 9026 Not Collective 9027 9028 Input Arguments: 9029 mat - matrix to extract local submatrix from 9030 isrow - local row indices for submatrix 9031 iscol - local column indices for submatrix 9032 9033 Output Arguments: 9034 submat - the submatrix 9035 9036 Level: intermediate 9037 9038 Notes: 9039 The submat should be returned with MatRestoreLocalSubMatrix(). 9040 9041 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 9042 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 9043 9044 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 9045 MatSetValuesBlockedLocal() will also be implemented. 9046 9047 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef() 9048 @*/ 9049 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9050 { 9051 PetscErrorCode ierr; 9052 9053 PetscFunctionBegin; 9054 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9055 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9056 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9057 PetscCheckSameComm(isrow,2,iscol,3); 9058 PetscValidPointer(submat,4); 9059 9060 if (mat->ops->getlocalsubmatrix) { 9061 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9062 } else { 9063 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 9064 } 9065 PetscFunctionReturn(0); 9066 } 9067 9068 #undef __FUNCT__ 9069 #define __FUNCT__ "MatRestoreLocalSubMatrix" 9070 /*@ 9071 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 9072 9073 Not Collective 9074 9075 Input Arguments: 9076 mat - matrix to extract local submatrix from 9077 isrow - local row indices for submatrix 9078 iscol - local column indices for submatrix 9079 submat - the submatrix 9080 9081 Level: intermediate 9082 9083 .seealso: MatGetLocalSubMatrix() 9084 @*/ 9085 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9086 { 9087 PetscErrorCode ierr; 9088 9089 PetscFunctionBegin; 9090 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9091 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9092 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9093 PetscCheckSameComm(isrow,2,iscol,3); 9094 PetscValidPointer(submat,4); 9095 if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);} 9096 9097 if (mat->ops->restorelocalsubmatrix) { 9098 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9099 } else { 9100 ierr = MatDestroy(submat);CHKERRQ(ierr); 9101 } 9102 *submat = PETSC_NULL; 9103 PetscFunctionReturn(0); 9104 } 9105 9106 /* --------------------------------------------------------*/ 9107 #undef __FUNCT__ 9108 #define __FUNCT__ "MatFindZeroDiagonals" 9109 /*@ 9110 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix 9111 9112 Collective on Mat 9113 9114 Input Parameter: 9115 . mat - the matrix 9116 9117 Output Parameter: 9118 . is - if any rows have zero diagonals this contains the list of them 9119 9120 Level: developer 9121 9122 Concepts: matrix-vector product 9123 9124 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 9125 @*/ 9126 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 9127 { 9128 PetscErrorCode ierr; 9129 9130 PetscFunctionBegin; 9131 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9132 PetscValidType(mat,1); 9133 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9134 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9135 9136 if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined"); 9137 ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr); 9138 PetscFunctionReturn(0); 9139 } 9140 9141 #undef __FUNCT__ 9142 #define __FUNCT__ "MatInvertBlockDiagonal" 9143 /*@C 9144 MatInvertBlockDiagonal - Inverts the block diagonal entries. 9145 9146 Collective on Mat 9147 9148 Input Parameters: 9149 . mat - the matrix 9150 9151 Output Parameters: 9152 . values - the block inverses in column major order (FORTRAN-like) 9153 9154 Note: 9155 This routine is not available from Fortran. 9156 9157 Level: advanced 9158 @*/ 9159 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 9160 { 9161 PetscErrorCode ierr; 9162 9163 PetscFunctionBegin; 9164 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9165 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9166 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9167 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 9168 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 9169 PetscFunctionReturn(0); 9170 } 9171 9172 #undef __FUNCT__ 9173 #define __FUNCT__ "MatTransposeColoringDestroy" 9174 /*@C 9175 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 9176 via MatTransposeColoringCreate(). 9177 9178 Collective on MatTransposeColoring 9179 9180 Input Parameter: 9181 . c - coloring context 9182 9183 Level: intermediate 9184 9185 .seealso: MatTransposeColoringCreate() 9186 @*/ 9187 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 9188 { 9189 PetscErrorCode ierr; 9190 MatTransposeColoring matcolor=*c; 9191 9192 PetscFunctionBegin; 9193 if (!matcolor) PetscFunctionReturn(0); 9194 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 9195 9196 ierr = PetscFree(matcolor->ncolumns);CHKERRQ(ierr); 9197 ierr = PetscFree(matcolor->nrows);CHKERRQ(ierr); 9198 ierr = PetscFree(matcolor->colorforrow);CHKERRQ(ierr); 9199 ierr = PetscFree2(matcolor->rows,matcolor->columnsforspidx);CHKERRQ(ierr); 9200 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 9201 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 9202 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 9203 PetscFunctionReturn(0); 9204 } 9205 9206 #undef __FUNCT__ 9207 #define __FUNCT__ "MatTransColoringApplySpToDen" 9208 /*@C 9209 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 9210 a MatTransposeColoring context has been created, computes a dense B^T by Apply 9211 MatTransposeColoring to sparse B. 9212 9213 Collective on MatTransposeColoring 9214 9215 Input Parameters: 9216 + B - sparse matrix B 9217 . Btdense - symbolic dense matrix B^T 9218 - coloring - coloring context created with MatTransposeColoringCreate() 9219 9220 Output Parameter: 9221 . Btdense - dense matrix B^T 9222 9223 Options Database Keys: 9224 + -mat_transpose_coloring_view - Activates basic viewing or coloring 9225 . -mat_transpose_coloring_view_draw - Activates drawing of coloring 9226 - -mat_transpose_coloring_view_info - Activates viewing of coloring info 9227 9228 Level: intermediate 9229 9230 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy() 9231 9232 .keywords: coloring 9233 @*/ 9234 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 9235 { 9236 PetscErrorCode ierr; 9237 9238 PetscFunctionBegin; 9239 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 9240 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 9241 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 9242 9243 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 9244 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 9245 PetscFunctionReturn(0); 9246 } 9247 9248 #undef __FUNCT__ 9249 #define __FUNCT__ "MatTransColoringApplyDenToSp" 9250 /*@C 9251 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 9252 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 9253 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 9254 Csp from Cden. 9255 9256 Collective on MatTransposeColoring 9257 9258 Input Parameters: 9259 + coloring - coloring context created with MatTransposeColoringCreate() 9260 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 9261 9262 Output Parameter: 9263 . Csp - sparse matrix 9264 9265 Options Database Keys: 9266 + -mat_multtranspose_coloring_view - Activates basic viewing or coloring 9267 . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring 9268 - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info 9269 9270 Level: intermediate 9271 9272 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 9273 9274 .keywords: coloring 9275 @*/ 9276 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 9277 { 9278 PetscErrorCode ierr; 9279 9280 PetscFunctionBegin; 9281 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 9282 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 9283 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 9284 9285 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 9286 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 9287 PetscFunctionReturn(0); 9288 } 9289 9290 #undef __FUNCT__ 9291 #define __FUNCT__ "MatTransposeColoringCreate" 9292 /*@C 9293 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 9294 9295 Collective on Mat 9296 9297 Input Parameters: 9298 + mat - the matrix product C 9299 - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring() 9300 9301 Output Parameter: 9302 . color - the new coloring context 9303 9304 Level: intermediate 9305 9306 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(), 9307 MatTransColoringApplyDen()ToSp, MatTransposeColoringView(), 9308 @*/ 9309 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 9310 { 9311 MatTransposeColoring c; 9312 MPI_Comm comm; 9313 PetscErrorCode ierr; 9314 9315 PetscFunctionBegin; 9316 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 9317 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9318 ierr = PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,0,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);CHKERRQ(ierr); 9319 9320 c->ctype = iscoloring->ctype; 9321 if (mat->ops->transposecoloringcreate) { 9322 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 9323 } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type"); 9324 9325 *color = c; 9326 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 9327 PetscFunctionReturn(0); 9328 } 9329