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