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