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