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 4815 PetscFunctionBegin; 4816 if (incall) PetscFunctionReturn(0); 4817 incall = PETSC_TRUE; 4818 ierr = PetscOptionsGetViewer(((PetscObject)mat)->comm,((PetscObject)mat)->prefix,optionname,&viewer,&flg);CHKERRQ(ierr); 4819 if (flg) { 4820 ierr = MatView(mat,viewer);CHKERRQ(ierr); 4821 ierr = PetscOptionsRestoreViewer(viewer);CHKERRQ(ierr); 4822 } 4823 incall = PETSC_FALSE; 4824 PetscFunctionReturn(0); 4825 } 4826 4827 #undef __FUNCT__ 4828 #define __FUNCT__ "MatAssemblyEnd" 4829 /*@ 4830 MatAssemblyEnd - Completes assembling the matrix. This routine should 4831 be called after MatAssemblyBegin(). 4832 4833 Collective on Mat 4834 4835 Input Parameters: 4836 + mat - the matrix 4837 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 4838 4839 Options Database Keys: 4840 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 4841 . -mat_view ::ascii_info_detail - Prints more detailed info 4842 . -mat_view - Prints matrix in ASCII format 4843 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 4844 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 4845 . -display <name> - Sets display name (default is host) 4846 . -draw_pause <sec> - Sets number of seconds to pause after display 4847 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>) 4848 . -viewer_socket_machine <machine> 4849 . -viewer_socket_port <port> 4850 . -mat_view binary - save matrix to file in binary format 4851 - -viewer_binary_filename <name> 4852 4853 Notes: 4854 MatSetValues() generally caches the values. The matrix is ready to 4855 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 4856 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 4857 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 4858 using the matrix. 4859 4860 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 4861 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 4862 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 4863 4864 Level: beginner 4865 4866 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 4867 @*/ 4868 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 4869 { 4870 PetscErrorCode ierr; 4871 static PetscInt inassm = 0; 4872 PetscBool flg = PETSC_FALSE; 4873 4874 PetscFunctionBegin; 4875 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4876 PetscValidType(mat,1); 4877 4878 inassm++; 4879 MatAssemblyEnd_InUse++; 4880 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 4881 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 4882 if (mat->ops->assemblyend) { 4883 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 4884 } 4885 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 4886 } else { 4887 if (mat->ops->assemblyend) { 4888 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 4889 } 4890 } 4891 4892 /* Flush assembly is not a true assembly */ 4893 if (type != MAT_FLUSH_ASSEMBLY) { 4894 mat->assembled = PETSC_TRUE; mat->num_ass++; 4895 } 4896 mat->insertmode = NOT_SET_VALUES; 4897 MatAssemblyEnd_InUse--; 4898 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 4899 if (!mat->symmetric_eternal) { 4900 mat->symmetric_set = PETSC_FALSE; 4901 mat->hermitian_set = PETSC_FALSE; 4902 mat->structurally_symmetric_set = PETSC_FALSE; 4903 } 4904 #if defined(PETSC_HAVE_CUSP) 4905 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 4906 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 4907 } 4908 #endif 4909 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 4910 ierr = MatViewFromOptions(mat,"-mat_view");CHKERRQ(ierr); 4911 ierr = PetscOptionsHasName(((PetscObject)mat)->prefix,"-mat_is_symmetric",&flg);CHKERRQ(ierr); 4912 if (flg) { 4913 PetscReal tol = 0.0; 4914 ierr = PetscOptionsGetReal(((PetscObject)mat)->prefix,"-mat_is_symmetric",&tol,PETSC_NULL);CHKERRQ(ierr); 4915 ierr = MatIsSymmetric(mat,tol,&flg);CHKERRQ(ierr); 4916 if (flg) { 4917 ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is symmetric (tolerance %G)\n",tol);CHKERRQ(ierr); 4918 } else { 4919 ierr = PetscPrintf(((PetscObject)mat)->comm,"Matrix is not symmetric (tolerance %G)\n",tol);CHKERRQ(ierr); 4920 } 4921 } 4922 if (mat->nullsp) { 4923 ierr = PetscOptionsGetBool(PETSC_NULL,"-mat_null_space_test",&flg,PETSC_NULL);CHKERRQ(ierr); 4924 if (flg) { 4925 ierr = MatNullSpaceTest(mat->nullsp,mat,PETSC_NULL);CHKERRQ(ierr); 4926 } 4927 } 4928 } 4929 inassm--; 4930 PetscFunctionReturn(0); 4931 } 4932 4933 #undef __FUNCT__ 4934 #define __FUNCT__ "MatSetOption" 4935 /*@ 4936 MatSetOption - Sets a parameter option for a matrix. Some options 4937 may be specific to certain storage formats. Some options 4938 determine how values will be inserted (or added). Sorted, 4939 row-oriented input will generally assemble the fastest. The default 4940 is row-oriented. 4941 4942 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 4943 4944 Input Parameters: 4945 + mat - the matrix 4946 . option - the option, one of those listed below (and possibly others), 4947 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 4948 4949 Options Describing Matrix Structure: 4950 + MAT_SPD - symmetric positive definite 4951 - MAT_SYMMETRIC - symmetric in terms of both structure and value 4952 . MAT_HERMITIAN - transpose is the complex conjugation 4953 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 4954 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 4955 you set to be kept with all future use of the matrix 4956 including after MatAssemblyBegin/End() which could 4957 potentially change the symmetry structure, i.e. you 4958 KNOW the matrix will ALWAYS have the property you set. 4959 4960 4961 Options For Use with MatSetValues(): 4962 Insert a logically dense subblock, which can be 4963 . MAT_ROW_ORIENTED - row-oriented (default) 4964 4965 Note these options reflect the data you pass in with MatSetValues(); it has 4966 nothing to do with how the data is stored internally in the matrix 4967 data structure. 4968 4969 When (re)assembling a matrix, we can restrict the input for 4970 efficiency/debugging purposes. These options include 4971 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be 4972 allowed if they generate a new nonzero 4973 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 4974 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 4975 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 4976 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 4977 + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 4978 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 4979 performance for very large process counts. 4980 4981 Notes: 4982 Some options are relevant only for particular matrix types and 4983 are thus ignored by others. Other options are not supported by 4984 certain matrix types and will generate an error message if set. 4985 4986 If using a Fortran 77 module to compute a matrix, one may need to 4987 use the column-oriented option (or convert to the row-oriented 4988 format). 4989 4990 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 4991 that would generate a new entry in the nonzero structure is instead 4992 ignored. Thus, if memory has not alredy been allocated for this particular 4993 data, then the insertion is ignored. For dense matrices, in which 4994 the entire array is allocated, no entries are ever ignored. 4995 Set after the first MatAssemblyEnd() 4996 4997 MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion 4998 that would generate a new entry in the nonzero structure instead produces 4999 an error. (Currently supported for AIJ and BAIJ formats only.) 5000 This is a useful flag when using SAME_NONZERO_PATTERN in calling 5001 KSPSetOperators() to ensure that the nonzero pattern truely does 5002 remain unchanged. Set after the first MatAssemblyEnd() 5003 5004 MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion 5005 that would generate a new entry that has not been preallocated will 5006 instead produce an error. (Currently supported for AIJ and BAIJ formats 5007 only.) This is a useful flag when debugging matrix memory preallocation. 5008 5009 MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for 5010 other processors should be dropped, rather than stashed. 5011 This is useful if you know that the "owning" processor is also 5012 always generating the correct matrix entries, so that PETSc need 5013 not transfer duplicate entries generated on another processor. 5014 5015 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5016 searches during matrix assembly. When this flag is set, the hash table 5017 is created during the first Matrix Assembly. This hash table is 5018 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5019 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5020 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5021 supported by MATMPIBAIJ format only. 5022 5023 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5024 are kept in the nonzero structure 5025 5026 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5027 a zero location in the matrix 5028 5029 MAT_USE_INODES - indicates using inode version of the code - works with AIJ and 5030 ROWBS matrix types 5031 5032 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5033 zero row routines and thus improves performance for very large process counts. 5034 5035 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5036 part of the matrix (since they should match the upper triangular part). 5037 5038 Notes: Can only be called after MatSetSizes() and MatSetType() have been set. 5039 5040 Level: intermediate 5041 5042 Concepts: matrices^setting options 5043 5044 .seealso: MatOption, Mat 5045 5046 @*/ 5047 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5048 { 5049 PetscErrorCode ierr; 5050 5051 PetscFunctionBegin; 5052 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5053 PetscValidType(mat,1); 5054 if (op > 0) PetscValidLogicalCollectiveEnum(mat,op,2); 5055 PetscValidLogicalCollectiveBool(mat,flg,3); 5056 5057 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); 5058 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()"); 5059 5060 switch (op) { 5061 case MAT_NO_OFF_PROC_ENTRIES: 5062 mat->nooffprocentries = flg; 5063 PetscFunctionReturn(0); 5064 break; 5065 case MAT_NO_OFF_PROC_ZERO_ROWS: 5066 mat->nooffproczerorows = flg; 5067 PetscFunctionReturn(0); 5068 break; 5069 case MAT_SPD: 5070 mat->spd_set = PETSC_TRUE; 5071 mat->spd = flg; 5072 if (flg) { 5073 mat->symmetric = PETSC_TRUE; 5074 mat->structurally_symmetric = PETSC_TRUE; 5075 mat->symmetric_set = PETSC_TRUE; 5076 mat->structurally_symmetric_set = PETSC_TRUE; 5077 } 5078 break; 5079 case MAT_SYMMETRIC: 5080 mat->symmetric = flg; 5081 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5082 mat->symmetric_set = PETSC_TRUE; 5083 mat->structurally_symmetric_set = flg; 5084 break; 5085 case MAT_HERMITIAN: 5086 mat->hermitian = flg; 5087 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5088 mat->hermitian_set = PETSC_TRUE; 5089 mat->structurally_symmetric_set = flg; 5090 break; 5091 case MAT_STRUCTURALLY_SYMMETRIC: 5092 mat->structurally_symmetric = flg; 5093 mat->structurally_symmetric_set = PETSC_TRUE; 5094 break; 5095 case MAT_SYMMETRY_ETERNAL: 5096 mat->symmetric_eternal = flg; 5097 break; 5098 default: 5099 break; 5100 } 5101 if (mat->ops->setoption) { 5102 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5103 } 5104 PetscFunctionReturn(0); 5105 } 5106 5107 #undef __FUNCT__ 5108 #define __FUNCT__ "MatZeroEntries" 5109 /*@ 5110 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5111 this routine retains the old nonzero structure. 5112 5113 Logically Collective on Mat 5114 5115 Input Parameters: 5116 . mat - the matrix 5117 5118 Level: intermediate 5119 5120 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. 5121 See the Performance chapter of the users manual for information on preallocating matrices. 5122 5123 Concepts: matrices^zeroing 5124 5125 .seealso: MatZeroRows() 5126 @*/ 5127 PetscErrorCode MatZeroEntries(Mat mat) 5128 { 5129 PetscErrorCode ierr; 5130 5131 PetscFunctionBegin; 5132 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5133 PetscValidType(mat,1); 5134 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5135 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"); 5136 if (!mat->ops->zeroentries) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5137 MatCheckPreallocated(mat,1); 5138 5139 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5140 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5141 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5142 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5143 #if defined(PETSC_HAVE_CUSP) 5144 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5145 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5146 } 5147 #endif 5148 PetscFunctionReturn(0); 5149 } 5150 5151 #undef __FUNCT__ 5152 #define __FUNCT__ "MatZeroRowsColumns" 5153 /*@C 5154 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5155 of a set of rows and columns of a matrix. 5156 5157 Collective on Mat 5158 5159 Input Parameters: 5160 + mat - the matrix 5161 . numRows - the number of rows to remove 5162 . rows - the global row indices 5163 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5164 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5165 - b - optional vector of right hand side, that will be adjusted by provided solution 5166 5167 Notes: 5168 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5169 5170 The user can set a value in the diagonal entry (or for the AIJ and 5171 row formats can optionally remove the main diagonal entry from the 5172 nonzero structure as well, by passing 0.0 as the final argument). 5173 5174 For the parallel case, all processes that share the matrix (i.e., 5175 those in the communicator used for matrix creation) MUST call this 5176 routine, regardless of whether any rows being zeroed are owned by 5177 them. 5178 5179 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5180 list only rows local to itself). 5181 5182 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5183 5184 Level: intermediate 5185 5186 Concepts: matrices^zeroing rows 5187 5188 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS() 5189 @*/ 5190 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5191 { 5192 PetscErrorCode ierr; 5193 5194 PetscFunctionBegin; 5195 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5196 PetscValidType(mat,1); 5197 if (numRows) PetscValidIntPointer(rows,3); 5198 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5199 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5200 if (!mat->ops->zerorowscolumns) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5201 MatCheckPreallocated(mat,1); 5202 5203 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5204 ierr = MatViewFromOptions(mat,"-mat_view");CHKERRQ(ierr); 5205 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5206 #if defined(PETSC_HAVE_CUSP) 5207 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5208 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5209 } 5210 #endif 5211 PetscFunctionReturn(0); 5212 } 5213 5214 #undef __FUNCT__ 5215 #define __FUNCT__ "MatZeroRowsColumnsIS" 5216 /*@C 5217 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5218 of a set of rows and columns of a matrix. 5219 5220 Collective on Mat 5221 5222 Input Parameters: 5223 + mat - the matrix 5224 . is - the rows to zero 5225 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5226 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5227 - b - optional vector of right hand side, that will be adjusted by provided solution 5228 5229 Notes: 5230 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5231 5232 The user can set a value in the diagonal entry (or for the AIJ and 5233 row formats can optionally remove the main diagonal entry from the 5234 nonzero structure as well, by passing 0.0 as the final argument). 5235 5236 For the parallel case, all processes that share the matrix (i.e., 5237 those in the communicator used for matrix creation) MUST call this 5238 routine, regardless of whether any rows being zeroed are owned by 5239 them. 5240 5241 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5242 list only rows local to itself). 5243 5244 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5245 5246 Level: intermediate 5247 5248 Concepts: matrices^zeroing rows 5249 5250 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns() 5251 @*/ 5252 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5253 { 5254 PetscErrorCode ierr; 5255 PetscInt numRows; 5256 const PetscInt *rows; 5257 5258 PetscFunctionBegin; 5259 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5260 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5261 PetscValidType(mat,1); 5262 PetscValidType(is,2); 5263 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5264 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5265 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5266 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5267 PetscFunctionReturn(0); 5268 } 5269 5270 #undef __FUNCT__ 5271 #define __FUNCT__ "MatZeroRows" 5272 /*@C 5273 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5274 of a set of rows of a matrix. 5275 5276 Collective on Mat 5277 5278 Input Parameters: 5279 + mat - the matrix 5280 . numRows - the number of rows to remove 5281 . rows - the global row indices 5282 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5283 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5284 - b - optional vector of right hand side, that will be adjusted by provided solution 5285 5286 Notes: 5287 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5288 but does not release memory. For the dense and block diagonal 5289 formats this does not alter the nonzero structure. 5290 5291 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5292 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5293 merely zeroed. 5294 5295 The user can set a value in the diagonal entry (or for the AIJ and 5296 row formats can optionally remove the main diagonal entry from the 5297 nonzero structure as well, by passing 0.0 as the final argument). 5298 5299 For the parallel case, all processes that share the matrix (i.e., 5300 those in the communicator used for matrix creation) MUST call this 5301 routine, regardless of whether any rows being zeroed are owned by 5302 them. 5303 5304 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5305 list only rows local to itself). 5306 5307 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5308 owns that are to be zeroed. This saves a global synchronization in the implementation. 5309 5310 Level: intermediate 5311 5312 Concepts: matrices^zeroing rows 5313 5314 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5315 @*/ 5316 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5317 { 5318 PetscErrorCode ierr; 5319 5320 PetscFunctionBegin; 5321 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5322 PetscValidType(mat,1); 5323 if (numRows) PetscValidIntPointer(rows,3); 5324 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5325 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5326 if (!mat->ops->zerorows) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5327 MatCheckPreallocated(mat,1); 5328 5329 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5330 ierr = MatViewFromOptions(mat,"-mat_view");CHKERRQ(ierr); 5331 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5332 #if defined(PETSC_HAVE_CUSP) 5333 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5334 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5335 } 5336 #endif 5337 PetscFunctionReturn(0); 5338 } 5339 5340 #undef __FUNCT__ 5341 #define __FUNCT__ "MatZeroRowsIS" 5342 /*@C 5343 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5344 of a set of rows of a matrix. 5345 5346 Collective on Mat 5347 5348 Input Parameters: 5349 + mat - the matrix 5350 . is - index set of rows to remove 5351 . diag - value put in all diagonals of eliminated rows 5352 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5353 - b - optional vector of right hand side, that will be adjusted by provided solution 5354 5355 Notes: 5356 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5357 but does not release memory. For the dense and block diagonal 5358 formats this does not alter the nonzero structure. 5359 5360 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5361 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5362 merely zeroed. 5363 5364 The user can set a value in the diagonal entry (or for the AIJ and 5365 row formats can optionally remove the main diagonal entry from the 5366 nonzero structure as well, by passing 0.0 as the final argument). 5367 5368 For the parallel case, all processes that share the matrix (i.e., 5369 those in the communicator used for matrix creation) MUST call this 5370 routine, regardless of whether any rows being zeroed are owned by 5371 them. 5372 5373 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5374 list only rows local to itself). 5375 5376 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5377 owns that are to be zeroed. This saves a global synchronization in the implementation. 5378 5379 Level: intermediate 5380 5381 Concepts: matrices^zeroing rows 5382 5383 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5384 @*/ 5385 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5386 { 5387 PetscInt numRows; 5388 const PetscInt *rows; 5389 PetscErrorCode ierr; 5390 5391 PetscFunctionBegin; 5392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5393 PetscValidType(mat,1); 5394 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5395 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5396 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5397 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5398 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5399 PetscFunctionReturn(0); 5400 } 5401 5402 #undef __FUNCT__ 5403 #define __FUNCT__ "MatZeroRowsStencil" 5404 /*@C 5405 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5406 of a set of rows of a matrix. These rows must be local to the process. 5407 5408 Collective on Mat 5409 5410 Input Parameters: 5411 + mat - the matrix 5412 . numRows - the number of rows to remove 5413 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5414 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5415 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5416 - b - optional vector of right hand side, that will be adjusted by provided solution 5417 5418 Notes: 5419 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5420 but does not release memory. For the dense and block diagonal 5421 formats this does not alter the nonzero structure. 5422 5423 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5424 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5425 merely zeroed. 5426 5427 The user can set a value in the diagonal entry (or for the AIJ and 5428 row formats can optionally remove the main diagonal entry from the 5429 nonzero structure as well, by passing 0.0 as the final argument). 5430 5431 For the parallel case, all processes that share the matrix (i.e., 5432 those in the communicator used for matrix creation) MUST call this 5433 routine, regardless of whether any rows being zeroed are owned by 5434 them. 5435 5436 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5437 list only rows local to itself). 5438 5439 The grid coordinates are across the entire grid, not just the local portion 5440 5441 In Fortran idxm and idxn should be declared as 5442 $ MatStencil idxm(4,m) 5443 and the values inserted using 5444 $ idxm(MatStencil_i,1) = i 5445 $ idxm(MatStencil_j,1) = j 5446 $ idxm(MatStencil_k,1) = k 5447 $ idxm(MatStencil_c,1) = c 5448 etc 5449 5450 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5451 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5452 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5453 DMDA_BOUNDARY_PERIODIC boundary type. 5454 5455 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 5456 a single value per point) you can skip filling those indices. 5457 5458 Level: intermediate 5459 5460 Concepts: matrices^zeroing rows 5461 5462 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5463 @*/ 5464 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5465 { 5466 PetscInt dim = mat->stencil.dim; 5467 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5468 PetscInt *dims = mat->stencil.dims+1; 5469 PetscInt *starts = mat->stencil.starts; 5470 PetscInt *dxm = (PetscInt *) rows; 5471 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5472 PetscErrorCode ierr; 5473 5474 PetscFunctionBegin; 5475 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5476 PetscValidType(mat,1); 5477 if (numRows) PetscValidIntPointer(rows,3); 5478 5479 ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr); 5480 for (i = 0; i < numRows; ++i) { 5481 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5482 for (j = 0; j < 3-sdim; ++j) dxm++; 5483 /* Local index in X dir */ 5484 tmp = *dxm++ - starts[0]; 5485 /* Loop over remaining dimensions */ 5486 for (j = 0; j < dim-1; ++j) { 5487 /* If nonlocal, set index to be negative */ 5488 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5489 /* Update local index */ 5490 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5491 } 5492 /* Skip component slot if necessary */ 5493 if (mat->stencil.noc) dxm++; 5494 /* Local row number */ 5495 if (tmp >= 0) { 5496 jdxm[numNewRows++] = tmp; 5497 } 5498 } 5499 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5500 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5501 PetscFunctionReturn(0); 5502 } 5503 5504 #undef __FUNCT__ 5505 #define __FUNCT__ "MatZeroRowsColumnsStencil" 5506 /*@C 5507 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5508 of a set of rows and columns of a matrix. 5509 5510 Collective on Mat 5511 5512 Input Parameters: 5513 + mat - the matrix 5514 . numRows - the number of rows/columns to remove 5515 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5516 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5517 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5518 - b - optional vector of right hand side, that will be adjusted by provided solution 5519 5520 Notes: 5521 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5522 but does not release memory. For the dense and block diagonal 5523 formats this does not alter the nonzero structure. 5524 5525 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5526 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5527 merely zeroed. 5528 5529 The user can set a value in the diagonal entry (or for the AIJ and 5530 row formats can optionally remove the main diagonal entry from the 5531 nonzero structure as well, by passing 0.0 as the final argument). 5532 5533 For the parallel case, all processes that share the matrix (i.e., 5534 those in the communicator used for matrix creation) MUST call this 5535 routine, regardless of whether any rows being zeroed are owned by 5536 them. 5537 5538 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5539 list only rows local to itself, but the row/column numbers are given in local numbering). 5540 5541 The grid coordinates are across the entire grid, not just the local portion 5542 5543 In Fortran idxm and idxn should be declared as 5544 $ MatStencil idxm(4,m) 5545 and the values inserted using 5546 $ idxm(MatStencil_i,1) = i 5547 $ idxm(MatStencil_j,1) = j 5548 $ idxm(MatStencil_k,1) = k 5549 $ idxm(MatStencil_c,1) = c 5550 etc 5551 5552 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5553 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5554 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5555 DMDA_BOUNDARY_PERIODIC boundary type. 5556 5557 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 5558 a single value per point) you can skip filling those indices. 5559 5560 Level: intermediate 5561 5562 Concepts: matrices^zeroing rows 5563 5564 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5565 @*/ 5566 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5567 { 5568 PetscInt dim = mat->stencil.dim; 5569 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5570 PetscInt *dims = mat->stencil.dims+1; 5571 PetscInt *starts = mat->stencil.starts; 5572 PetscInt *dxm = (PetscInt *) rows; 5573 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5574 PetscErrorCode ierr; 5575 5576 PetscFunctionBegin; 5577 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5578 PetscValidType(mat,1); 5579 if (numRows) PetscValidIntPointer(rows,3); 5580 5581 ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr); 5582 for (i = 0; i < numRows; ++i) { 5583 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5584 for (j = 0; j < 3-sdim; ++j) dxm++; 5585 /* Local index in X dir */ 5586 tmp = *dxm++ - starts[0]; 5587 /* Loop over remaining dimensions */ 5588 for (j = 0; j < dim-1; ++j) { 5589 /* If nonlocal, set index to be negative */ 5590 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5591 /* Update local index */ 5592 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5593 } 5594 /* Skip component slot if necessary */ 5595 if (mat->stencil.noc) dxm++; 5596 /* Local row number */ 5597 if (tmp >= 0) { 5598 jdxm[numNewRows++] = tmp; 5599 } 5600 } 5601 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5602 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5603 PetscFunctionReturn(0); 5604 } 5605 5606 #undef __FUNCT__ 5607 #define __FUNCT__ "MatZeroRowsLocal" 5608 /*@C 5609 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 5610 of a set of rows of a matrix; using local numbering of rows. 5611 5612 Collective on Mat 5613 5614 Input Parameters: 5615 + mat - the matrix 5616 . numRows - the number of rows to remove 5617 . rows - the global row indices 5618 . diag - value put in all diagonals of eliminated rows 5619 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5620 - b - optional vector of right hand side, that will be adjusted by provided solution 5621 5622 Notes: 5623 Before calling MatZeroRowsLocal(), the user must first set the 5624 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5625 5626 For the AIJ matrix formats this removes the old nonzero structure, 5627 but does not release memory. For the dense and block diagonal 5628 formats this does not alter the nonzero structure. 5629 5630 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5631 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5632 merely zeroed. 5633 5634 The user can set a value in the diagonal entry (or for the AIJ and 5635 row formats can optionally remove the main diagonal entry from the 5636 nonzero structure as well, by passing 0.0 as the final argument). 5637 5638 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5639 owns that are to be zeroed. This saves a global synchronization in the implementation. 5640 5641 Level: intermediate 5642 5643 Concepts: matrices^zeroing 5644 5645 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5646 @*/ 5647 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5648 { 5649 PetscErrorCode ierr; 5650 PetscMPIInt size; 5651 5652 PetscFunctionBegin; 5653 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5654 PetscValidType(mat,1); 5655 if (numRows) PetscValidIntPointer(rows,3); 5656 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5657 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5658 MatCheckPreallocated(mat,1); 5659 5660 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 5661 if (mat->ops->zerorowslocal) { 5662 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5663 } else if (size == 1) { 5664 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5665 } else { 5666 IS is, newis; 5667 const PetscInt *newRows; 5668 5669 if (!mat->rmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 5670 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 5671 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 5672 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 5673 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 5674 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 5675 ierr = ISDestroy(&newis);CHKERRQ(ierr); 5676 ierr = ISDestroy(&is);CHKERRQ(ierr); 5677 } 5678 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5679 #if defined(PETSC_HAVE_CUSP) 5680 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5681 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5682 } 5683 #endif 5684 PetscFunctionReturn(0); 5685 } 5686 5687 #undef __FUNCT__ 5688 #define __FUNCT__ "MatZeroRowsLocalIS" 5689 /*@C 5690 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 5691 of a set of rows of a matrix; using local numbering of rows. 5692 5693 Collective on Mat 5694 5695 Input Parameters: 5696 + mat - the matrix 5697 . is - index set of rows to remove 5698 . diag - value put in all diagonals of eliminated rows 5699 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5700 - b - optional vector of right hand side, that will be adjusted by provided solution 5701 5702 Notes: 5703 Before calling MatZeroRowsLocalIS(), the user must first set the 5704 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5705 5706 For the AIJ matrix formats this removes the old nonzero structure, 5707 but does not release memory. For the dense and block diagonal 5708 formats this does not alter the nonzero structure. 5709 5710 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5711 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5712 merely zeroed. 5713 5714 The user can set a value in the diagonal entry (or for the AIJ and 5715 row formats can optionally remove the main diagonal entry from the 5716 nonzero structure as well, by passing 0.0 as the final argument). 5717 5718 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5719 owns that are to be zeroed. This saves a global synchronization in the implementation. 5720 5721 Level: intermediate 5722 5723 Concepts: matrices^zeroing 5724 5725 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5726 @*/ 5727 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5728 { 5729 PetscErrorCode ierr; 5730 PetscInt numRows; 5731 const PetscInt *rows; 5732 5733 PetscFunctionBegin; 5734 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5735 PetscValidType(mat,1); 5736 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5737 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5738 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5739 MatCheckPreallocated(mat,1); 5740 5741 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5742 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5743 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5744 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5745 PetscFunctionReturn(0); 5746 } 5747 5748 #undef __FUNCT__ 5749 #define __FUNCT__ "MatZeroRowsColumnsLocal" 5750 /*@C 5751 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 5752 of a set of rows and columns of a matrix; using local numbering of rows. 5753 5754 Collective on Mat 5755 5756 Input Parameters: 5757 + mat - the matrix 5758 . numRows - the number of rows to remove 5759 . rows - the global row indices 5760 . diag - value put in all diagonals of eliminated rows 5761 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5762 - b - optional vector of right hand side, that will be adjusted by provided solution 5763 5764 Notes: 5765 Before calling MatZeroRowsColumnsLocal(), the user must first set the 5766 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5767 5768 The user can set a value in the diagonal entry (or for the AIJ and 5769 row formats can optionally remove the main diagonal entry from the 5770 nonzero structure as well, by passing 0.0 as the final argument). 5771 5772 Level: intermediate 5773 5774 Concepts: matrices^zeroing 5775 5776 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5777 @*/ 5778 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5779 { 5780 PetscErrorCode ierr; 5781 PetscMPIInt size; 5782 5783 PetscFunctionBegin; 5784 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5785 PetscValidType(mat,1); 5786 if (numRows) PetscValidIntPointer(rows,3); 5787 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5788 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5789 MatCheckPreallocated(mat,1); 5790 5791 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 5792 if (size == 1) { 5793 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5794 } else { 5795 IS is, newis; 5796 const PetscInt *newRows; 5797 5798 if (!mat->cmap->mapping) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 5799 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 5800 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 5801 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 5802 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 5803 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 5804 ierr = ISDestroy(&newis);CHKERRQ(ierr); 5805 ierr = ISDestroy(&is);CHKERRQ(ierr); 5806 } 5807 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5808 #if defined(PETSC_HAVE_CUSP) 5809 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5810 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5811 } 5812 #endif 5813 PetscFunctionReturn(0); 5814 } 5815 5816 #undef __FUNCT__ 5817 #define __FUNCT__ "MatZeroRowsColumnsLocalIS" 5818 /*@C 5819 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 5820 of a set of rows and columns of a matrix; using local numbering of rows. 5821 5822 Collective on Mat 5823 5824 Input Parameters: 5825 + mat - the matrix 5826 . is - index set of rows to remove 5827 . diag - value put in all diagonals of eliminated rows 5828 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5829 - b - optional vector of right hand side, that will be adjusted by provided solution 5830 5831 Notes: 5832 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 5833 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5834 5835 The user can set a value in the diagonal entry (or for the AIJ and 5836 row formats can optionally remove the main diagonal entry from the 5837 nonzero structure as well, by passing 0.0 as the final argument). 5838 5839 Level: intermediate 5840 5841 Concepts: matrices^zeroing 5842 5843 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5844 @*/ 5845 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5846 { 5847 PetscErrorCode ierr; 5848 PetscInt numRows; 5849 const PetscInt *rows; 5850 5851 PetscFunctionBegin; 5852 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5853 PetscValidType(mat,1); 5854 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5855 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5856 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5857 MatCheckPreallocated(mat,1); 5858 5859 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5860 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5861 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5862 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5863 PetscFunctionReturn(0); 5864 } 5865 5866 #undef __FUNCT__ 5867 #define __FUNCT__ "MatGetSize" 5868 /*@ 5869 MatGetSize - Returns the numbers of rows and columns in a matrix. 5870 5871 Not Collective 5872 5873 Input Parameter: 5874 . mat - the matrix 5875 5876 Output Parameters: 5877 + m - the number of global rows 5878 - n - the number of global columns 5879 5880 Note: both output parameters can be PETSC_NULL on input. 5881 5882 Level: beginner 5883 5884 Concepts: matrices^size 5885 5886 .seealso: MatGetLocalSize() 5887 @*/ 5888 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 5889 { 5890 PetscFunctionBegin; 5891 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5892 if (m) *m = mat->rmap->N; 5893 if (n) *n = mat->cmap->N; 5894 PetscFunctionReturn(0); 5895 } 5896 5897 #undef __FUNCT__ 5898 #define __FUNCT__ "MatGetLocalSize" 5899 /*@ 5900 MatGetLocalSize - Returns the number of rows and columns in a matrix 5901 stored locally. This information may be implementation dependent, so 5902 use with care. 5903 5904 Not Collective 5905 5906 Input Parameters: 5907 . mat - the matrix 5908 5909 Output Parameters: 5910 + m - the number of local rows 5911 - n - the number of local columns 5912 5913 Note: both output parameters can be PETSC_NULL on input. 5914 5915 Level: beginner 5916 5917 Concepts: matrices^local size 5918 5919 .seealso: MatGetSize() 5920 @*/ 5921 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 5922 { 5923 PetscFunctionBegin; 5924 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5925 if (m) PetscValidIntPointer(m,2); 5926 if (n) PetscValidIntPointer(n,3); 5927 if (m) *m = mat->rmap->n; 5928 if (n) *n = mat->cmap->n; 5929 PetscFunctionReturn(0); 5930 } 5931 5932 #undef __FUNCT__ 5933 #define __FUNCT__ "MatGetOwnershipRangeColumn" 5934 /*@ 5935 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 5936 this processor. (The columns of the "diagonal block") 5937 5938 Not Collective, unless matrix has not been allocated, then collective on Mat 5939 5940 Input Parameters: 5941 . mat - the matrix 5942 5943 Output Parameters: 5944 + m - the global index of the first local column 5945 - n - one more than the global index of the last local column 5946 5947 Notes: both output parameters can be PETSC_NULL on input. 5948 5949 Level: developer 5950 5951 Concepts: matrices^column ownership 5952 5953 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 5954 5955 @*/ 5956 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 5957 { 5958 PetscFunctionBegin; 5959 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5960 PetscValidType(mat,1); 5961 if (m) PetscValidIntPointer(m,2); 5962 if (n) PetscValidIntPointer(n,3); 5963 MatCheckPreallocated(mat,1); 5964 if (m) *m = mat->cmap->rstart; 5965 if (n) *n = mat->cmap->rend; 5966 PetscFunctionReturn(0); 5967 } 5968 5969 #undef __FUNCT__ 5970 #define __FUNCT__ "MatGetOwnershipRange" 5971 /*@ 5972 MatGetOwnershipRange - Returns the range of matrix rows owned by 5973 this processor, assuming that the matrix is laid out with the first 5974 n1 rows on the first processor, the next n2 rows on the second, etc. 5975 For certain parallel layouts this range may not be well defined. 5976 5977 Not Collective 5978 5979 Input Parameters: 5980 . mat - the matrix 5981 5982 Output Parameters: 5983 + m - the global index of the first local row 5984 - n - one more than the global index of the last local row 5985 5986 Note: Both output parameters can be PETSC_NULL on input. 5987 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 5988 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 5989 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 5990 5991 Level: beginner 5992 5993 Concepts: matrices^row ownership 5994 5995 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 5996 5997 @*/ 5998 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 5999 { 6000 PetscFunctionBegin; 6001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6002 PetscValidType(mat,1); 6003 if (m) PetscValidIntPointer(m,2); 6004 if (n) PetscValidIntPointer(n,3); 6005 MatCheckPreallocated(mat,1); 6006 if (m) *m = mat->rmap->rstart; 6007 if (n) *n = mat->rmap->rend; 6008 PetscFunctionReturn(0); 6009 } 6010 6011 #undef __FUNCT__ 6012 #define __FUNCT__ "MatGetOwnershipRanges" 6013 /*@C 6014 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6015 each process 6016 6017 Not Collective, unless matrix has not been allocated, then collective on Mat 6018 6019 Input Parameters: 6020 . mat - the matrix 6021 6022 Output Parameters: 6023 . ranges - start of each processors portion plus one more then the total length at the end 6024 6025 Level: beginner 6026 6027 Concepts: matrices^row ownership 6028 6029 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6030 6031 @*/ 6032 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6033 { 6034 PetscErrorCode ierr; 6035 6036 PetscFunctionBegin; 6037 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6038 PetscValidType(mat,1); 6039 MatCheckPreallocated(mat,1); 6040 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6041 PetscFunctionReturn(0); 6042 } 6043 6044 #undef __FUNCT__ 6045 #define __FUNCT__ "MatGetOwnershipRangesColumn" 6046 /*@C 6047 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6048 this processor. (The columns of the "diagonal blocks" for each process) 6049 6050 Not Collective, unless matrix has not been allocated, then collective on Mat 6051 6052 Input Parameters: 6053 . mat - the matrix 6054 6055 Output Parameters: 6056 . ranges - start of each processors portion plus one more then the total length at the end 6057 6058 Level: beginner 6059 6060 Concepts: matrices^column ownership 6061 6062 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6063 6064 @*/ 6065 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6066 { 6067 PetscErrorCode ierr; 6068 6069 PetscFunctionBegin; 6070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6071 PetscValidType(mat,1); 6072 MatCheckPreallocated(mat,1); 6073 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6074 PetscFunctionReturn(0); 6075 } 6076 6077 #undef __FUNCT__ 6078 #define __FUNCT__ "MatGetOwnershipIS" 6079 /*@C 6080 MatGetOwnershipIS - Get row and column ownership as index sets 6081 6082 Not Collective 6083 6084 Input Arguments: 6085 . A - matrix of type Elemental 6086 6087 Output Arguments: 6088 + rows - rows in which this process owns elements 6089 . cols - columns in which this process owns elements 6090 6091 Level: intermediate 6092 6093 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues() 6094 @*/ 6095 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6096 { 6097 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6098 6099 PetscFunctionBegin; 6100 MatCheckPreallocated(A,1); 6101 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",(PetscVoidStarFunction)&f);CHKERRQ(ierr); 6102 if (f) { 6103 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6104 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6105 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6106 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6107 } 6108 PetscFunctionReturn(0); 6109 } 6110 6111 #undef __FUNCT__ 6112 #define __FUNCT__ "MatILUFactorSymbolic" 6113 /*@C 6114 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6115 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6116 to complete the factorization. 6117 6118 Collective on Mat 6119 6120 Input Parameters: 6121 + mat - the matrix 6122 . row - row permutation 6123 . column - column permutation 6124 - info - structure containing 6125 $ levels - number of levels of fill. 6126 $ expected fill - as ratio of original fill. 6127 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6128 missing diagonal entries) 6129 6130 Output Parameters: 6131 . fact - new matrix that has been symbolically factored 6132 6133 Notes: 6134 See the <a href="../../docs/manual.pdf">users manual</a> for additional information about 6135 choosing the fill factor for better efficiency. 6136 6137 Most users should employ the simplified KSP interface for linear solvers 6138 instead of working directly with matrix algebra routines such as this. 6139 See, e.g., KSPCreate(). 6140 6141 Level: developer 6142 6143 Concepts: matrices^symbolic LU factorization 6144 Concepts: matrices^factorization 6145 Concepts: LU^symbolic factorization 6146 6147 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6148 MatGetOrdering(), MatFactorInfo 6149 6150 Developer Note: fortran interface is not autogenerated as the f90 6151 interface defintion cannot be generated correctly [due to MatFactorInfo] 6152 6153 @*/ 6154 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6155 { 6156 PetscErrorCode ierr; 6157 6158 PetscFunctionBegin; 6159 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6160 PetscValidType(mat,1); 6161 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6162 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6163 PetscValidPointer(info,4); 6164 PetscValidPointer(fact,5); 6165 if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6166 if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill); 6167 if (!(fact)->ops->ilufactorsymbolic) { 6168 const MatSolverPackage spackage; 6169 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6170 SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6171 } 6172 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6173 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6174 MatCheckPreallocated(mat,2); 6175 6176 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6177 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6178 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6179 PetscFunctionReturn(0); 6180 } 6181 6182 #undef __FUNCT__ 6183 #define __FUNCT__ "MatICCFactorSymbolic" 6184 /*@C 6185 MatICCFactorSymbolic - Performs symbolic incomplete 6186 Cholesky factorization for a symmetric matrix. Use 6187 MatCholeskyFactorNumeric() to complete the factorization. 6188 6189 Collective on Mat 6190 6191 Input Parameters: 6192 + mat - the matrix 6193 . perm - row and column permutation 6194 - info - structure containing 6195 $ levels - number of levels of fill. 6196 $ expected fill - as ratio of original fill. 6197 6198 Output Parameter: 6199 . fact - the factored matrix 6200 6201 Notes: 6202 Most users should employ the KSP interface for linear solvers 6203 instead of working directly with matrix algebra routines such as this. 6204 See, e.g., KSPCreate(). 6205 6206 Level: developer 6207 6208 Concepts: matrices^symbolic incomplete Cholesky factorization 6209 Concepts: matrices^factorization 6210 Concepts: Cholsky^symbolic factorization 6211 6212 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6213 6214 Developer Note: fortran interface is not autogenerated as the f90 6215 interface defintion cannot be generated correctly [due to MatFactorInfo] 6216 6217 @*/ 6218 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6219 { 6220 PetscErrorCode ierr; 6221 6222 PetscFunctionBegin; 6223 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6224 PetscValidType(mat,1); 6225 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6226 PetscValidPointer(info,3); 6227 PetscValidPointer(fact,4); 6228 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6229 if (info->levels < 0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6230 if (info->fill < 1.0) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill); 6231 if (!(fact)->ops->iccfactorsymbolic) { 6232 const MatSolverPackage spackage; 6233 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6234 SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6235 } 6236 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6237 MatCheckPreallocated(mat,2); 6238 6239 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6240 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6241 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6242 PetscFunctionReturn(0); 6243 } 6244 6245 #undef __FUNCT__ 6246 #define __FUNCT__ "MatGetSubMatrices" 6247 /*@C 6248 MatGetSubMatrices - Extracts several submatrices from a matrix. If submat 6249 points to an array of valid matrices, they may be reused to store the new 6250 submatrices. 6251 6252 Collective on Mat 6253 6254 Input Parameters: 6255 + mat - the matrix 6256 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6257 . irow, icol - index sets of rows and columns to extract (must be sorted) 6258 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6259 6260 Output Parameter: 6261 . submat - the array of submatrices 6262 6263 Notes: 6264 MatGetSubMatrices() can extract ONLY sequential submatrices 6265 (from both sequential and parallel matrices). Use MatGetSubMatrix() 6266 to extract a parallel submatrix. 6267 6268 Currently both row and column indices must be sorted to guarantee 6269 correctness with all matrix types. 6270 6271 When extracting submatrices from a parallel matrix, each processor can 6272 form a different submatrix by setting the rows and columns of its 6273 individual index sets according to the local submatrix desired. 6274 6275 When finished using the submatrices, the user should destroy 6276 them with MatDestroyMatrices(). 6277 6278 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6279 original matrix has not changed from that last call to MatGetSubMatrices(). 6280 6281 This routine creates the matrices in submat; you should NOT create them before 6282 calling it. It also allocates the array of matrix pointers submat. 6283 6284 For BAIJ matrices the index sets must respect the block structure, that is if they 6285 request one row/column in a block, they must request all rows/columns that are in 6286 that block. For example, if the block size is 2 you cannot request just row 0 and 6287 column 0. 6288 6289 Fortran Note: 6290 The Fortran interface is slightly different from that given below; it 6291 requires one to pass in as submat a Mat (integer) array of size at least m. 6292 6293 Level: advanced 6294 6295 Concepts: matrices^accessing submatrices 6296 Concepts: submatrices 6297 6298 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6299 @*/ 6300 PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6301 { 6302 PetscErrorCode ierr; 6303 PetscInt i; 6304 PetscBool eq; 6305 6306 PetscFunctionBegin; 6307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6308 PetscValidType(mat,1); 6309 if (n) { 6310 PetscValidPointer(irow,3); 6311 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6312 PetscValidPointer(icol,4); 6313 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6314 } 6315 PetscValidPointer(submat,6); 6316 if (n && scall == MAT_REUSE_MATRIX) { 6317 PetscValidPointer(*submat,6); 6318 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6319 } 6320 if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6321 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6322 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6323 MatCheckPreallocated(mat,1); 6324 6325 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6326 ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6327 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6328 for (i=0; i<n; i++) { 6329 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6330 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6331 if (eq) { 6332 if (mat->symmetric) { 6333 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6334 } else if (mat->hermitian) { 6335 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6336 } else if (mat->structurally_symmetric) { 6337 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6338 } 6339 } 6340 } 6341 } 6342 PetscFunctionReturn(0); 6343 } 6344 6345 #undef __FUNCT__ 6346 #define __FUNCT__ "MatGetSubMatricesParallel" 6347 PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6348 { 6349 PetscErrorCode ierr; 6350 PetscInt i; 6351 PetscBool eq; 6352 6353 PetscFunctionBegin; 6354 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6355 PetscValidType(mat,1); 6356 if (n) { 6357 PetscValidPointer(irow,3); 6358 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6359 PetscValidPointer(icol,4); 6360 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6361 } 6362 PetscValidPointer(submat,6); 6363 if (n && scall == MAT_REUSE_MATRIX) { 6364 PetscValidPointer(*submat,6); 6365 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6366 } 6367 if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6368 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6369 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6370 MatCheckPreallocated(mat,1); 6371 6372 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6373 ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6374 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6375 for (i=0; i<n; i++) { 6376 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6377 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6378 if (eq) { 6379 if (mat->symmetric) { 6380 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6381 } else if (mat->hermitian) { 6382 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6383 } else if (mat->structurally_symmetric) { 6384 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6385 } 6386 } 6387 } 6388 } 6389 PetscFunctionReturn(0); 6390 } 6391 6392 #undef __FUNCT__ 6393 #define __FUNCT__ "MatDestroyMatrices" 6394 /*@C 6395 MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices(). 6396 6397 Collective on Mat 6398 6399 Input Parameters: 6400 + n - the number of local matrices 6401 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6402 sequence of MatGetSubMatrices()) 6403 6404 Level: advanced 6405 6406 Notes: Frees not only the matrices, but also the array that contains the matrices 6407 In Fortran will not free the array. 6408 6409 .seealso: MatGetSubMatrices() 6410 @*/ 6411 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6412 { 6413 PetscErrorCode ierr; 6414 PetscInt i; 6415 6416 PetscFunctionBegin; 6417 if (!*mat) PetscFunctionReturn(0); 6418 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6419 PetscValidPointer(mat,2); 6420 for (i=0; i<n; i++) { 6421 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6422 } 6423 /* memory is allocated even if n = 0 */ 6424 ierr = PetscFree(*mat);CHKERRQ(ierr); 6425 *mat = PETSC_NULL; 6426 PetscFunctionReturn(0); 6427 } 6428 6429 #undef __FUNCT__ 6430 #define __FUNCT__ "MatGetSeqNonzeroStructure" 6431 /*@C 6432 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6433 6434 Collective on Mat 6435 6436 Input Parameters: 6437 . mat - the matrix 6438 6439 Output Parameter: 6440 . matstruct - the sequential matrix with the nonzero structure of mat 6441 6442 Level: intermediate 6443 6444 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices() 6445 @*/ 6446 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6447 { 6448 PetscErrorCode ierr; 6449 6450 PetscFunctionBegin; 6451 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6452 PetscValidPointer(matstruct,2); 6453 6454 PetscValidType(mat,1); 6455 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6456 MatCheckPreallocated(mat,1); 6457 6458 if (!mat->ops->getseqnonzerostructure) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6459 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6460 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6461 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6462 PetscFunctionReturn(0); 6463 } 6464 6465 #undef __FUNCT__ 6466 #define __FUNCT__ "MatDestroySeqNonzeroStructure" 6467 /*@C 6468 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6469 6470 Collective on Mat 6471 6472 Input Parameters: 6473 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6474 sequence of MatGetSequentialNonzeroStructure()) 6475 6476 Level: advanced 6477 6478 Notes: Frees not only the matrices, but also the array that contains the matrices 6479 6480 .seealso: MatGetSeqNonzeroStructure() 6481 @*/ 6482 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6483 { 6484 PetscErrorCode ierr; 6485 6486 PetscFunctionBegin; 6487 PetscValidPointer(mat,1); 6488 ierr = MatDestroy(mat);CHKERRQ(ierr); 6489 PetscFunctionReturn(0); 6490 } 6491 6492 #undef __FUNCT__ 6493 #define __FUNCT__ "MatIncreaseOverlap" 6494 /*@ 6495 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6496 replaces the index sets by larger ones that represent submatrices with 6497 additional overlap. 6498 6499 Collective on Mat 6500 6501 Input Parameters: 6502 + mat - the matrix 6503 . n - the number of index sets 6504 . is - the array of index sets (these index sets will changed during the call) 6505 - ov - the additional overlap requested 6506 6507 Level: developer 6508 6509 Concepts: overlap 6510 Concepts: ASM^computing overlap 6511 6512 .seealso: MatGetSubMatrices() 6513 @*/ 6514 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6515 { 6516 PetscErrorCode ierr; 6517 6518 PetscFunctionBegin; 6519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6520 PetscValidType(mat,1); 6521 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6522 if (n) { 6523 PetscValidPointer(is,3); 6524 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6525 } 6526 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6527 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6528 MatCheckPreallocated(mat,1); 6529 6530 if (!ov) PetscFunctionReturn(0); 6531 if (!mat->ops->increaseoverlap) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6532 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6533 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6534 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6535 PetscFunctionReturn(0); 6536 } 6537 6538 #undef __FUNCT__ 6539 #define __FUNCT__ "MatGetBlockSize" 6540 /*@ 6541 MatGetBlockSize - Returns the matrix block size; useful especially for the 6542 block row and block diagonal formats. 6543 6544 Not Collective 6545 6546 Input Parameter: 6547 . mat - the matrix 6548 6549 Output Parameter: 6550 . bs - block size 6551 6552 Notes: 6553 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ 6554 6555 Level: intermediate 6556 6557 Concepts: matrices^block size 6558 6559 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 6560 @*/ 6561 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 6562 { 6563 PetscFunctionBegin; 6564 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6565 PetscValidType(mat,1); 6566 PetscValidIntPointer(bs,2); 6567 MatCheckPreallocated(mat,1); 6568 *bs = mat->rmap->bs; 6569 PetscFunctionReturn(0); 6570 } 6571 6572 #undef __FUNCT__ 6573 #define __FUNCT__ "MatGetBlockSizes" 6574 /*@ 6575 MatGetBlockSizes - Returns the matrix block row and column sizes; 6576 useful especially for the block row and block diagonal formats. 6577 6578 Not Collective 6579 6580 Input Parameter: 6581 . mat - the matrix 6582 6583 Output Parameter: 6584 . rbs - row block size 6585 . cbs - coumn block size 6586 6587 Notes: 6588 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ 6589 6590 Level: intermediate 6591 6592 Concepts: matrices^block size 6593 6594 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6595 @*/ 6596 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 6597 { 6598 PetscFunctionBegin; 6599 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6600 PetscValidType(mat,1); 6601 if (rbs) PetscValidIntPointer(rbs,2); 6602 if (cbs) PetscValidIntPointer(cbs,3); 6603 MatCheckPreallocated(mat,1); 6604 if (rbs) *rbs = mat->rmap->bs; 6605 if (cbs) *cbs = mat->cmap->bs; 6606 PetscFunctionReturn(0); 6607 } 6608 6609 #undef __FUNCT__ 6610 #define __FUNCT__ "MatSetBlockSize" 6611 /*@ 6612 MatSetBlockSize - Sets the matrix block size. 6613 6614 Logically Collective on Mat 6615 6616 Input Parameters: 6617 + mat - the matrix 6618 - bs - block size 6619 6620 Notes: 6621 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 6622 6623 Level: intermediate 6624 6625 Concepts: matrices^block size 6626 6627 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6628 @*/ 6629 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 6630 { 6631 PetscErrorCode ierr; 6632 6633 PetscFunctionBegin; 6634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6635 PetscValidLogicalCollectiveInt(mat,bs,2); 6636 ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr); 6637 ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr); 6638 PetscFunctionReturn(0); 6639 } 6640 6641 #undef __FUNCT__ 6642 #define __FUNCT__ "MatSetBlockSizes" 6643 /*@ 6644 MatSetBlockSizes - Sets the matrix block row and column sizes. 6645 6646 Logically Collective on Mat 6647 6648 Input Parameters: 6649 + mat - the matrix 6650 - rbs - row block size 6651 - cbs - column block size 6652 6653 Notes: 6654 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 6655 6656 Level: intermediate 6657 6658 Concepts: matrices^block size 6659 6660 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6661 @*/ 6662 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 6663 { 6664 PetscErrorCode ierr; 6665 6666 PetscFunctionBegin; 6667 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6668 PetscValidLogicalCollectiveInt(mat,rbs,2); 6669 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 6670 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 6671 PetscFunctionReturn(0); 6672 } 6673 6674 #undef __FUNCT__ 6675 #define __FUNCT__ "MatGetRowIJ" 6676 /*@C 6677 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 6678 6679 Collective on Mat 6680 6681 Input Parameters: 6682 + mat - the matrix 6683 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 6684 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 6685 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6686 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6687 always used. 6688 6689 Output Parameters: 6690 + n - number of rows in the (possibly compressed) matrix 6691 . ia - the row pointers [of length n+1] 6692 . ja - the column indices 6693 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 6694 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 6695 6696 Level: developer 6697 6698 Notes: You CANNOT change any of the ia[] or ja[] values. 6699 6700 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values 6701 6702 Fortran Node 6703 6704 In Fortran use 6705 $ PetscInt ia(1), ja(1) 6706 $ PetscOffset iia, jja 6707 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 6708 $ 6709 $ or 6710 $ 6711 $ PetscScalar, pointer :: xx_v(:) 6712 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 6713 6714 6715 Acess the ith and jth entries via ia(iia + i) and ja(jja + j) 6716 6717 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 6718 @*/ 6719 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 6720 { 6721 PetscErrorCode ierr; 6722 6723 PetscFunctionBegin; 6724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6725 PetscValidType(mat,1); 6726 PetscValidIntPointer(n,4); 6727 if (ia) PetscValidIntPointer(ia,5); 6728 if (ja) PetscValidIntPointer(ja,6); 6729 PetscValidIntPointer(done,7); 6730 MatCheckPreallocated(mat,1); 6731 if (!mat->ops->getrowij) *done = PETSC_FALSE; 6732 else { 6733 *done = PETSC_TRUE; 6734 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 6735 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6736 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 6737 } 6738 PetscFunctionReturn(0); 6739 } 6740 6741 #undef __FUNCT__ 6742 #define __FUNCT__ "MatGetColumnIJ" 6743 /*@C 6744 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 6745 6746 Collective on Mat 6747 6748 Input Parameters: 6749 + mat - the matrix 6750 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6751 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6752 symmetrized 6753 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6754 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6755 always used. 6756 6757 Output Parameters: 6758 + n - number of columns in the (possibly compressed) matrix 6759 . ia - the column pointers 6760 . ja - the row indices 6761 - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 6762 6763 Level: developer 6764 6765 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 6766 @*/ 6767 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 6768 { 6769 PetscErrorCode ierr; 6770 6771 PetscFunctionBegin; 6772 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6773 PetscValidType(mat,1); 6774 PetscValidIntPointer(n,4); 6775 if (ia) PetscValidIntPointer(ia,5); 6776 if (ja) PetscValidIntPointer(ja,6); 6777 PetscValidIntPointer(done,7); 6778 MatCheckPreallocated(mat,1); 6779 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 6780 else { 6781 *done = PETSC_TRUE; 6782 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6783 } 6784 PetscFunctionReturn(0); 6785 } 6786 6787 #undef __FUNCT__ 6788 #define __FUNCT__ "MatRestoreRowIJ" 6789 /*@C 6790 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 6791 MatGetRowIJ(). 6792 6793 Collective on Mat 6794 6795 Input Parameters: 6796 + mat - the matrix 6797 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6798 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6799 symmetrized 6800 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6801 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6802 always used. 6803 6804 Output Parameters: 6805 + n - size of (possibly compressed) matrix 6806 . ia - the row pointers 6807 . ja - the column indices 6808 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 6809 6810 Level: developer 6811 6812 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 6813 @*/ 6814 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 6815 { 6816 PetscErrorCode ierr; 6817 6818 PetscFunctionBegin; 6819 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6820 PetscValidType(mat,1); 6821 if (ia) PetscValidIntPointer(ia,5); 6822 if (ja) PetscValidIntPointer(ja,6); 6823 PetscValidIntPointer(done,7); 6824 MatCheckPreallocated(mat,1); 6825 6826 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 6827 else { 6828 *done = PETSC_TRUE; 6829 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6830 } 6831 PetscFunctionReturn(0); 6832 } 6833 6834 #undef __FUNCT__ 6835 #define __FUNCT__ "MatRestoreColumnIJ" 6836 /*@C 6837 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 6838 MatGetColumnIJ(). 6839 6840 Collective on Mat 6841 6842 Input Parameters: 6843 + mat - the matrix 6844 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6845 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6846 symmetrized 6847 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6848 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6849 always used. 6850 6851 Output Parameters: 6852 + n - size of (possibly compressed) matrix 6853 . ia - the column pointers 6854 . ja - the row indices 6855 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 6856 6857 Level: developer 6858 6859 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 6860 @*/ 6861 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 6862 { 6863 PetscErrorCode ierr; 6864 6865 PetscFunctionBegin; 6866 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6867 PetscValidType(mat,1); 6868 if (ia) PetscValidIntPointer(ia,5); 6869 if (ja) PetscValidIntPointer(ja,6); 6870 PetscValidIntPointer(done,7); 6871 MatCheckPreallocated(mat,1); 6872 6873 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 6874 else { 6875 *done = PETSC_TRUE; 6876 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6877 } 6878 PetscFunctionReturn(0); 6879 } 6880 6881 #undef __FUNCT__ 6882 #define __FUNCT__ "MatColoringPatch" 6883 /*@C 6884 MatColoringPatch -Used inside matrix coloring routines that 6885 use MatGetRowIJ() and/or MatGetColumnIJ(). 6886 6887 Collective on Mat 6888 6889 Input Parameters: 6890 + mat - the matrix 6891 . ncolors - max color value 6892 . n - number of entries in colorarray 6893 - colorarray - array indicating color for each column 6894 6895 Output Parameters: 6896 . iscoloring - coloring generated using colorarray information 6897 6898 Level: developer 6899 6900 .seealso: MatGetRowIJ(), MatGetColumnIJ() 6901 6902 @*/ 6903 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 6904 { 6905 PetscErrorCode ierr; 6906 6907 PetscFunctionBegin; 6908 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6909 PetscValidType(mat,1); 6910 PetscValidIntPointer(colorarray,4); 6911 PetscValidPointer(iscoloring,5); 6912 MatCheckPreallocated(mat,1); 6913 6914 if (!mat->ops->coloringpatch) { 6915 ierr = ISColoringCreate(((PetscObject)mat)->comm,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 6916 } else { 6917 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 6918 } 6919 PetscFunctionReturn(0); 6920 } 6921 6922 6923 #undef __FUNCT__ 6924 #define __FUNCT__ "MatSetUnfactored" 6925 /*@ 6926 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 6927 6928 Logically Collective on Mat 6929 6930 Input Parameter: 6931 . mat - the factored matrix to be reset 6932 6933 Notes: 6934 This routine should be used only with factored matrices formed by in-place 6935 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 6936 format). This option can save memory, for example, when solving nonlinear 6937 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 6938 ILU(0) preconditioner. 6939 6940 Note that one can specify in-place ILU(0) factorization by calling 6941 .vb 6942 PCType(pc,PCILU); 6943 PCFactorSeUseInPlace(pc); 6944 .ve 6945 or by using the options -pc_type ilu -pc_factor_in_place 6946 6947 In-place factorization ILU(0) can also be used as a local 6948 solver for the blocks within the block Jacobi or additive Schwarz 6949 methods (runtime option: -sub_pc_factor_in_place). See the discussion 6950 of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting 6951 local solver options. 6952 6953 Most users should employ the simplified KSP interface for linear solvers 6954 instead of working directly with matrix algebra routines such as this. 6955 See, e.g., KSPCreate(). 6956 6957 Level: developer 6958 6959 .seealso: PCFactorSetUseInPlace() 6960 6961 Concepts: matrices^unfactored 6962 6963 @*/ 6964 PetscErrorCode MatSetUnfactored(Mat mat) 6965 { 6966 PetscErrorCode ierr; 6967 6968 PetscFunctionBegin; 6969 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6970 PetscValidType(mat,1); 6971 MatCheckPreallocated(mat,1); 6972 mat->factortype = MAT_FACTOR_NONE; 6973 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 6974 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 6975 PetscFunctionReturn(0); 6976 } 6977 6978 /*MC 6979 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 6980 6981 Synopsis: 6982 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 6983 6984 Not collective 6985 6986 Input Parameter: 6987 . x - matrix 6988 6989 Output Parameters: 6990 + xx_v - the Fortran90 pointer to the array 6991 - ierr - error code 6992 6993 Example of Usage: 6994 .vb 6995 PetscScalar, pointer xx_v(:,:) 6996 .... 6997 call MatDenseGetArrayF90(x,xx_v,ierr) 6998 a = xx_v(3) 6999 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7000 .ve 7001 7002 Level: advanced 7003 7004 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray() 7005 7006 Concepts: matrices^accessing array 7007 7008 M*/ 7009 7010 /*MC 7011 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7012 accessed with MatGetArrayF90(). 7013 7014 Synopsis: 7015 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7016 7017 Not collective 7018 7019 Input Parameters: 7020 + x - matrix 7021 - xx_v - the Fortran90 pointer to the array 7022 7023 Output Parameter: 7024 . ierr - error code 7025 7026 Example of Usage: 7027 .vb 7028 PetscScalar, pointer xx_v(:) 7029 .... 7030 call MatDenseGetArrayF90(x,xx_v,ierr) 7031 a = xx_v(3) 7032 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7033 .ve 7034 7035 Level: advanced 7036 7037 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray() 7038 7039 M*/ 7040 7041 7042 #undef __FUNCT__ 7043 #define __FUNCT__ "MatGetSubMatrix" 7044 /*@ 7045 MatGetSubMatrix - Gets a single submatrix on the same number of processors 7046 as the original matrix. 7047 7048 Collective on Mat 7049 7050 Input Parameters: 7051 + mat - the original matrix 7052 . isrow - parallel IS containing the rows this processor should obtain 7053 . 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. 7054 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7055 7056 Output Parameter: 7057 . newmat - the new submatrix, of the same type as the old 7058 7059 Level: advanced 7060 7061 Notes: 7062 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7063 7064 The rows in isrow will be sorted into the same order as the original matrix on each process. 7065 7066 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7067 the MatGetSubMatrix() routine will create the newmat for you. Any additional calls 7068 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7069 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7070 you are finished using it. 7071 7072 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7073 the input matrix. 7074 7075 If iscol is PETSC_NULL then all columns are obtained (not supported in Fortran). 7076 7077 Example usage: 7078 Consider the following 8x8 matrix with 34 non-zero values, that is 7079 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7080 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7081 as follows: 7082 7083 .vb 7084 1 2 0 | 0 3 0 | 0 4 7085 Proc0 0 5 6 | 7 0 0 | 8 0 7086 9 0 10 | 11 0 0 | 12 0 7087 ------------------------------------- 7088 13 0 14 | 15 16 17 | 0 0 7089 Proc1 0 18 0 | 19 20 21 | 0 0 7090 0 0 0 | 22 23 0 | 24 0 7091 ------------------------------------- 7092 Proc2 25 26 27 | 0 0 28 | 29 0 7093 30 0 0 | 31 32 33 | 0 34 7094 .ve 7095 7096 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7097 7098 .vb 7099 2 0 | 0 3 0 | 0 7100 Proc0 5 6 | 7 0 0 | 8 7101 ------------------------------- 7102 Proc1 18 0 | 19 20 21 | 0 7103 ------------------------------- 7104 Proc2 26 27 | 0 0 28 | 29 7105 0 0 | 31 32 33 | 0 7106 .ve 7107 7108 7109 Concepts: matrices^submatrices 7110 7111 .seealso: MatGetSubMatrices() 7112 @*/ 7113 PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7114 { 7115 PetscErrorCode ierr; 7116 PetscMPIInt size; 7117 Mat *local; 7118 IS iscoltmp; 7119 7120 PetscFunctionBegin; 7121 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7122 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7123 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7124 PetscValidPointer(newmat,5); 7125 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7126 PetscValidType(mat,1); 7127 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7128 MatCheckPreallocated(mat,1); 7129 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 7130 7131 if (!iscol) { 7132 ierr = ISCreateStride(((PetscObject)mat)->comm,mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7133 } else { 7134 iscoltmp = iscol; 7135 } 7136 7137 /* if original matrix is on just one processor then use submatrix generated */ 7138 if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7139 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7140 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7141 PetscFunctionReturn(0); 7142 } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) { 7143 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7144 *newmat = *local; 7145 ierr = PetscFree(local);CHKERRQ(ierr); 7146 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7147 PetscFunctionReturn(0); 7148 } else if (!mat->ops->getsubmatrix) { 7149 /* Create a new matrix type that implements the operation using the full matrix */ 7150 switch (cll) { 7151 case MAT_INITIAL_MATRIX: 7152 ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7153 break; 7154 case MAT_REUSE_MATRIX: 7155 ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7156 break; 7157 default: SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7158 } 7159 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7160 PetscFunctionReturn(0); 7161 } 7162 7163 if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7164 ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7165 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7166 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7167 PetscFunctionReturn(0); 7168 } 7169 7170 #undef __FUNCT__ 7171 #define __FUNCT__ "MatStashSetInitialSize" 7172 /*@ 7173 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7174 used during the assembly process to store values that belong to 7175 other processors. 7176 7177 Not Collective 7178 7179 Input Parameters: 7180 + mat - the matrix 7181 . size - the initial size of the stash. 7182 - bsize - the initial size of the block-stash(if used). 7183 7184 Options Database Keys: 7185 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7186 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7187 7188 Level: intermediate 7189 7190 Notes: 7191 The block-stash is used for values set with MatSetValuesBlocked() while 7192 the stash is used for values set with MatSetValues() 7193 7194 Run with the option -info and look for output of the form 7195 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7196 to determine the appropriate value, MM, to use for size and 7197 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7198 to determine the value, BMM to use for bsize 7199 7200 Concepts: stash^setting matrix size 7201 Concepts: matrices^stash 7202 7203 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7204 7205 @*/ 7206 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7207 { 7208 PetscErrorCode ierr; 7209 7210 PetscFunctionBegin; 7211 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7212 PetscValidType(mat,1); 7213 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7214 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7215 PetscFunctionReturn(0); 7216 } 7217 7218 #undef __FUNCT__ 7219 #define __FUNCT__ "MatInterpolateAdd" 7220 /*@ 7221 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7222 the matrix 7223 7224 Neighbor-wise Collective on Mat 7225 7226 Input Parameters: 7227 + mat - the matrix 7228 . x,y - the vectors 7229 - w - where the result is stored 7230 7231 Level: intermediate 7232 7233 Notes: 7234 w may be the same vector as y. 7235 7236 This allows one to use either the restriction or interpolation (its transpose) 7237 matrix to do the interpolation 7238 7239 Concepts: interpolation 7240 7241 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7242 7243 @*/ 7244 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7245 { 7246 PetscErrorCode ierr; 7247 PetscInt M,N,Ny; 7248 7249 PetscFunctionBegin; 7250 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7251 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7252 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7253 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7254 PetscValidType(A,1); 7255 MatCheckPreallocated(A,1); 7256 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7257 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7258 if (M == Ny) { 7259 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7260 } else { 7261 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7262 } 7263 PetscFunctionReturn(0); 7264 } 7265 7266 #undef __FUNCT__ 7267 #define __FUNCT__ "MatInterpolate" 7268 /*@ 7269 MatInterpolate - y = A*x or A'*x depending on the shape of 7270 the matrix 7271 7272 Neighbor-wise Collective on Mat 7273 7274 Input Parameters: 7275 + mat - the matrix 7276 - x,y - the vectors 7277 7278 Level: intermediate 7279 7280 Notes: 7281 This allows one to use either the restriction or interpolation (its transpose) 7282 matrix to do the interpolation 7283 7284 Concepts: matrices^interpolation 7285 7286 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7287 7288 @*/ 7289 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 7290 { 7291 PetscErrorCode ierr; 7292 PetscInt M,N,Ny; 7293 7294 PetscFunctionBegin; 7295 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7296 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7297 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7298 PetscValidType(A,1); 7299 MatCheckPreallocated(A,1); 7300 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7301 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7302 if (M == Ny) { 7303 ierr = MatMult(A,x,y);CHKERRQ(ierr); 7304 } else { 7305 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 7306 } 7307 PetscFunctionReturn(0); 7308 } 7309 7310 #undef __FUNCT__ 7311 #define __FUNCT__ "MatRestrict" 7312 /*@ 7313 MatRestrict - y = A*x or A'*x 7314 7315 Neighbor-wise Collective on Mat 7316 7317 Input Parameters: 7318 + mat - the matrix 7319 - x,y - the vectors 7320 7321 Level: intermediate 7322 7323 Notes: 7324 This allows one to use either the restriction or interpolation (its transpose) 7325 matrix to do the restriction 7326 7327 Concepts: matrices^restriction 7328 7329 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 7330 7331 @*/ 7332 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 7333 { 7334 PetscErrorCode ierr; 7335 PetscInt M,N,Ny; 7336 7337 PetscFunctionBegin; 7338 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7339 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7340 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7341 PetscValidType(A,1); 7342 MatCheckPreallocated(A,1); 7343 7344 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7345 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7346 if (M == Ny) { 7347 ierr = MatMult(A,x,y);CHKERRQ(ierr); 7348 } else { 7349 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 7350 } 7351 PetscFunctionReturn(0); 7352 } 7353 7354 #undef __FUNCT__ 7355 #define __FUNCT__ "MatGetNullSpace" 7356 /*@ 7357 MatGetNullSpace - retrieves the null space to a matrix. 7358 7359 Logically Collective on Mat and MatNullSpace 7360 7361 Input Parameters: 7362 + mat - the matrix 7363 - nullsp - the null space object 7364 7365 Level: developer 7366 7367 Notes: 7368 This null space is used by solvers. Overwrites any previous null space that may have been attached 7369 7370 Concepts: null space^attaching to matrix 7371 7372 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace() 7373 @*/ 7374 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 7375 { 7376 PetscFunctionBegin; 7377 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7378 PetscValidType(mat,1); 7379 PetscValidPointer(nullsp,2); 7380 *nullsp = mat->nullsp; 7381 PetscFunctionReturn(0); 7382 } 7383 7384 #undef __FUNCT__ 7385 #define __FUNCT__ "MatSetNullSpace" 7386 /*@ 7387 MatSetNullSpace - attaches a null space to a matrix. 7388 This null space will be removed from the resulting vector whenever 7389 MatMult() is called 7390 7391 Logically Collective on Mat and MatNullSpace 7392 7393 Input Parameters: 7394 + mat - the matrix 7395 - nullsp - the null space object 7396 7397 Level: advanced 7398 7399 Notes: 7400 This null space is used by solvers. Overwrites any previous null space that may have been attached 7401 7402 Concepts: null space^attaching to matrix 7403 7404 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace() 7405 @*/ 7406 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 7407 { 7408 PetscErrorCode ierr; 7409 7410 PetscFunctionBegin; 7411 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7412 PetscValidType(mat,1); 7413 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 7414 MatCheckPreallocated(mat,1); 7415 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 7416 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 7417 mat->nullsp = nullsp; 7418 PetscFunctionReturn(0); 7419 } 7420 7421 #undef __FUNCT__ 7422 #define __FUNCT__ "MatSetNearNullSpace" 7423 /*@ 7424 MatSetNearNullSpace - attaches a null space to a matrix. 7425 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 7426 7427 Logically Collective on Mat and MatNullSpace 7428 7429 Input Parameters: 7430 + mat - the matrix 7431 - nullsp - the null space object 7432 7433 Level: advanced 7434 7435 Notes: 7436 Overwrites any previous near null space that may have been attached 7437 7438 Concepts: null space^attaching to matrix 7439 7440 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace() 7441 @*/ 7442 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 7443 { 7444 PetscErrorCode ierr; 7445 7446 PetscFunctionBegin; 7447 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7448 PetscValidType(mat,1); 7449 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 7450 MatCheckPreallocated(mat,1); 7451 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 7452 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 7453 mat->nearnullsp = nullsp; 7454 PetscFunctionReturn(0); 7455 } 7456 7457 #undef __FUNCT__ 7458 #define __FUNCT__ "MatGetNearNullSpace" 7459 /*@ 7460 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 7461 7462 Not Collective 7463 7464 Input Parameters: 7465 . mat - the matrix 7466 7467 Output Parameters: 7468 . nullsp - the null space object, PETSC_NULL if not set 7469 7470 Level: developer 7471 7472 Concepts: null space^attaching to matrix 7473 7474 .seealso: MatSetNearNullSpace(), MatGetNullSpace() 7475 @*/ 7476 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 7477 { 7478 PetscFunctionBegin; 7479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7480 PetscValidType(mat,1); 7481 PetscValidPointer(nullsp,2); 7482 MatCheckPreallocated(mat,1); 7483 *nullsp = mat->nearnullsp; 7484 PetscFunctionReturn(0); 7485 } 7486 7487 #undef __FUNCT__ 7488 #define __FUNCT__ "MatICCFactor" 7489 /*@C 7490 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 7491 7492 Collective on Mat 7493 7494 Input Parameters: 7495 + mat - the matrix 7496 . row - row/column permutation 7497 . fill - expected fill factor >= 1.0 7498 - level - level of fill, for ICC(k) 7499 7500 Notes: 7501 Probably really in-place only when level of fill is zero, otherwise allocates 7502 new space to store factored matrix and deletes previous memory. 7503 7504 Most users should employ the simplified KSP interface for linear solvers 7505 instead of working directly with matrix algebra routines such as this. 7506 See, e.g., KSPCreate(). 7507 7508 Level: developer 7509 7510 Concepts: matrices^incomplete Cholesky factorization 7511 Concepts: Cholesky factorization 7512 7513 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 7514 7515 Developer Note: fortran interface is not autogenerated as the f90 7516 interface defintion cannot be generated correctly [due to MatFactorInfo] 7517 7518 @*/ 7519 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo* info) 7520 { 7521 PetscErrorCode ierr; 7522 7523 PetscFunctionBegin; 7524 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7525 PetscValidType(mat,1); 7526 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 7527 PetscValidPointer(info,3); 7528 if (mat->rmap->N != mat->cmap->N) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONG,"matrix must be square"); 7529 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7530 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7531 if (!mat->ops->iccfactor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7532 MatCheckPreallocated(mat,1); 7533 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 7534 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7535 PetscFunctionReturn(0); 7536 } 7537 7538 #undef __FUNCT__ 7539 #define __FUNCT__ "MatSetValuesAdic" 7540 /*@ 7541 MatSetValuesAdic - Sets values computed with ADIC automatic differentiation into a matrix. 7542 7543 Not Collective 7544 7545 Input Parameters: 7546 + mat - the matrix 7547 - v - the values compute with ADIC 7548 7549 Level: developer 7550 7551 Notes: 7552 Must call MatSetColoring() before using this routine. Also this matrix must already 7553 have its nonzero pattern determined. 7554 7555 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 7556 MatSetValues(), MatSetColoring(), MatSetValuesAdifor() 7557 @*/ 7558 PetscErrorCode MatSetValuesAdic(Mat mat,void *v) 7559 { 7560 PetscErrorCode ierr; 7561 7562 PetscFunctionBegin; 7563 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7564 PetscValidType(mat,1); 7565 PetscValidPointer(mat,2); 7566 7567 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7568 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7569 if (!mat->ops->setvaluesadic) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7570 ierr = (*mat->ops->setvaluesadic)(mat,v);CHKERRQ(ierr); 7571 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7572 ierr = MatViewFromOptions(mat,"-mat_view");CHKERRQ(ierr); 7573 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7574 PetscFunctionReturn(0); 7575 } 7576 7577 7578 #undef __FUNCT__ 7579 #define __FUNCT__ "MatSetColoring" 7580 /*@ 7581 MatSetColoring - Sets a coloring used by calls to MatSetValuesAdic() 7582 7583 Not Collective 7584 7585 Input Parameters: 7586 + mat - the matrix 7587 - coloring - the coloring 7588 7589 Level: developer 7590 7591 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 7592 MatSetValues(), MatSetValuesAdic() 7593 @*/ 7594 PetscErrorCode MatSetColoring(Mat mat,ISColoring coloring) 7595 { 7596 PetscErrorCode ierr; 7597 7598 PetscFunctionBegin; 7599 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7600 PetscValidType(mat,1); 7601 PetscValidPointer(coloring,2); 7602 7603 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7604 if (!mat->ops->setcoloring) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7605 ierr = (*mat->ops->setcoloring)(mat,coloring);CHKERRQ(ierr); 7606 PetscFunctionReturn(0); 7607 } 7608 7609 #undef __FUNCT__ 7610 #define __FUNCT__ "MatSetValuesAdifor" 7611 /*@ 7612 MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix. 7613 7614 Not Collective 7615 7616 Input Parameters: 7617 + mat - the matrix 7618 . nl - leading dimension of v 7619 - v - the values compute with ADIFOR 7620 7621 Level: developer 7622 7623 Notes: 7624 Must call MatSetColoring() before using this routine. Also this matrix must already 7625 have its nonzero pattern determined. 7626 7627 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 7628 MatSetValues(), MatSetColoring() 7629 @*/ 7630 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v) 7631 { 7632 PetscErrorCode ierr; 7633 7634 PetscFunctionBegin; 7635 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7636 PetscValidType(mat,1); 7637 PetscValidPointer(v,3); 7638 7639 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7640 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7641 if (!mat->ops->setvaluesadifor) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7642 ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr); 7643 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7644 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7645 PetscFunctionReturn(0); 7646 } 7647 7648 #undef __FUNCT__ 7649 #define __FUNCT__ "MatDiagonalScaleLocal" 7650 /*@ 7651 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 7652 ghosted ones. 7653 7654 Not Collective 7655 7656 Input Parameters: 7657 + mat - the matrix 7658 - diag = the diagonal values, including ghost ones 7659 7660 Level: developer 7661 7662 Notes: Works only for MPIAIJ and MPIBAIJ matrices 7663 7664 .seealso: MatDiagonalScale() 7665 @*/ 7666 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 7667 { 7668 PetscErrorCode ierr; 7669 PetscMPIInt size; 7670 7671 PetscFunctionBegin; 7672 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7673 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 7674 PetscValidType(mat,1); 7675 7676 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7677 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 7678 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr); 7679 if (size == 1) { 7680 PetscInt n,m; 7681 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 7682 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 7683 if (m == n) { 7684 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 7685 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 7686 } else { 7687 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 7688 } 7689 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 7690 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7691 PetscFunctionReturn(0); 7692 } 7693 7694 #undef __FUNCT__ 7695 #define __FUNCT__ "MatGetInertia" 7696 /*@ 7697 MatGetInertia - Gets the inertia from a factored matrix 7698 7699 Collective on Mat 7700 7701 Input Parameter: 7702 . mat - the matrix 7703 7704 Output Parameters: 7705 + nneg - number of negative eigenvalues 7706 . nzero - number of zero eigenvalues 7707 - npos - number of positive eigenvalues 7708 7709 Level: advanced 7710 7711 Notes: Matrix must have been factored by MatCholeskyFactor() 7712 7713 7714 @*/ 7715 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 7716 { 7717 PetscErrorCode ierr; 7718 7719 PetscFunctionBegin; 7720 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7721 PetscValidType(mat,1); 7722 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 7723 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 7724 if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7725 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 7726 PetscFunctionReturn(0); 7727 } 7728 7729 /* ----------------------------------------------------------------*/ 7730 #undef __FUNCT__ 7731 #define __FUNCT__ "MatSolves" 7732 /*@C 7733 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 7734 7735 Neighbor-wise Collective on Mat and Vecs 7736 7737 Input Parameters: 7738 + mat - the factored matrix 7739 - b - the right-hand-side vectors 7740 7741 Output Parameter: 7742 . x - the result vectors 7743 7744 Notes: 7745 The vectors b and x cannot be the same. I.e., one cannot 7746 call MatSolves(A,x,x). 7747 7748 Notes: 7749 Most users should employ the simplified KSP interface for linear solvers 7750 instead of working directly with matrix algebra routines such as this. 7751 See, e.g., KSPCreate(). 7752 7753 Level: developer 7754 7755 Concepts: matrices^triangular solves 7756 7757 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 7758 @*/ 7759 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 7760 { 7761 PetscErrorCode ierr; 7762 7763 PetscFunctionBegin; 7764 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7765 PetscValidType(mat,1); 7766 if (x == b) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 7767 if (!mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 7768 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 7769 7770 if (!mat->ops->solves) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7771 MatCheckPreallocated(mat,1); 7772 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 7773 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 7774 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 7775 PetscFunctionReturn(0); 7776 } 7777 7778 #undef __FUNCT__ 7779 #define __FUNCT__ "MatIsSymmetric" 7780 /*@ 7781 MatIsSymmetric - Test whether a matrix is symmetric 7782 7783 Collective on Mat 7784 7785 Input Parameter: 7786 + A - the matrix to test 7787 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 7788 7789 Output Parameters: 7790 . flg - the result 7791 7792 Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 7793 7794 Level: intermediate 7795 7796 Concepts: matrix^symmetry 7797 7798 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 7799 @*/ 7800 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 7801 { 7802 PetscErrorCode ierr; 7803 7804 PetscFunctionBegin; 7805 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7806 PetscValidPointer(flg,2); 7807 7808 if (!A->symmetric_set) { 7809 if (!A->ops->issymmetric) { 7810 MatType mattype; 7811 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7812 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 7813 } 7814 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 7815 if (!tol) { 7816 A->symmetric_set = PETSC_TRUE; 7817 A->symmetric = *flg; 7818 if (A->symmetric) { 7819 A->structurally_symmetric_set = PETSC_TRUE; 7820 A->structurally_symmetric = PETSC_TRUE; 7821 } 7822 } 7823 } else if (A->symmetric) { 7824 *flg = PETSC_TRUE; 7825 } else if (!tol) { 7826 *flg = PETSC_FALSE; 7827 } else { 7828 if (!A->ops->issymmetric) { 7829 MatType mattype; 7830 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7831 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 7832 } 7833 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 7834 } 7835 PetscFunctionReturn(0); 7836 } 7837 7838 #undef __FUNCT__ 7839 #define __FUNCT__ "MatIsHermitian" 7840 /*@ 7841 MatIsHermitian - Test whether a matrix is Hermitian 7842 7843 Collective on Mat 7844 7845 Input Parameter: 7846 + A - the matrix to test 7847 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 7848 7849 Output Parameters: 7850 . flg - the result 7851 7852 Level: intermediate 7853 7854 Concepts: matrix^symmetry 7855 7856 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 7857 MatIsSymmetricKnown(), MatIsSymmetric() 7858 @*/ 7859 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 7860 { 7861 PetscErrorCode ierr; 7862 7863 PetscFunctionBegin; 7864 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7865 PetscValidPointer(flg,2); 7866 7867 if (!A->hermitian_set) { 7868 if (!A->ops->ishermitian) { 7869 MatType mattype; 7870 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7871 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 7872 } 7873 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 7874 if (!tol) { 7875 A->hermitian_set = PETSC_TRUE; 7876 A->hermitian = *flg; 7877 if (A->hermitian) { 7878 A->structurally_symmetric_set = PETSC_TRUE; 7879 A->structurally_symmetric = PETSC_TRUE; 7880 } 7881 } 7882 } else if (A->hermitian) { 7883 *flg = PETSC_TRUE; 7884 } else if (!tol) { 7885 *flg = PETSC_FALSE; 7886 } else { 7887 if (!A->ops->ishermitian) { 7888 MatType mattype; 7889 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7890 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 7891 } 7892 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 7893 } 7894 PetscFunctionReturn(0); 7895 } 7896 7897 #undef __FUNCT__ 7898 #define __FUNCT__ "MatIsSymmetricKnown" 7899 /*@ 7900 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 7901 7902 Not Collective 7903 7904 Input Parameter: 7905 . A - the matrix to check 7906 7907 Output Parameters: 7908 + set - if the symmetric flag is set (this tells you if the next flag is valid) 7909 - flg - the result 7910 7911 Level: advanced 7912 7913 Concepts: matrix^symmetry 7914 7915 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 7916 if you want it explicitly checked 7917 7918 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 7919 @*/ 7920 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 7921 { 7922 PetscFunctionBegin; 7923 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7924 PetscValidPointer(set,2); 7925 PetscValidPointer(flg,3); 7926 if (A->symmetric_set) { 7927 *set = PETSC_TRUE; 7928 *flg = A->symmetric; 7929 } else { 7930 *set = PETSC_FALSE; 7931 } 7932 PetscFunctionReturn(0); 7933 } 7934 7935 #undef __FUNCT__ 7936 #define __FUNCT__ "MatIsHermitianKnown" 7937 /*@ 7938 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 7939 7940 Not Collective 7941 7942 Input Parameter: 7943 . A - the matrix to check 7944 7945 Output Parameters: 7946 + set - if the hermitian flag is set (this tells you if the next flag is valid) 7947 - flg - the result 7948 7949 Level: advanced 7950 7951 Concepts: matrix^symmetry 7952 7953 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 7954 if you want it explicitly checked 7955 7956 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 7957 @*/ 7958 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 7959 { 7960 PetscFunctionBegin; 7961 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7962 PetscValidPointer(set,2); 7963 PetscValidPointer(flg,3); 7964 if (A->hermitian_set) { 7965 *set = PETSC_TRUE; 7966 *flg = A->hermitian; 7967 } else { 7968 *set = PETSC_FALSE; 7969 } 7970 PetscFunctionReturn(0); 7971 } 7972 7973 #undef __FUNCT__ 7974 #define __FUNCT__ "MatIsStructurallySymmetric" 7975 /*@ 7976 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 7977 7978 Collective on Mat 7979 7980 Input Parameter: 7981 . A - the matrix to test 7982 7983 Output Parameters: 7984 . flg - the result 7985 7986 Level: intermediate 7987 7988 Concepts: matrix^symmetry 7989 7990 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 7991 @*/ 7992 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 7993 { 7994 PetscErrorCode ierr; 7995 7996 PetscFunctionBegin; 7997 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7998 PetscValidPointer(flg,2); 7999 if (!A->structurally_symmetric_set) { 8000 if (!A->ops->isstructurallysymmetric) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8001 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8002 A->structurally_symmetric_set = PETSC_TRUE; 8003 } 8004 *flg = A->structurally_symmetric; 8005 PetscFunctionReturn(0); 8006 } 8007 8008 #undef __FUNCT__ 8009 #define __FUNCT__ "MatStashGetInfo" 8010 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*); 8011 /*@ 8012 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8013 to be communicated to other processors during the MatAssemblyBegin/End() process 8014 8015 Not collective 8016 8017 Input Parameter: 8018 . vec - the vector 8019 8020 Output Parameters: 8021 + nstash - the size of the stash 8022 . reallocs - the number of additional mallocs incurred. 8023 . bnstash - the size of the block stash 8024 - breallocs - the number of additional mallocs incurred.in the block stash 8025 8026 Level: advanced 8027 8028 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8029 8030 @*/ 8031 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8032 { 8033 PetscErrorCode ierr; 8034 8035 PetscFunctionBegin; 8036 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8037 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8038 PetscFunctionReturn(0); 8039 } 8040 8041 #undef __FUNCT__ 8042 #define __FUNCT__ "MatGetVecs" 8043 /*@C 8044 MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 8045 parallel layout 8046 8047 Collective on Mat 8048 8049 Input Parameter: 8050 . mat - the matrix 8051 8052 Output Parameter: 8053 + right - (optional) vector that the matrix can be multiplied against 8054 - left - (optional) vector that the matrix vector product can be stored in 8055 8056 Level: advanced 8057 8058 .seealso: MatCreate() 8059 @*/ 8060 PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left) 8061 { 8062 PetscErrorCode ierr; 8063 8064 PetscFunctionBegin; 8065 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8066 PetscValidType(mat,1); 8067 MatCheckPreallocated(mat,1); 8068 if (mat->ops->getvecs) { 8069 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8070 } else { 8071 PetscMPIInt size; 8072 ierr = MPI_Comm_size(((PetscObject)mat)->comm, &size);CHKERRQ(ierr); 8073 if (right) { 8074 ierr = VecCreate(((PetscObject)mat)->comm,right);CHKERRQ(ierr); 8075 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8076 ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr); 8077 ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr); 8078 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8079 } 8080 if (left) { 8081 ierr = VecCreate(((PetscObject)mat)->comm,left);CHKERRQ(ierr); 8082 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8083 ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr); 8084 ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr); 8085 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8086 } 8087 } 8088 PetscFunctionReturn(0); 8089 } 8090 8091 #undef __FUNCT__ 8092 #define __FUNCT__ "MatFactorInfoInitialize" 8093 /*@C 8094 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8095 with default values. 8096 8097 Not Collective 8098 8099 Input Parameters: 8100 . info - the MatFactorInfo data structure 8101 8102 8103 Notes: The solvers are generally used through the KSP and PC objects, for example 8104 PCLU, PCILU, PCCHOLESKY, PCICC 8105 8106 Level: developer 8107 8108 .seealso: MatFactorInfo 8109 8110 Developer Note: fortran interface is not autogenerated as the f90 8111 interface defintion cannot be generated correctly [due to MatFactorInfo] 8112 8113 @*/ 8114 8115 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8116 { 8117 PetscErrorCode ierr; 8118 8119 PetscFunctionBegin; 8120 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8121 PetscFunctionReturn(0); 8122 } 8123 8124 #undef __FUNCT__ 8125 #define __FUNCT__ "MatPtAP" 8126 /*@ 8127 MatPtAP - Creates the matrix product C = P^T * A * P 8128 8129 Neighbor-wise Collective on Mat 8130 8131 Input Parameters: 8132 + A - the matrix 8133 . P - the projection matrix 8134 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8135 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)) 8136 8137 Output Parameters: 8138 . C - the product matrix 8139 8140 Notes: 8141 C will be created and must be destroyed by the user with MatDestroy(). 8142 8143 This routine is currently only implemented for pairs of AIJ matrices and classes 8144 which inherit from AIJ. 8145 8146 Level: intermediate 8147 8148 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 8149 @*/ 8150 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 8151 { 8152 PetscErrorCode ierr; 8153 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8154 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 8155 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=PETSC_NULL; 8156 PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE; 8157 8158 PetscFunctionBegin; 8159 ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,PETSC_NULL);CHKERRQ(ierr); 8160 ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,PETSC_NULL);CHKERRQ(ierr); 8161 8162 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8163 PetscValidType(A,1); 8164 MatCheckPreallocated(A,1); 8165 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8166 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8167 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8168 PetscValidType(P,2); 8169 MatCheckPreallocated(P,2); 8170 if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8171 if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8172 8173 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); 8174 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8175 8176 if (scall == MAT_REUSE_MATRIX) { 8177 PetscValidPointer(*C,5); 8178 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 8179 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8180 if (viatranspose || viamatmatmatmult){ 8181 Mat Pt; 8182 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 8183 if (viamatmatmatmult){ 8184 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 8185 } else { 8186 Mat AP; 8187 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 8188 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 8189 ierr = MatDestroy(&AP);CHKERRQ(ierr); 8190 } 8191 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 8192 } else { 8193 ierr = (*(*C)->ops->ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 8194 } 8195 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8196 PetscFunctionReturn(0); 8197 } 8198 8199 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8200 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8201 8202 fA = A->ops->ptap; 8203 fP = P->ops->ptap; 8204 if (fP == fA) { 8205 if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 8206 ptap = fA; 8207 } else { 8208 /* dispatch based on the type of A and P from their PetscObject's PetscFLists. */ 8209 char ptapname[256]; 8210 ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr); 8211 ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8212 ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr); 8213 ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr); 8214 ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 8215 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,(void (**)(void))&ptap);CHKERRQ(ierr); 8216 if (!ptap) { 8217 /* dual dispatch using MatQueryOp */ 8218 ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&ptap), "MatPtAP",2,((PetscObject)A)->type_name,((PetscObject)P)->type_name); CHKERRQ(ierr); 8219 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); 8220 } 8221 } 8222 8223 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8224 if (viatranspose || viamatmatmatmult) { 8225 Mat Pt; 8226 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 8227 if (viamatmatmatmult){ 8228 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 8229 ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr); 8230 } else { 8231 Mat AP; 8232 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 8233 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 8234 ierr = MatDestroy(&AP);CHKERRQ(ierr); 8235 ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr); 8236 } 8237 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 8238 } else { 8239 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 8240 } 8241 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8242 PetscFunctionReturn(0); 8243 } 8244 8245 #undef __FUNCT__ 8246 #define __FUNCT__ "MatPtAPNumeric" 8247 /*@ 8248 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 8249 8250 Neighbor-wise Collective on Mat 8251 8252 Input Parameters: 8253 + A - the matrix 8254 - P - the projection matrix 8255 8256 Output Parameters: 8257 . C - the product matrix 8258 8259 Notes: 8260 C must have been created by calling MatPtAPSymbolic and must be destroyed by 8261 the user using MatDeatroy(). 8262 8263 This routine is currently only implemented for pairs of AIJ matrices and classes 8264 which inherit from AIJ. C will be of type MATAIJ. 8265 8266 Level: intermediate 8267 8268 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 8269 @*/ 8270 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 8271 { 8272 PetscErrorCode ierr; 8273 8274 PetscFunctionBegin; 8275 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8276 PetscValidType(A,1); 8277 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8278 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8279 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8280 PetscValidType(P,2); 8281 MatCheckPreallocated(P,2); 8282 if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8283 if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8284 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8285 PetscValidType(C,3); 8286 MatCheckPreallocated(C,3); 8287 if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8288 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); 8289 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); 8290 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); 8291 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); 8292 MatCheckPreallocated(A,1); 8293 8294 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8295 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 8296 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8297 PetscFunctionReturn(0); 8298 } 8299 8300 #undef __FUNCT__ 8301 #define __FUNCT__ "MatPtAPSymbolic" 8302 /*@ 8303 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 8304 8305 Neighbor-wise Collective on Mat 8306 8307 Input Parameters: 8308 + A - the matrix 8309 - P - the projection matrix 8310 8311 Output Parameters: 8312 . C - the (i,j) structure of the product matrix 8313 8314 Notes: 8315 C will be created and must be destroyed by the user with MatDestroy(). 8316 8317 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 8318 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 8319 this (i,j) structure by calling MatPtAPNumeric(). 8320 8321 Level: intermediate 8322 8323 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 8324 @*/ 8325 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 8326 { 8327 PetscErrorCode ierr; 8328 8329 PetscFunctionBegin; 8330 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8331 PetscValidType(A,1); 8332 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8333 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8334 if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8335 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8336 PetscValidType(P,2); 8337 MatCheckPreallocated(P,2); 8338 if (!P->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8339 if (P->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8340 PetscValidPointer(C,3); 8341 8342 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); 8343 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); 8344 MatCheckPreallocated(A,1); 8345 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 8346 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 8347 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 8348 8349 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 8350 PetscFunctionReturn(0); 8351 } 8352 8353 #undef __FUNCT__ 8354 #define __FUNCT__ "MatRARt" 8355 /*@ 8356 MatRARt - Creates the matrix product C = R * A * R^T 8357 8358 Neighbor-wise Collective on Mat 8359 8360 Input Parameters: 8361 + A - the matrix 8362 . R - the projection matrix 8363 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8364 - fill - expected fill as ratio of nnz(C)/nnz(A) 8365 8366 Output Parameters: 8367 . C - the product matrix 8368 8369 Notes: 8370 C will be created and must be destroyed by the user with MatDestroy(). 8371 8372 This routine is currently only implemented for pairs of AIJ matrices and classes 8373 which inherit from AIJ. 8374 8375 Level: intermediate 8376 8377 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 8378 @*/ 8379 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 8380 { 8381 PetscErrorCode ierr; 8382 8383 PetscFunctionBegin; 8384 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8385 PetscValidType(A,1); 8386 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8387 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8388 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8389 PetscValidType(R,2); 8390 MatCheckPreallocated(R,2); 8391 if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8392 if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8393 PetscValidPointer(C,3); 8394 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); 8395 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8396 MatCheckPreallocated(A,1); 8397 8398 if (!A->ops->rart) { 8399 MatType mattype; 8400 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8401 SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype); 8402 } 8403 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 8404 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 8405 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 8406 PetscFunctionReturn(0); 8407 } 8408 8409 #undef __FUNCT__ 8410 #define __FUNCT__ "MatRARtNumeric" 8411 /*@ 8412 MatRARtNumeric - Computes the matrix product C = R * A * R^T 8413 8414 Neighbor-wise Collective on Mat 8415 8416 Input Parameters: 8417 + A - the matrix 8418 - R - the projection matrix 8419 8420 Output Parameters: 8421 . C - the product matrix 8422 8423 Notes: 8424 C must have been created by calling MatRARtSymbolic and must be destroyed by 8425 the user using MatDeatroy(). 8426 8427 This routine is currently only implemented for pairs of AIJ matrices and classes 8428 which inherit from AIJ. C will be of type MATAIJ. 8429 8430 Level: intermediate 8431 8432 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 8433 @*/ 8434 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 8435 { 8436 PetscErrorCode ierr; 8437 8438 PetscFunctionBegin; 8439 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8440 PetscValidType(A,1); 8441 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8442 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8443 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8444 PetscValidType(R,2); 8445 MatCheckPreallocated(R,2); 8446 if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8447 if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8448 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8449 PetscValidType(C,3); 8450 MatCheckPreallocated(C,3); 8451 if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8452 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); 8453 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); 8454 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); 8455 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); 8456 MatCheckPreallocated(A,1); 8457 8458 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 8459 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 8460 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 8461 PetscFunctionReturn(0); 8462 } 8463 8464 #undef __FUNCT__ 8465 #define __FUNCT__ "MatRARtSymbolic" 8466 /*@ 8467 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 8468 8469 Neighbor-wise Collective on Mat 8470 8471 Input Parameters: 8472 + A - the matrix 8473 - R - the projection matrix 8474 8475 Output Parameters: 8476 . C - the (i,j) structure of the product matrix 8477 8478 Notes: 8479 C will be created and must be destroyed by the user with MatDestroy(). 8480 8481 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 8482 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 8483 this (i,j) structure by calling MatRARtNumeric(). 8484 8485 Level: intermediate 8486 8487 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 8488 @*/ 8489 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 8490 { 8491 PetscErrorCode ierr; 8492 8493 PetscFunctionBegin; 8494 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8495 PetscValidType(A,1); 8496 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8497 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8498 if (fill <1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8499 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8500 PetscValidType(R,2); 8501 MatCheckPreallocated(R,2); 8502 if (!R->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8503 if (R->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8504 PetscValidPointer(C,3); 8505 8506 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); 8507 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); 8508 MatCheckPreallocated(A,1); 8509 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 8510 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 8511 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 8512 8513 ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); 8514 PetscFunctionReturn(0); 8515 } 8516 8517 extern PetscErrorCode MatQueryOp(MPI_Comm comm, void (**function)(void), const char op[], PetscInt numArgs, ...); 8518 8519 #undef __FUNCT__ 8520 #define __FUNCT__ "MatMatMult" 8521 /*@ 8522 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 8523 8524 Neighbor-wise Collective on Mat 8525 8526 Input Parameters: 8527 + A - the left matrix 8528 . B - the right matrix 8529 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8530 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 8531 if the result is a dense matrix this is irrelevent 8532 8533 Output Parameters: 8534 . C - the product matrix 8535 8536 Notes: 8537 Unless scall is MAT_REUSE_MATRIX C will be created. 8538 8539 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8540 8541 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8542 actually needed. 8543 8544 If you have many matrices with the same non-zero structure to multiply, you 8545 should either 8546 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 8547 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 8548 8549 Level: intermediate 8550 8551 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 8552 @*/ 8553 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8554 { 8555 PetscErrorCode ierr; 8556 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8557 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8558 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL; 8559 8560 PetscFunctionBegin; 8561 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8562 PetscValidType(A,1); 8563 MatCheckPreallocated(A,1); 8564 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8565 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8566 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8567 PetscValidType(B,2); 8568 MatCheckPreallocated(B,2); 8569 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8570 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8571 PetscValidPointer(C,3); 8572 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); 8573 if (scall == MAT_REUSE_MATRIX) { 8574 PetscValidPointer(*C,5); 8575 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 8576 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8577 ierr = (*(*C)->ops->matmult)(A,B,scall,fill,C);CHKERRQ(ierr); 8578 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8579 PetscFunctionReturn(0); 8580 } 8581 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8582 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8583 8584 fA = A->ops->matmult; 8585 fB = B->ops->matmult; 8586 if (fB == fA) { 8587 if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 8588 mult = fB; 8589 } else { 8590 /* dispatch based on the type of A and B from their PetscObject's PetscFLists. */ 8591 char multname[256]; 8592 ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr); 8593 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8594 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 8595 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8596 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 8597 ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr); 8598 if (!mult) { 8599 /* dual dispatch using MatQueryOp */ 8600 ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr); 8601 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); 8602 } 8603 } 8604 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8605 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 8606 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8607 PetscFunctionReturn(0); 8608 } 8609 8610 #undef __FUNCT__ 8611 #define __FUNCT__ "MatMatMultSymbolic" 8612 /*@ 8613 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 8614 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 8615 8616 Neighbor-wise Collective on Mat 8617 8618 Input Parameters: 8619 + A - the left matrix 8620 . B - the right matrix 8621 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 8622 if C is a dense matrix this is irrelevent 8623 8624 Output Parameters: 8625 . C - the product matrix 8626 8627 Notes: 8628 Unless scall is MAT_REUSE_MATRIX C will be created. 8629 8630 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8631 actually needed. 8632 8633 This routine is currently implemented for 8634 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 8635 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 8636 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 8637 8638 Level: intermediate 8639 8640 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 8641 We should incorporate them into PETSc. 8642 8643 .seealso: MatMatMult(), MatMatMultNumeric() 8644 @*/ 8645 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 8646 { 8647 PetscErrorCode ierr; 8648 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat *); 8649 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat *); 8650 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat *)=PETSC_NULL; 8651 8652 PetscFunctionBegin; 8653 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8654 PetscValidType(A,1); 8655 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8656 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8657 8658 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8659 PetscValidType(B,2); 8660 MatCheckPreallocated(B,2); 8661 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8662 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8663 PetscValidPointer(C,3); 8664 8665 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); 8666 if (fill == PETSC_DEFAULT) fill = 2.0; 8667 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8668 MatCheckPreallocated(A,1); 8669 8670 Asymbolic = A->ops->matmultsymbolic; 8671 Bsymbolic = B->ops->matmultsymbolic; 8672 if (Asymbolic == Bsymbolic) { 8673 if (!Bsymbolic) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 8674 symbolic = Bsymbolic; 8675 } else { /* dispatch based on the type of A and B */ 8676 char symbolicname[256]; 8677 ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr); 8678 ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8679 ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr); 8680 ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8681 ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr); 8682 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,(void (**)(void))&symbolic);CHKERRQ(ierr); 8683 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); 8684 } 8685 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8686 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 8687 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8688 PetscFunctionReturn(0); 8689 } 8690 8691 #undef __FUNCT__ 8692 #define __FUNCT__ "MatMatMultNumeric" 8693 /*@ 8694 MatMatMultNumeric - Performs the numeric matrix-matrix product. 8695 Call this routine after first calling MatMatMultSymbolic(). 8696 8697 Neighbor-wise Collective on Mat 8698 8699 Input Parameters: 8700 + A - the left matrix 8701 - B - the right matrix 8702 8703 Output Parameters: 8704 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 8705 8706 Notes: 8707 C must have been created with MatMatMultSymbolic(). 8708 8709 This routine is currently implemented for 8710 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 8711 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 8712 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 8713 8714 Level: intermediate 8715 8716 .seealso: MatMatMult(), MatMatMultSymbolic() 8717 @*/ 8718 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 8719 { 8720 PetscErrorCode ierr; 8721 PetscErrorCode (*Anumeric)(Mat,Mat,Mat); 8722 PetscErrorCode (*Bnumeric)(Mat,Mat,Mat); 8723 PetscErrorCode (*numeric)(Mat,Mat,Mat)=PETSC_NULL; 8724 8725 PetscFunctionBegin; 8726 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8727 PetscValidType(A,1); 8728 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8729 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8730 8731 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8732 PetscValidType(B,2); 8733 MatCheckPreallocated(B,2); 8734 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8735 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8736 8737 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8738 PetscValidType(C,3); 8739 MatCheckPreallocated(C,3); 8740 if (!C->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8741 if (C->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8742 8743 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); 8744 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); 8745 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); 8746 MatCheckPreallocated(A,1); 8747 8748 Anumeric = A->ops->matmultnumeric; 8749 Bnumeric = B->ops->matmultnumeric; 8750 if (Anumeric == Bnumeric) { 8751 if (!Bnumeric) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMultNumeric not supported for B of type %s",((PetscObject)B)->type_name); 8752 numeric = Bnumeric; 8753 } else { 8754 char numericname[256]; 8755 ierr = PetscStrcpy(numericname,"MatMatMultNumeric_");CHKERRQ(ierr); 8756 ierr = PetscStrcat(numericname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8757 ierr = PetscStrcat(numericname,"_");CHKERRQ(ierr); 8758 ierr = PetscStrcat(numericname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8759 ierr = PetscStrcat(numericname,"_C");CHKERRQ(ierr); 8760 ierr = PetscObjectQueryFunction((PetscObject)B,numericname,(void (**)(void))&numeric);CHKERRQ(ierr); 8761 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); 8762 } 8763 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8764 ierr = (*numeric)(A,B,C);CHKERRQ(ierr); 8765 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8766 PetscFunctionReturn(0); 8767 } 8768 8769 #undef __FUNCT__ 8770 #define __FUNCT__ "MatMatTransposeMult" 8771 /*@ 8772 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 8773 8774 Neighbor-wise Collective on Mat 8775 8776 Input Parameters: 8777 + A - the left matrix 8778 . B - the right matrix 8779 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8780 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 8781 8782 Output Parameters: 8783 . C - the product matrix 8784 8785 Notes: 8786 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 8787 8788 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8789 8790 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8791 actually needed. 8792 8793 This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ. 8794 8795 Level: intermediate 8796 8797 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 8798 @*/ 8799 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8800 { 8801 PetscErrorCode ierr; 8802 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8803 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8804 8805 PetscFunctionBegin; 8806 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8807 PetscValidType(A,1); 8808 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8809 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8810 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8811 PetscValidType(B,2); 8812 MatCheckPreallocated(B,2); 8813 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8814 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8815 PetscValidPointer(C,3); 8816 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); 8817 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8818 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8819 MatCheckPreallocated(A,1); 8820 8821 fA = A->ops->mattransposemult; 8822 if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 8823 fB = B->ops->mattransposemult; 8824 if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 8825 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); 8826 8827 if (scall == MAT_INITIAL_MATRIX) { 8828 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8829 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 8830 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8831 } 8832 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 8833 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 8834 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 8835 PetscFunctionReturn(0); 8836 } 8837 8838 #undef __FUNCT__ 8839 #define __FUNCT__ "MatTransposeMatMult" 8840 /*@ 8841 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 8842 8843 Neighbor-wise Collective on Mat 8844 8845 Input Parameters: 8846 + A - the left matrix 8847 . B - the right matrix 8848 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8849 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 8850 8851 Output Parameters: 8852 . C - the product matrix 8853 8854 Notes: 8855 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 8856 8857 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8858 8859 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8860 actually needed. 8861 8862 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 8863 which inherit from SeqAIJ. C will be of same type as the input matrices. 8864 8865 Level: intermediate 8866 8867 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 8868 @*/ 8869 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8870 { 8871 PetscErrorCode ierr; 8872 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8873 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8874 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*); 8875 8876 PetscFunctionBegin; 8877 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8878 PetscValidType(A,1); 8879 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8880 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8881 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8882 PetscValidType(B,2); 8883 MatCheckPreallocated(B,2); 8884 if (!B->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8885 if (B->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8886 PetscValidPointer(C,3); 8887 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); 8888 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8889 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8890 MatCheckPreallocated(A,1); 8891 8892 fA = A->ops->transposematmult; 8893 if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 8894 fB = B->ops->transposematmult; 8895 if (!fB) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name); 8896 if (fB==fA) { 8897 transposematmult = fA; 8898 } else { 8899 /* dual dispatch using MatQueryOp */ 8900 ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&transposematmult), "MatTansposeMatMult",2,((PetscObject)A)->type_name,((PetscObject)B)->type_name); CHKERRQ(ierr); 8901 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); 8902 } 8903 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 8904 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 8905 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 8906 PetscFunctionReturn(0); 8907 } 8908 8909 #undef __FUNCT__ 8910 #define __FUNCT__ "MatMatMatMult" 8911 /*@ 8912 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 8913 8914 Neighbor-wise Collective on Mat 8915 8916 Input Parameters: 8917 + A - the left matrix 8918 . B - the middle matrix 8919 . C - the right matrix 8920 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8921 - 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 8922 if the result is a dense matrix this is irrelevent 8923 8924 Output Parameters: 8925 . D - the product matrix 8926 8927 Notes: 8928 Unless scall is MAT_REUSE_MATRIX D will be created. 8929 8930 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 8931 8932 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8933 actually needed. 8934 8935 If you have many matrices with the same non-zero structure to multiply, you 8936 should either 8937 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 8938 $ 2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed 8939 8940 Level: intermediate 8941 8942 .seealso: MatMatMult, MatPtAP() 8943 @*/ 8944 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 8945 { 8946 PetscErrorCode ierr; 8947 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 8948 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 8949 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 8950 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat *)=PETSC_NULL; 8951 8952 PetscFunctionBegin; 8953 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8954 PetscValidType(A,1); 8955 MatCheckPreallocated(A,1); 8956 if (!A->assembled) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8957 if (A->factortype) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8958 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8959 PetscValidType(B,2); 8960 MatCheckPreallocated(B,2); 8961 if (!B->assembled) SETERRQ(((PetscObject)B)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8962 if (B->factortype) SETERRQ(((PetscObject)B)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8963 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8964 PetscValidPointer(C,3); 8965 MatCheckPreallocated(C,3); 8966 if (!C->assembled) SETERRQ(((PetscObject)C)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8967 if (C->factortype) SETERRQ(((PetscObject)C)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8968 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); 8969 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); 8970 if (scall == MAT_REUSE_MATRIX) { 8971 PetscValidPointer(*D,6); 8972 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 8973 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 8974 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 8975 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 8976 PetscFunctionReturn(0); 8977 } 8978 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8979 if (fill < 1.0) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8980 8981 fA = A->ops->matmatmult; 8982 fB = B->ops->matmatmult; 8983 fC = C->ops->matmatmult; 8984 if (fA == fB && fA == fC) { 8985 if (!fA) SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 8986 mult = fA; 8987 } else { 8988 /* dispatch based on the type of A, B and C from their PetscObject's PetscFLists. */ 8989 char multname[256]; 8990 ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr); 8991 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8992 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 8993 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8994 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 8995 ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr); 8996 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); 8997 ierr = PetscObjectQueryFunction((PetscObject)B,multname,(void (**)(void))&mult);CHKERRQ(ierr); 8998 if (!mult) { 8999 /* dual dispatch using MatQueryOp */ 9000 ierr = MatQueryOp(((PetscObject)A)->comm, (PetscVoidFunction*)(&mult), "MatMatMatMult",3,((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); CHKERRQ(ierr); 9001 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); 9002 } 9003 } 9004 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9005 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9006 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9007 PetscFunctionReturn(0); 9008 } 9009 9010 #undef __FUNCT__ 9011 #define __FUNCT__ "MatGetRedundantMatrix" 9012 /*@C 9013 MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9014 9015 Collective on Mat 9016 9017 Input Parameters: 9018 + mat - the matrix 9019 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9020 . subcomm - MPI communicator split from the communicator where mat resides in 9021 . mlocal_red - number of local rows of the redundant matrix 9022 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9023 9024 Output Parameter: 9025 . matredundant - redundant matrix 9026 9027 Notes: 9028 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9029 original matrix has not changed from that last call to MatGetRedundantMatrix(). 9030 9031 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9032 calling it. 9033 9034 Only MPIAIJ matrix is supported. 9035 9036 Level: advanced 9037 9038 Concepts: subcommunicator 9039 Concepts: duplicate matrix 9040 9041 .seealso: MatDestroy() 9042 @*/ 9043 PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant) 9044 { 9045 PetscErrorCode ierr; 9046 9047 PetscFunctionBegin; 9048 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9049 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9050 PetscValidPointer(*matredundant,6); 9051 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6); 9052 } 9053 if (!mat->ops->getredundantmatrix) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9054 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9055 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9056 MatCheckPreallocated(mat,1); 9057 9058 ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr); 9059 ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr); 9060 ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr); 9061 PetscFunctionReturn(0); 9062 } 9063 9064 #undef __FUNCT__ 9065 #define __FUNCT__ "MatGetMultiProcBlock" 9066 /*@C 9067 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 9068 a given 'mat' object. Each submatrix can span multiple procs. 9069 9070 Collective on Mat 9071 9072 Input Parameters: 9073 + mat - the matrix 9074 . subcomm - the subcommunicator obtained by com_split(comm) 9075 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9076 9077 Output Parameter: 9078 . subMat - 'parallel submatrices each spans a given subcomm 9079 9080 Notes: 9081 The submatrix partition across processors is dicated by 'subComm' a 9082 communicator obtained by com_split(comm). The comm_split 9083 is not restriced to be grouped with consequitive original ranks. 9084 9085 Due the comm_split() usage, the parallel layout of the submatrices 9086 map directly to the layout of the original matrix [wrt the local 9087 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9088 into the 'DiagonalMat' of the subMat, hence it is used directly from 9089 the subMat. However the offDiagMat looses some columns - and this is 9090 reconstructed with MatSetValues() 9091 9092 Level: advanced 9093 9094 Concepts: subcommunicator 9095 Concepts: submatrices 9096 9097 .seealso: MatGetSubMatrices() 9098 @*/ 9099 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat* subMat) 9100 { 9101 PetscErrorCode ierr; 9102 PetscMPIInt commsize,subCommSize; 9103 9104 PetscFunctionBegin; 9105 ierr = MPI_Comm_size(((PetscObject)mat)->comm,&commsize);CHKERRQ(ierr); 9106 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 9107 if (subCommSize > commsize) SETERRQ2(((PetscObject)mat)->comm,PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 9108 9109 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9110 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 9111 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9112 PetscFunctionReturn(0); 9113 } 9114 9115 #undef __FUNCT__ 9116 #define __FUNCT__ "MatGetLocalSubMatrix" 9117 /*@ 9118 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9119 9120 Not Collective 9121 9122 Input Arguments: 9123 mat - matrix to extract local submatrix from 9124 isrow - local row indices for submatrix 9125 iscol - local column indices for submatrix 9126 9127 Output Arguments: 9128 submat - the submatrix 9129 9130 Level: intermediate 9131 9132 Notes: 9133 The submat should be returned with MatRestoreLocalSubMatrix(). 9134 9135 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 9136 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 9137 9138 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 9139 MatSetValuesBlockedLocal() will also be implemented. 9140 9141 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef() 9142 @*/ 9143 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9144 { 9145 PetscErrorCode ierr; 9146 9147 PetscFunctionBegin; 9148 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9149 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9150 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9151 PetscCheckSameComm(isrow,2,iscol,3); 9152 PetscValidPointer(submat,4); 9153 9154 if (mat->ops->getlocalsubmatrix) { 9155 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9156 } else { 9157 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 9158 } 9159 PetscFunctionReturn(0); 9160 } 9161 9162 #undef __FUNCT__ 9163 #define __FUNCT__ "MatRestoreLocalSubMatrix" 9164 /*@ 9165 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 9166 9167 Not Collective 9168 9169 Input Arguments: 9170 mat - matrix to extract local submatrix from 9171 isrow - local row indices for submatrix 9172 iscol - local column indices for submatrix 9173 submat - the submatrix 9174 9175 Level: intermediate 9176 9177 .seealso: MatGetLocalSubMatrix() 9178 @*/ 9179 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9180 { 9181 PetscErrorCode ierr; 9182 9183 PetscFunctionBegin; 9184 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9185 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9186 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9187 PetscCheckSameComm(isrow,2,iscol,3); 9188 PetscValidPointer(submat,4); 9189 if (*submat) {PetscValidHeaderSpecific(*submat,MAT_CLASSID,4);} 9190 9191 if (mat->ops->restorelocalsubmatrix) { 9192 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9193 } else { 9194 ierr = MatDestroy(submat);CHKERRQ(ierr); 9195 } 9196 *submat = PETSC_NULL; 9197 PetscFunctionReturn(0); 9198 } 9199 9200 /* --------------------------------------------------------*/ 9201 #undef __FUNCT__ 9202 #define __FUNCT__ "MatFindZeroDiagonals" 9203 /*@ 9204 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix 9205 9206 Collective on Mat 9207 9208 Input Parameter: 9209 . mat - the matrix 9210 9211 Output Parameter: 9212 . is - if any rows have zero diagonals this contains the list of them 9213 9214 Level: developer 9215 9216 Concepts: matrix-vector product 9217 9218 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 9219 @*/ 9220 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 9221 { 9222 PetscErrorCode ierr; 9223 9224 PetscFunctionBegin; 9225 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9226 PetscValidType(mat,1); 9227 if (!mat->assembled) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9228 if (mat->factortype) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9229 9230 if (!mat->ops->findzerodiagonals) SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined"); 9231 ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr); 9232 PetscFunctionReturn(0); 9233 } 9234 9235 #undef __FUNCT__ 9236 #define __FUNCT__ "MatInvertBlockDiagonal" 9237 /*@C 9238 MatInvertBlockDiagonal - Inverts the block diagonal entries. 9239 9240 Collective on Mat 9241 9242 Input Parameters: 9243 . mat - the matrix 9244 9245 Output Parameters: 9246 . values - the block inverses in column major order (FORTRAN-like) 9247 9248 Note: 9249 This routine is not available from Fortran. 9250 9251 Level: advanced 9252 @*/ 9253 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 9254 { 9255 PetscErrorCode ierr; 9256 9257 PetscFunctionBegin; 9258 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9259 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9260 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9261 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 9262 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 9263 PetscFunctionReturn(0); 9264 } 9265 9266 #undef __FUNCT__ 9267 #define __FUNCT__ "MatTransposeColoringDestroy" 9268 /*@C 9269 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 9270 via MatTransposeColoringCreate(). 9271 9272 Collective on MatTransposeColoring 9273 9274 Input Parameter: 9275 . c - coloring context 9276 9277 Level: intermediate 9278 9279 .seealso: MatTransposeColoringCreate() 9280 @*/ 9281 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 9282 { 9283 PetscErrorCode ierr; 9284 MatTransposeColoring matcolor=*c; 9285 9286 PetscFunctionBegin; 9287 if (!matcolor) PetscFunctionReturn(0); 9288 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 9289 9290 ierr = PetscFree(matcolor->ncolumns);CHKERRQ(ierr); 9291 ierr = PetscFree(matcolor->nrows);CHKERRQ(ierr); 9292 ierr = PetscFree(matcolor->colorforrow);CHKERRQ(ierr); 9293 ierr = PetscFree2(matcolor->rows,matcolor->columnsforspidx);CHKERRQ(ierr); 9294 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 9295 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 9296 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 9297 PetscFunctionReturn(0); 9298 } 9299 9300 #undef __FUNCT__ 9301 #define __FUNCT__ "MatTransColoringApplySpToDen" 9302 /*@C 9303 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 9304 a MatTransposeColoring context has been created, computes a dense B^T by Apply 9305 MatTransposeColoring to sparse B. 9306 9307 Collective on MatTransposeColoring 9308 9309 Input Parameters: 9310 + B - sparse matrix B 9311 . Btdense - symbolic dense matrix B^T 9312 - coloring - coloring context created with MatTransposeColoringCreate() 9313 9314 Output Parameter: 9315 . Btdense - dense matrix B^T 9316 9317 Options Database Keys: 9318 + -mat_transpose_coloring_view - Activates basic viewing or coloring 9319 . -mat_transpose_coloring_view_draw - Activates drawing of coloring 9320 - -mat_transpose_coloring_view_info - Activates viewing of coloring info 9321 9322 Level: intermediate 9323 9324 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy() 9325 9326 .keywords: coloring 9327 @*/ 9328 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 9329 { 9330 PetscErrorCode ierr; 9331 9332 PetscFunctionBegin; 9333 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 9334 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 9335 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 9336 9337 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 9338 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 9339 PetscFunctionReturn(0); 9340 } 9341 9342 #undef __FUNCT__ 9343 #define __FUNCT__ "MatTransColoringApplyDenToSp" 9344 /*@C 9345 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 9346 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 9347 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 9348 Csp from Cden. 9349 9350 Collective on MatTransposeColoring 9351 9352 Input Parameters: 9353 + coloring - coloring context created with MatTransposeColoringCreate() 9354 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 9355 9356 Output Parameter: 9357 . Csp - sparse matrix 9358 9359 Options Database Keys: 9360 + -mat_multtranspose_coloring_view - Activates basic viewing or coloring 9361 . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring 9362 - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info 9363 9364 Level: intermediate 9365 9366 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 9367 9368 .keywords: coloring 9369 @*/ 9370 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 9371 { 9372 PetscErrorCode ierr; 9373 9374 PetscFunctionBegin; 9375 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 9376 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 9377 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 9378 9379 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 9380 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 9381 PetscFunctionReturn(0); 9382 } 9383 9384 #undef __FUNCT__ 9385 #define __FUNCT__ "MatTransposeColoringCreate" 9386 /*@C 9387 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 9388 9389 Collective on Mat 9390 9391 Input Parameters: 9392 + mat - the matrix product C 9393 - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring() 9394 9395 Output Parameter: 9396 . color - the new coloring context 9397 9398 Level: intermediate 9399 9400 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(), 9401 MatTransColoringApplyDenToSp(), MatTransposeColoringView(), 9402 @*/ 9403 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 9404 { 9405 MatTransposeColoring c; 9406 MPI_Comm comm; 9407 PetscErrorCode ierr; 9408 9409 PetscFunctionBegin; 9410 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 9411 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9412 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); 9413 9414 c->ctype = iscoloring->ctype; 9415 if (mat->ops->transposecoloringcreate) { 9416 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 9417 } else SETERRQ(((PetscObject)mat)->comm,PETSC_ERR_SUP,"Code not yet written for this matrix type"); 9418 9419 *color = c; 9420 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 9421 PetscFunctionReturn(0); 9422 } 9423