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