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