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