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