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