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