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