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(mat,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(mat,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) PetscValidLogicalCollectiveEnum(mat,op,2); 5174 PetscValidLogicalCollectiveBool(mat,flg,3); 5175 5176 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); 5177 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()"); 5178 5179 switch (op) { 5180 case MAT_NO_OFF_PROC_ENTRIES: 5181 mat->nooffprocentries = flg; 5182 PetscFunctionReturn(0); 5183 break; 5184 case MAT_NO_OFF_PROC_ZERO_ROWS: 5185 mat->nooffproczerorows = flg; 5186 PetscFunctionReturn(0); 5187 break; 5188 case MAT_SPD: 5189 mat->spd_set = PETSC_TRUE; 5190 mat->spd = flg; 5191 if (flg) { 5192 mat->symmetric = PETSC_TRUE; 5193 mat->structurally_symmetric = PETSC_TRUE; 5194 mat->symmetric_set = PETSC_TRUE; 5195 mat->structurally_symmetric_set = PETSC_TRUE; 5196 } 5197 break; 5198 case MAT_SYMMETRIC: 5199 mat->symmetric = flg; 5200 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5201 mat->symmetric_set = PETSC_TRUE; 5202 mat->structurally_symmetric_set = flg; 5203 break; 5204 case MAT_HERMITIAN: 5205 mat->hermitian = flg; 5206 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5207 mat->hermitian_set = PETSC_TRUE; 5208 mat->structurally_symmetric_set = flg; 5209 break; 5210 case MAT_STRUCTURALLY_SYMMETRIC: 5211 mat->structurally_symmetric = flg; 5212 mat->structurally_symmetric_set = PETSC_TRUE; 5213 break; 5214 case MAT_SYMMETRY_ETERNAL: 5215 mat->symmetric_eternal = flg; 5216 break; 5217 default: 5218 break; 5219 } 5220 if (mat->ops->setoption) { 5221 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5222 } 5223 PetscFunctionReturn(0); 5224 } 5225 5226 #undef __FUNCT__ 5227 #define __FUNCT__ "MatZeroEntries" 5228 /*@ 5229 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5230 this routine retains the old nonzero structure. 5231 5232 Logically Collective on Mat 5233 5234 Input Parameters: 5235 . mat - the matrix 5236 5237 Level: intermediate 5238 5239 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. 5240 See the Performance chapter of the users manual for information on preallocating matrices. 5241 5242 Concepts: matrices^zeroing 5243 5244 .seealso: MatZeroRows() 5245 @*/ 5246 PetscErrorCode MatZeroEntries(Mat mat) 5247 { 5248 PetscErrorCode ierr; 5249 5250 PetscFunctionBegin; 5251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5252 PetscValidType(mat,1); 5253 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5254 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"); 5255 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5256 MatCheckPreallocated(mat,1); 5257 5258 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5259 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5260 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5261 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5262 #if defined(PETSC_HAVE_CUSP) 5263 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5264 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5265 } 5266 #endif 5267 #if defined(PETSC_HAVE_VIENNACL) 5268 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5269 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5270 } 5271 #endif 5272 PetscFunctionReturn(0); 5273 } 5274 5275 #undef __FUNCT__ 5276 #define __FUNCT__ "MatZeroRowsColumns" 5277 /*@C 5278 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5279 of a set of rows and columns of a matrix. 5280 5281 Collective on Mat 5282 5283 Input Parameters: 5284 + mat - the matrix 5285 . numRows - the number of rows to remove 5286 . rows - the global row indices 5287 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5288 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5289 - b - optional vector of right hand side, that will be adjusted by provided solution 5290 5291 Notes: 5292 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5293 5294 The user can set a value in the diagonal entry (or for the AIJ and 5295 row formats can optionally remove the main diagonal entry from the 5296 nonzero structure as well, by passing 0.0 as the final argument). 5297 5298 For the parallel case, all processes that share the matrix (i.e., 5299 those in the communicator used for matrix creation) MUST call this 5300 routine, regardless of whether any rows being zeroed are owned by 5301 them. 5302 5303 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5304 list only rows local to itself). 5305 5306 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5307 5308 Level: intermediate 5309 5310 Concepts: matrices^zeroing rows 5311 5312 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS() 5313 @*/ 5314 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5315 { 5316 PetscErrorCode ierr; 5317 5318 PetscFunctionBegin; 5319 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5320 PetscValidType(mat,1); 5321 if (numRows) PetscValidIntPointer(rows,3); 5322 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5323 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5324 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5325 MatCheckPreallocated(mat,1); 5326 5327 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5328 if (mat->viewonassembly) { 5329 ierr = PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);CHKERRQ(ierr); 5330 ierr = MatView(mat,mat->viewonassembly);CHKERRQ(ierr); 5331 ierr = PetscViewerPopFormat(mat->viewonassembly);CHKERRQ(ierr); 5332 } 5333 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5334 #if defined(PETSC_HAVE_CUSP) 5335 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5336 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5337 } 5338 #endif 5339 #if defined(PETSC_HAVE_VIENNACL) 5340 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5341 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5342 } 5343 #endif 5344 PetscFunctionReturn(0); 5345 } 5346 5347 #undef __FUNCT__ 5348 #define __FUNCT__ "MatZeroRowsColumnsIS" 5349 /*@C 5350 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5351 of a set of rows and columns of a matrix. 5352 5353 Collective on Mat 5354 5355 Input Parameters: 5356 + mat - the matrix 5357 . is - the rows to zero 5358 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5359 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5360 - b - optional vector of right hand side, that will be adjusted by provided solution 5361 5362 Notes: 5363 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5364 5365 The user can set a value in the diagonal entry (or for the AIJ and 5366 row formats can optionally remove the main diagonal entry from the 5367 nonzero structure as well, by passing 0.0 as the final argument). 5368 5369 For the parallel case, all processes that share the matrix (i.e., 5370 those in the communicator used for matrix creation) MUST call this 5371 routine, regardless of whether any rows being zeroed are owned by 5372 them. 5373 5374 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5375 list only rows local to itself). 5376 5377 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5378 5379 Level: intermediate 5380 5381 Concepts: matrices^zeroing rows 5382 5383 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns() 5384 @*/ 5385 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5386 { 5387 PetscErrorCode ierr; 5388 PetscInt numRows; 5389 const PetscInt *rows; 5390 5391 PetscFunctionBegin; 5392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5393 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5394 PetscValidType(mat,1); 5395 PetscValidType(is,2); 5396 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5397 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5398 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5399 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5400 PetscFunctionReturn(0); 5401 } 5402 5403 #undef __FUNCT__ 5404 #define __FUNCT__ "MatZeroRows" 5405 /*@C 5406 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5407 of a set of rows of a matrix. 5408 5409 Collective on Mat 5410 5411 Input Parameters: 5412 + mat - the matrix 5413 . numRows - the number of rows to remove 5414 . rows - the global row indices 5415 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5416 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5417 - b - optional vector of right hand side, that will be adjusted by provided solution 5418 5419 Notes: 5420 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5421 but does not release memory. For the dense and block diagonal 5422 formats this does not alter the nonzero structure. 5423 5424 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5425 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5426 merely zeroed. 5427 5428 The user can set a value in the diagonal entry (or for the AIJ and 5429 row formats can optionally remove the main diagonal entry from the 5430 nonzero structure as well, by passing 0.0 as the final argument). 5431 5432 For the parallel case, all processes that share the matrix (i.e., 5433 those in the communicator used for matrix creation) MUST call this 5434 routine, regardless of whether any rows being zeroed are owned by 5435 them. 5436 5437 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5438 list only rows local to itself). 5439 5440 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5441 owns that are to be zeroed. This saves a global synchronization in the implementation. 5442 5443 Level: intermediate 5444 5445 Concepts: matrices^zeroing rows 5446 5447 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5448 @*/ 5449 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5450 { 5451 PetscErrorCode ierr; 5452 5453 PetscFunctionBegin; 5454 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5455 PetscValidType(mat,1); 5456 if (numRows) PetscValidIntPointer(rows,3); 5457 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5458 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5459 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5460 MatCheckPreallocated(mat,1); 5461 5462 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5463 if (mat->viewonassembly) { 5464 ierr = PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);CHKERRQ(ierr); 5465 ierr = MatView(mat,mat->viewonassembly);CHKERRQ(ierr); 5466 ierr = PetscViewerPopFormat(mat->viewonassembly);CHKERRQ(ierr); 5467 } 5468 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5469 #if defined(PETSC_HAVE_CUSP) 5470 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5471 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5472 } 5473 #endif 5474 #if defined(PETSC_HAVE_VIENNACL) 5475 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5476 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5477 } 5478 #endif 5479 PetscFunctionReturn(0); 5480 } 5481 5482 #undef __FUNCT__ 5483 #define __FUNCT__ "MatZeroRowsIS" 5484 /*@C 5485 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5486 of a set of rows of a matrix. 5487 5488 Collective on Mat 5489 5490 Input Parameters: 5491 + mat - the matrix 5492 . is - index set of rows to remove 5493 . diag - value put in all diagonals of eliminated rows 5494 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5495 - b - optional vector of right hand side, that will be adjusted by provided solution 5496 5497 Notes: 5498 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5499 but does not release memory. For the dense and block diagonal 5500 formats this does not alter the nonzero structure. 5501 5502 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5503 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5504 merely zeroed. 5505 5506 The user can set a value in the diagonal entry (or for the AIJ and 5507 row formats can optionally remove the main diagonal entry from the 5508 nonzero structure as well, by passing 0.0 as the final argument). 5509 5510 For the parallel case, all processes that share the matrix (i.e., 5511 those in the communicator used for matrix creation) MUST call this 5512 routine, regardless of whether any rows being zeroed are owned by 5513 them. 5514 5515 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5516 list only rows local to itself). 5517 5518 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5519 owns that are to be zeroed. This saves a global synchronization in the implementation. 5520 5521 Level: intermediate 5522 5523 Concepts: matrices^zeroing rows 5524 5525 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5526 @*/ 5527 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5528 { 5529 PetscInt numRows; 5530 const PetscInt *rows; 5531 PetscErrorCode ierr; 5532 5533 PetscFunctionBegin; 5534 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5535 PetscValidType(mat,1); 5536 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5537 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5538 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5539 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5540 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5541 PetscFunctionReturn(0); 5542 } 5543 5544 #undef __FUNCT__ 5545 #define __FUNCT__ "MatZeroRowsStencil" 5546 /*@C 5547 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5548 of a set of rows of a matrix. These rows must be local to the process. 5549 5550 Collective on Mat 5551 5552 Input Parameters: 5553 + mat - the matrix 5554 . numRows - the number of rows to remove 5555 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5556 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5557 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5558 - b - optional vector of right hand side, that will be adjusted by provided solution 5559 5560 Notes: 5561 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5562 but does not release memory. For the dense and block diagonal 5563 formats this does not alter the nonzero structure. 5564 5565 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5566 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5567 merely zeroed. 5568 5569 The user can set a value in the diagonal entry (or for the AIJ and 5570 row formats can optionally remove the main diagonal entry from the 5571 nonzero structure as well, by passing 0.0 as the final argument). 5572 5573 For the parallel case, all processes that share the matrix (i.e., 5574 those in the communicator used for matrix creation) MUST call this 5575 routine, regardless of whether any rows being zeroed are owned by 5576 them. 5577 5578 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5579 list only rows local to itself). 5580 5581 The grid coordinates are across the entire grid, not just the local portion 5582 5583 In Fortran idxm and idxn should be declared as 5584 $ MatStencil idxm(4,m) 5585 and the values inserted using 5586 $ idxm(MatStencil_i,1) = i 5587 $ idxm(MatStencil_j,1) = j 5588 $ idxm(MatStencil_k,1) = k 5589 $ idxm(MatStencil_c,1) = c 5590 etc 5591 5592 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5593 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5594 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5595 DMDA_BOUNDARY_PERIODIC boundary type. 5596 5597 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 5598 a single value per point) you can skip filling those indices. 5599 5600 Level: intermediate 5601 5602 Concepts: matrices^zeroing rows 5603 5604 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5605 @*/ 5606 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5607 { 5608 PetscInt dim = mat->stencil.dim; 5609 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5610 PetscInt *dims = mat->stencil.dims+1; 5611 PetscInt *starts = mat->stencil.starts; 5612 PetscInt *dxm = (PetscInt*) rows; 5613 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5614 PetscErrorCode ierr; 5615 5616 PetscFunctionBegin; 5617 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5618 PetscValidType(mat,1); 5619 if (numRows) PetscValidIntPointer(rows,3); 5620 5621 ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr); 5622 for (i = 0; i < numRows; ++i) { 5623 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5624 for (j = 0; j < 3-sdim; ++j) dxm++; 5625 /* Local index in X dir */ 5626 tmp = *dxm++ - starts[0]; 5627 /* Loop over remaining dimensions */ 5628 for (j = 0; j < dim-1; ++j) { 5629 /* If nonlocal, set index to be negative */ 5630 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5631 /* Update local index */ 5632 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5633 } 5634 /* Skip component slot if necessary */ 5635 if (mat->stencil.noc) dxm++; 5636 /* Local row number */ 5637 if (tmp >= 0) { 5638 jdxm[numNewRows++] = tmp; 5639 } 5640 } 5641 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5642 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5643 PetscFunctionReturn(0); 5644 } 5645 5646 #undef __FUNCT__ 5647 #define __FUNCT__ "MatZeroRowsColumnsStencil" 5648 /*@C 5649 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5650 of a set of rows and columns of a matrix. 5651 5652 Collective on Mat 5653 5654 Input Parameters: 5655 + mat - the matrix 5656 . numRows - the number of rows/columns to remove 5657 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5658 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5659 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5660 - b - optional vector of right hand side, that will be adjusted by provided solution 5661 5662 Notes: 5663 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5664 but does not release memory. For the dense and block diagonal 5665 formats this does not alter the nonzero structure. 5666 5667 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5668 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5669 merely zeroed. 5670 5671 The user can set a value in the diagonal entry (or for the AIJ and 5672 row formats can optionally remove the main diagonal entry from the 5673 nonzero structure as well, by passing 0.0 as the final argument). 5674 5675 For the parallel case, all processes that share the matrix (i.e., 5676 those in the communicator used for matrix creation) MUST call this 5677 routine, regardless of whether any rows being zeroed are owned by 5678 them. 5679 5680 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5681 list only rows local to itself, but the row/column numbers are given in local numbering). 5682 5683 The grid coordinates are across the entire grid, not just the local portion 5684 5685 In Fortran idxm and idxn should be declared as 5686 $ MatStencil idxm(4,m) 5687 and the values inserted using 5688 $ idxm(MatStencil_i,1) = i 5689 $ idxm(MatStencil_j,1) = j 5690 $ idxm(MatStencil_k,1) = k 5691 $ idxm(MatStencil_c,1) = c 5692 etc 5693 5694 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5695 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5696 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5697 DMDA_BOUNDARY_PERIODIC boundary type. 5698 5699 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 5700 a single value per point) you can skip filling those indices. 5701 5702 Level: intermediate 5703 5704 Concepts: matrices^zeroing rows 5705 5706 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5707 @*/ 5708 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5709 { 5710 PetscInt dim = mat->stencil.dim; 5711 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5712 PetscInt *dims = mat->stencil.dims+1; 5713 PetscInt *starts = mat->stencil.starts; 5714 PetscInt *dxm = (PetscInt*) rows; 5715 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5716 PetscErrorCode ierr; 5717 5718 PetscFunctionBegin; 5719 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5720 PetscValidType(mat,1); 5721 if (numRows) PetscValidIntPointer(rows,3); 5722 5723 ierr = PetscMalloc(numRows*sizeof(PetscInt), &jdxm);CHKERRQ(ierr); 5724 for (i = 0; i < numRows; ++i) { 5725 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5726 for (j = 0; j < 3-sdim; ++j) dxm++; 5727 /* Local index in X dir */ 5728 tmp = *dxm++ - starts[0]; 5729 /* Loop over remaining dimensions */ 5730 for (j = 0; j < dim-1; ++j) { 5731 /* If nonlocal, set index to be negative */ 5732 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5733 /* Update local index */ 5734 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5735 } 5736 /* Skip component slot if necessary */ 5737 if (mat->stencil.noc) dxm++; 5738 /* Local row number */ 5739 if (tmp >= 0) { 5740 jdxm[numNewRows++] = tmp; 5741 } 5742 } 5743 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5744 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5745 PetscFunctionReturn(0); 5746 } 5747 5748 #undef __FUNCT__ 5749 #define __FUNCT__ "MatZeroRowsLocal" 5750 /*@C 5751 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 5752 of a set of rows of a matrix; using local numbering of rows. 5753 5754 Collective on Mat 5755 5756 Input Parameters: 5757 + mat - the matrix 5758 . numRows - the number of rows to remove 5759 . rows - the global row indices 5760 . diag - value put in all diagonals of eliminated rows 5761 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5762 - b - optional vector of right hand side, that will be adjusted by provided solution 5763 5764 Notes: 5765 Before calling MatZeroRowsLocal(), the user must first set the 5766 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5767 5768 For the AIJ matrix formats this removes the old nonzero structure, 5769 but does not release memory. For the dense and block diagonal 5770 formats this does not alter the nonzero structure. 5771 5772 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5773 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5774 merely zeroed. 5775 5776 The user can set a value in the diagonal entry (or for the AIJ and 5777 row formats can optionally remove the main diagonal entry from the 5778 nonzero structure as well, by passing 0.0 as the final argument). 5779 5780 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5781 owns that are to be zeroed. This saves a global synchronization in the implementation. 5782 5783 Level: intermediate 5784 5785 Concepts: matrices^zeroing 5786 5787 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5788 @*/ 5789 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5790 { 5791 PetscErrorCode ierr; 5792 PetscMPIInt size; 5793 5794 PetscFunctionBegin; 5795 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5796 PetscValidType(mat,1); 5797 if (numRows) PetscValidIntPointer(rows,3); 5798 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5799 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5800 MatCheckPreallocated(mat,1); 5801 5802 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 5803 if (mat->ops->zerorowslocal) { 5804 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5805 } else if (size == 1) { 5806 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5807 } else { 5808 IS is, newis; 5809 const PetscInt *newRows; 5810 5811 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 5812 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 5813 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 5814 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 5815 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 5816 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 5817 ierr = ISDestroy(&newis);CHKERRQ(ierr); 5818 ierr = ISDestroy(&is);CHKERRQ(ierr); 5819 } 5820 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5821 #if defined(PETSC_HAVE_CUSP) 5822 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5823 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5824 } 5825 #endif 5826 #if defined(PETSC_HAVE_VIENNACL) 5827 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5828 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5829 } 5830 #endif 5831 PetscFunctionReturn(0); 5832 } 5833 5834 #undef __FUNCT__ 5835 #define __FUNCT__ "MatZeroRowsLocalIS" 5836 /*@C 5837 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 5838 of a set of rows of a matrix; using local numbering of rows. 5839 5840 Collective on Mat 5841 5842 Input Parameters: 5843 + mat - the matrix 5844 . is - index set of rows to remove 5845 . diag - value put in all diagonals of eliminated rows 5846 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5847 - b - optional vector of right hand side, that will be adjusted by provided solution 5848 5849 Notes: 5850 Before calling MatZeroRowsLocalIS(), the user must first set the 5851 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5852 5853 For the AIJ matrix formats this removes the old nonzero structure, 5854 but does not release memory. For the dense and block diagonal 5855 formats this does not alter the nonzero structure. 5856 5857 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5858 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5859 merely zeroed. 5860 5861 The user can set a value in the diagonal entry (or for the AIJ and 5862 row formats can optionally remove the main diagonal entry from the 5863 nonzero structure as well, by passing 0.0 as the final argument). 5864 5865 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5866 owns that are to be zeroed. This saves a global synchronization in the implementation. 5867 5868 Level: intermediate 5869 5870 Concepts: matrices^zeroing 5871 5872 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5873 @*/ 5874 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5875 { 5876 PetscErrorCode ierr; 5877 PetscInt numRows; 5878 const PetscInt *rows; 5879 5880 PetscFunctionBegin; 5881 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5882 PetscValidType(mat,1); 5883 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5884 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5885 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5886 MatCheckPreallocated(mat,1); 5887 5888 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5889 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5890 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5891 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5892 PetscFunctionReturn(0); 5893 } 5894 5895 #undef __FUNCT__ 5896 #define __FUNCT__ "MatZeroRowsColumnsLocal" 5897 /*@C 5898 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 5899 of a set of rows and columns of a matrix; using local numbering of rows. 5900 5901 Collective on Mat 5902 5903 Input Parameters: 5904 + mat - the matrix 5905 . numRows - the number of rows to remove 5906 . rows - the global row indices 5907 . diag - value put in all diagonals of eliminated rows 5908 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5909 - b - optional vector of right hand side, that will be adjusted by provided solution 5910 5911 Notes: 5912 Before calling MatZeroRowsColumnsLocal(), the user must first set the 5913 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5914 5915 The user can set a value in the diagonal entry (or for the AIJ and 5916 row formats can optionally remove the main diagonal entry from the 5917 nonzero structure as well, by passing 0.0 as the final argument). 5918 5919 Level: intermediate 5920 5921 Concepts: matrices^zeroing 5922 5923 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5924 @*/ 5925 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5926 { 5927 PetscErrorCode ierr; 5928 PetscMPIInt size; 5929 5930 PetscFunctionBegin; 5931 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5932 PetscValidType(mat,1); 5933 if (numRows) PetscValidIntPointer(rows,3); 5934 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5935 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5936 MatCheckPreallocated(mat,1); 5937 5938 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 5939 if (size == 1) { 5940 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5941 } else { 5942 IS is, newis; 5943 const PetscInt *newRows; 5944 5945 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 5946 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 5947 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 5948 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 5949 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 5950 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 5951 ierr = ISDestroy(&newis);CHKERRQ(ierr); 5952 ierr = ISDestroy(&is);CHKERRQ(ierr); 5953 } 5954 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5955 #if defined(PETSC_HAVE_CUSP) 5956 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5957 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5958 } 5959 #endif 5960 #if defined(PETSC_HAVE_VIENNACL) 5961 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5962 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5963 } 5964 #endif 5965 PetscFunctionReturn(0); 5966 } 5967 5968 #undef __FUNCT__ 5969 #define __FUNCT__ "MatZeroRowsColumnsLocalIS" 5970 /*@C 5971 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 5972 of a set of rows and columns of a matrix; using local numbering of rows. 5973 5974 Collective on Mat 5975 5976 Input Parameters: 5977 + mat - the matrix 5978 . is - index set of rows to remove 5979 . diag - value put in all diagonals of eliminated rows 5980 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5981 - b - optional vector of right hand side, that will be adjusted by provided solution 5982 5983 Notes: 5984 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 5985 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 5986 5987 The user can set a value in the diagonal entry (or for the AIJ and 5988 row formats can optionally remove the main diagonal entry from the 5989 nonzero structure as well, by passing 0.0 as the final argument). 5990 5991 Level: intermediate 5992 5993 Concepts: matrices^zeroing 5994 5995 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 5996 @*/ 5997 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5998 { 5999 PetscErrorCode ierr; 6000 PetscInt numRows; 6001 const PetscInt *rows; 6002 6003 PetscFunctionBegin; 6004 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6005 PetscValidType(mat,1); 6006 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6007 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6008 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6009 MatCheckPreallocated(mat,1); 6010 6011 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6012 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6013 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6014 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6015 PetscFunctionReturn(0); 6016 } 6017 6018 #undef __FUNCT__ 6019 #define __FUNCT__ "MatGetSize" 6020 /*@ 6021 MatGetSize - Returns the numbers of rows and columns in a matrix. 6022 6023 Not Collective 6024 6025 Input Parameter: 6026 . mat - the matrix 6027 6028 Output Parameters: 6029 + m - the number of global rows 6030 - n - the number of global columns 6031 6032 Note: both output parameters can be NULL on input. 6033 6034 Level: beginner 6035 6036 Concepts: matrices^size 6037 6038 .seealso: MatGetLocalSize() 6039 @*/ 6040 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6041 { 6042 PetscFunctionBegin; 6043 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6044 if (m) *m = mat->rmap->N; 6045 if (n) *n = mat->cmap->N; 6046 PetscFunctionReturn(0); 6047 } 6048 6049 #undef __FUNCT__ 6050 #define __FUNCT__ "MatGetLocalSize" 6051 /*@ 6052 MatGetLocalSize - Returns the number of rows and columns in a matrix 6053 stored locally. This information may be implementation dependent, so 6054 use with care. 6055 6056 Not Collective 6057 6058 Input Parameters: 6059 . mat - the matrix 6060 6061 Output Parameters: 6062 + m - the number of local rows 6063 - n - the number of local columns 6064 6065 Note: both output parameters can be NULL on input. 6066 6067 Level: beginner 6068 6069 Concepts: matrices^local size 6070 6071 .seealso: MatGetSize() 6072 @*/ 6073 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6074 { 6075 PetscFunctionBegin; 6076 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6077 if (m) PetscValidIntPointer(m,2); 6078 if (n) PetscValidIntPointer(n,3); 6079 if (m) *m = mat->rmap->n; 6080 if (n) *n = mat->cmap->n; 6081 PetscFunctionReturn(0); 6082 } 6083 6084 #undef __FUNCT__ 6085 #define __FUNCT__ "MatGetOwnershipRangeColumn" 6086 /*@ 6087 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6088 this processor. (The columns of the "diagonal block") 6089 6090 Not Collective, unless matrix has not been allocated, then collective on Mat 6091 6092 Input Parameters: 6093 . mat - the matrix 6094 6095 Output Parameters: 6096 + m - the global index of the first local column 6097 - n - one more than the global index of the last local column 6098 6099 Notes: both output parameters can be NULL on input. 6100 6101 Level: developer 6102 6103 Concepts: matrices^column ownership 6104 6105 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6106 6107 @*/ 6108 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6109 { 6110 PetscFunctionBegin; 6111 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6112 PetscValidType(mat,1); 6113 if (m) PetscValidIntPointer(m,2); 6114 if (n) PetscValidIntPointer(n,3); 6115 MatCheckPreallocated(mat,1); 6116 if (m) *m = mat->cmap->rstart; 6117 if (n) *n = mat->cmap->rend; 6118 PetscFunctionReturn(0); 6119 } 6120 6121 #undef __FUNCT__ 6122 #define __FUNCT__ "MatGetOwnershipRange" 6123 /*@ 6124 MatGetOwnershipRange - Returns the range of matrix rows owned by 6125 this processor, assuming that the matrix is laid out with the first 6126 n1 rows on the first processor, the next n2 rows on the second, etc. 6127 For certain parallel layouts this range may not be well defined. 6128 6129 Not Collective 6130 6131 Input Parameters: 6132 . mat - the matrix 6133 6134 Output Parameters: 6135 + m - the global index of the first local row 6136 - n - one more than the global index of the last local row 6137 6138 Note: Both output parameters can be NULL on input. 6139 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6140 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6141 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6142 6143 Level: beginner 6144 6145 Concepts: matrices^row ownership 6146 6147 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6148 6149 @*/ 6150 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6151 { 6152 PetscFunctionBegin; 6153 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6154 PetscValidType(mat,1); 6155 if (m) PetscValidIntPointer(m,2); 6156 if (n) PetscValidIntPointer(n,3); 6157 MatCheckPreallocated(mat,1); 6158 if (m) *m = mat->rmap->rstart; 6159 if (n) *n = mat->rmap->rend; 6160 PetscFunctionReturn(0); 6161 } 6162 6163 #undef __FUNCT__ 6164 #define __FUNCT__ "MatGetOwnershipRanges" 6165 /*@C 6166 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6167 each process 6168 6169 Not Collective, unless matrix has not been allocated, then collective on Mat 6170 6171 Input Parameters: 6172 . mat - the matrix 6173 6174 Output Parameters: 6175 . ranges - start of each processors portion plus one more then the total length at the end 6176 6177 Level: beginner 6178 6179 Concepts: matrices^row ownership 6180 6181 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6182 6183 @*/ 6184 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6185 { 6186 PetscErrorCode ierr; 6187 6188 PetscFunctionBegin; 6189 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6190 PetscValidType(mat,1); 6191 MatCheckPreallocated(mat,1); 6192 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6193 PetscFunctionReturn(0); 6194 } 6195 6196 #undef __FUNCT__ 6197 #define __FUNCT__ "MatGetOwnershipRangesColumn" 6198 /*@C 6199 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6200 this processor. (The columns of the "diagonal blocks" for each process) 6201 6202 Not Collective, unless matrix has not been allocated, then collective on Mat 6203 6204 Input Parameters: 6205 . mat - the matrix 6206 6207 Output Parameters: 6208 . ranges - start of each processors portion plus one more then the total length at the end 6209 6210 Level: beginner 6211 6212 Concepts: matrices^column ownership 6213 6214 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6215 6216 @*/ 6217 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6218 { 6219 PetscErrorCode ierr; 6220 6221 PetscFunctionBegin; 6222 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6223 PetscValidType(mat,1); 6224 MatCheckPreallocated(mat,1); 6225 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6226 PetscFunctionReturn(0); 6227 } 6228 6229 #undef __FUNCT__ 6230 #define __FUNCT__ "MatGetOwnershipIS" 6231 /*@C 6232 MatGetOwnershipIS - Get row and column ownership as index sets 6233 6234 Not Collective 6235 6236 Input Arguments: 6237 . A - matrix of type Elemental 6238 6239 Output Arguments: 6240 + rows - rows in which this process owns elements 6241 . cols - columns in which this process owns elements 6242 6243 Level: intermediate 6244 6245 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues() 6246 @*/ 6247 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6248 { 6249 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6250 6251 PetscFunctionBegin; 6252 MatCheckPreallocated(A,1); 6253 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6254 if (f) { 6255 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6256 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6257 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6258 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6259 } 6260 PetscFunctionReturn(0); 6261 } 6262 6263 #undef __FUNCT__ 6264 #define __FUNCT__ "MatILUFactorSymbolic" 6265 /*@C 6266 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6267 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6268 to complete the factorization. 6269 6270 Collective on Mat 6271 6272 Input Parameters: 6273 + mat - the matrix 6274 . row - row permutation 6275 . column - column permutation 6276 - info - structure containing 6277 $ levels - number of levels of fill. 6278 $ expected fill - as ratio of original fill. 6279 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6280 missing diagonal entries) 6281 6282 Output Parameters: 6283 . fact - new matrix that has been symbolically factored 6284 6285 Notes: 6286 See the <a href="../../docs/manual.pdf">users manual</a> for additional information about 6287 choosing the fill factor for better efficiency. 6288 6289 Most users should employ the simplified KSP interface for linear solvers 6290 instead of working directly with matrix algebra routines such as this. 6291 See, e.g., KSPCreate(). 6292 6293 Level: developer 6294 6295 Concepts: matrices^symbolic LU factorization 6296 Concepts: matrices^factorization 6297 Concepts: LU^symbolic factorization 6298 6299 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6300 MatGetOrdering(), MatFactorInfo 6301 6302 Developer Note: fortran interface is not autogenerated as the f90 6303 interface defintion cannot be generated correctly [due to MatFactorInfo] 6304 6305 @*/ 6306 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6307 { 6308 PetscErrorCode ierr; 6309 6310 PetscFunctionBegin; 6311 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6312 PetscValidType(mat,1); 6313 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6314 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6315 PetscValidPointer(info,4); 6316 PetscValidPointer(fact,5); 6317 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6318 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill); 6319 if (!(fact)->ops->ilufactorsymbolic) { 6320 const MatSolverPackage spackage; 6321 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6322 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6323 } 6324 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6325 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6326 MatCheckPreallocated(mat,2); 6327 6328 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6329 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6330 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6331 PetscFunctionReturn(0); 6332 } 6333 6334 #undef __FUNCT__ 6335 #define __FUNCT__ "MatICCFactorSymbolic" 6336 /*@C 6337 MatICCFactorSymbolic - Performs symbolic incomplete 6338 Cholesky factorization for a symmetric matrix. Use 6339 MatCholeskyFactorNumeric() to complete the factorization. 6340 6341 Collective on Mat 6342 6343 Input Parameters: 6344 + mat - the matrix 6345 . perm - row and column permutation 6346 - info - structure containing 6347 $ levels - number of levels of fill. 6348 $ expected fill - as ratio of original fill. 6349 6350 Output Parameter: 6351 . fact - the factored matrix 6352 6353 Notes: 6354 Most users should employ the KSP interface for linear solvers 6355 instead of working directly with matrix algebra routines such as this. 6356 See, e.g., KSPCreate(). 6357 6358 Level: developer 6359 6360 Concepts: matrices^symbolic incomplete Cholesky factorization 6361 Concepts: matrices^factorization 6362 Concepts: Cholsky^symbolic factorization 6363 6364 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6365 6366 Developer Note: fortran interface is not autogenerated as the f90 6367 interface defintion cannot be generated correctly [due to MatFactorInfo] 6368 6369 @*/ 6370 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6371 { 6372 PetscErrorCode ierr; 6373 6374 PetscFunctionBegin; 6375 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6376 PetscValidType(mat,1); 6377 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6378 PetscValidPointer(info,3); 6379 PetscValidPointer(fact,4); 6380 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6381 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6382 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill); 6383 if (!(fact)->ops->iccfactorsymbolic) { 6384 const MatSolverPackage spackage; 6385 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6386 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6387 } 6388 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6389 MatCheckPreallocated(mat,2); 6390 6391 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6392 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6393 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6394 PetscFunctionReturn(0); 6395 } 6396 6397 #undef __FUNCT__ 6398 #define __FUNCT__ "MatGetSubMatrices" 6399 /*@C 6400 MatGetSubMatrices - Extracts several submatrices from a matrix. If submat 6401 points to an array of valid matrices, they may be reused to store the new 6402 submatrices. 6403 6404 Collective on Mat 6405 6406 Input Parameters: 6407 + mat - the matrix 6408 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6409 . irow, icol - index sets of rows and columns to extract (must be sorted) 6410 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6411 6412 Output Parameter: 6413 . submat - the array of submatrices 6414 6415 Notes: 6416 MatGetSubMatrices() can extract ONLY sequential submatrices 6417 (from both sequential and parallel matrices). Use MatGetSubMatrix() 6418 to extract a parallel submatrix. 6419 6420 Currently both row and column indices must be sorted to guarantee 6421 correctness with all matrix types. 6422 6423 When extracting submatrices from a parallel matrix, each processor can 6424 form a different submatrix by setting the rows and columns of its 6425 individual index sets according to the local submatrix desired. 6426 6427 When finished using the submatrices, the user should destroy 6428 them with MatDestroyMatrices(). 6429 6430 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6431 original matrix has not changed from that last call to MatGetSubMatrices(). 6432 6433 This routine creates the matrices in submat; you should NOT create them before 6434 calling it. It also allocates the array of matrix pointers submat. 6435 6436 For BAIJ matrices the index sets must respect the block structure, that is if they 6437 request one row/column in a block, they must request all rows/columns that are in 6438 that block. For example, if the block size is 2 you cannot request just row 0 and 6439 column 0. 6440 6441 Fortran Note: 6442 The Fortran interface is slightly different from that given below; it 6443 requires one to pass in as submat a Mat (integer) array of size at least m. 6444 6445 Level: advanced 6446 6447 Concepts: matrices^accessing submatrices 6448 Concepts: submatrices 6449 6450 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6451 @*/ 6452 PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6453 { 6454 PetscErrorCode ierr; 6455 PetscInt i; 6456 PetscBool eq; 6457 6458 PetscFunctionBegin; 6459 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6460 PetscValidType(mat,1); 6461 if (n) { 6462 PetscValidPointer(irow,3); 6463 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6464 PetscValidPointer(icol,4); 6465 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6466 } 6467 PetscValidPointer(submat,6); 6468 if (n && scall == MAT_REUSE_MATRIX) { 6469 PetscValidPointer(*submat,6); 6470 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6471 } 6472 if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6473 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6474 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6475 MatCheckPreallocated(mat,1); 6476 6477 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6478 ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6479 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6480 for (i=0; i<n; i++) { 6481 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6482 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6483 if (eq) { 6484 if (mat->symmetric) { 6485 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6486 } else if (mat->hermitian) { 6487 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6488 } else if (mat->structurally_symmetric) { 6489 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6490 } 6491 } 6492 } 6493 } 6494 PetscFunctionReturn(0); 6495 } 6496 6497 #undef __FUNCT__ 6498 #define __FUNCT__ "MatGetSubMatricesParallel" 6499 PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6500 { 6501 PetscErrorCode ierr; 6502 PetscInt i; 6503 PetscBool eq; 6504 6505 PetscFunctionBegin; 6506 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6507 PetscValidType(mat,1); 6508 if (n) { 6509 PetscValidPointer(irow,3); 6510 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6511 PetscValidPointer(icol,4); 6512 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6513 } 6514 PetscValidPointer(submat,6); 6515 if (n && scall == MAT_REUSE_MATRIX) { 6516 PetscValidPointer(*submat,6); 6517 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6518 } 6519 if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6520 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6521 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6522 MatCheckPreallocated(mat,1); 6523 6524 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6525 ierr = (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6526 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6527 for (i=0; i<n; i++) { 6528 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6529 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6530 if (eq) { 6531 if (mat->symmetric) { 6532 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6533 } else if (mat->hermitian) { 6534 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6535 } else if (mat->structurally_symmetric) { 6536 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6537 } 6538 } 6539 } 6540 } 6541 PetscFunctionReturn(0); 6542 } 6543 6544 #undef __FUNCT__ 6545 #define __FUNCT__ "MatDestroyMatrices" 6546 /*@C 6547 MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices(). 6548 6549 Collective on Mat 6550 6551 Input Parameters: 6552 + n - the number of local matrices 6553 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6554 sequence of MatGetSubMatrices()) 6555 6556 Level: advanced 6557 6558 Notes: Frees not only the matrices, but also the array that contains the matrices 6559 In Fortran will not free the array. 6560 6561 .seealso: MatGetSubMatrices() 6562 @*/ 6563 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6564 { 6565 PetscErrorCode ierr; 6566 PetscInt i; 6567 6568 PetscFunctionBegin; 6569 if (!*mat) PetscFunctionReturn(0); 6570 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6571 PetscValidPointer(mat,2); 6572 for (i=0; i<n; i++) { 6573 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6574 } 6575 /* memory is allocated even if n = 0 */ 6576 ierr = PetscFree(*mat);CHKERRQ(ierr); 6577 *mat = NULL; 6578 PetscFunctionReturn(0); 6579 } 6580 6581 #undef __FUNCT__ 6582 #define __FUNCT__ "MatGetSeqNonzeroStructure" 6583 /*@C 6584 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6585 6586 Collective on Mat 6587 6588 Input Parameters: 6589 . mat - the matrix 6590 6591 Output Parameter: 6592 . matstruct - the sequential matrix with the nonzero structure of mat 6593 6594 Level: intermediate 6595 6596 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices() 6597 @*/ 6598 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6599 { 6600 PetscErrorCode ierr; 6601 6602 PetscFunctionBegin; 6603 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6604 PetscValidPointer(matstruct,2); 6605 6606 PetscValidType(mat,1); 6607 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6608 MatCheckPreallocated(mat,1); 6609 6610 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6611 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6612 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6613 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6614 PetscFunctionReturn(0); 6615 } 6616 6617 #undef __FUNCT__ 6618 #define __FUNCT__ "MatDestroySeqNonzeroStructure" 6619 /*@C 6620 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6621 6622 Collective on Mat 6623 6624 Input Parameters: 6625 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6626 sequence of MatGetSequentialNonzeroStructure()) 6627 6628 Level: advanced 6629 6630 Notes: Frees not only the matrices, but also the array that contains the matrices 6631 6632 .seealso: MatGetSeqNonzeroStructure() 6633 @*/ 6634 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6635 { 6636 PetscErrorCode ierr; 6637 6638 PetscFunctionBegin; 6639 PetscValidPointer(mat,1); 6640 ierr = MatDestroy(mat);CHKERRQ(ierr); 6641 PetscFunctionReturn(0); 6642 } 6643 6644 #undef __FUNCT__ 6645 #define __FUNCT__ "MatIncreaseOverlap" 6646 /*@ 6647 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6648 replaces the index sets by larger ones that represent submatrices with 6649 additional overlap. 6650 6651 Collective on Mat 6652 6653 Input Parameters: 6654 + mat - the matrix 6655 . n - the number of index sets 6656 . is - the array of index sets (these index sets will changed during the call) 6657 - ov - the additional overlap requested 6658 6659 Level: developer 6660 6661 Concepts: overlap 6662 Concepts: ASM^computing overlap 6663 6664 .seealso: MatGetSubMatrices() 6665 @*/ 6666 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6667 { 6668 PetscErrorCode ierr; 6669 6670 PetscFunctionBegin; 6671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6672 PetscValidType(mat,1); 6673 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6674 if (n) { 6675 PetscValidPointer(is,3); 6676 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6677 } 6678 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6679 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6680 MatCheckPreallocated(mat,1); 6681 6682 if (!ov) PetscFunctionReturn(0); 6683 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6684 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6685 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6686 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6687 PetscFunctionReturn(0); 6688 } 6689 6690 #undef __FUNCT__ 6691 #define __FUNCT__ "MatGetBlockSize" 6692 /*@ 6693 MatGetBlockSize - Returns the matrix block size; useful especially for the 6694 block row and block diagonal formats. 6695 6696 Not Collective 6697 6698 Input Parameter: 6699 . mat - the matrix 6700 6701 Output Parameter: 6702 . bs - block size 6703 6704 Notes: 6705 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ 6706 6707 Level: intermediate 6708 6709 Concepts: matrices^block size 6710 6711 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 6712 @*/ 6713 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 6714 { 6715 PetscFunctionBegin; 6716 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6717 PetscValidType(mat,1); 6718 PetscValidIntPointer(bs,2); 6719 MatCheckPreallocated(mat,1); 6720 *bs = mat->rmap->bs; 6721 PetscFunctionReturn(0); 6722 } 6723 6724 #undef __FUNCT__ 6725 #define __FUNCT__ "MatGetBlockSizes" 6726 /*@ 6727 MatGetBlockSizes - Returns the matrix block row and column sizes; 6728 useful especially for the block row and block diagonal formats. 6729 6730 Not Collective 6731 6732 Input Parameter: 6733 . mat - the matrix 6734 6735 Output Parameter: 6736 . rbs - row block size 6737 . cbs - coumn block size 6738 6739 Notes: 6740 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ 6741 6742 Level: intermediate 6743 6744 Concepts: matrices^block size 6745 6746 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6747 @*/ 6748 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 6749 { 6750 PetscFunctionBegin; 6751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6752 PetscValidType(mat,1); 6753 if (rbs) PetscValidIntPointer(rbs,2); 6754 if (cbs) PetscValidIntPointer(cbs,3); 6755 MatCheckPreallocated(mat,1); 6756 if (rbs) *rbs = mat->rmap->bs; 6757 if (cbs) *cbs = mat->cmap->bs; 6758 PetscFunctionReturn(0); 6759 } 6760 6761 #undef __FUNCT__ 6762 #define __FUNCT__ "MatSetBlockSize" 6763 /*@ 6764 MatSetBlockSize - Sets the matrix block size. 6765 6766 Logically Collective on Mat 6767 6768 Input Parameters: 6769 + mat - the matrix 6770 - bs - block size 6771 6772 Notes: 6773 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 6774 6775 Level: intermediate 6776 6777 Concepts: matrices^block size 6778 6779 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6780 @*/ 6781 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 6782 { 6783 PetscErrorCode ierr; 6784 6785 PetscFunctionBegin; 6786 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6787 PetscValidLogicalCollectiveInt(mat,bs,2); 6788 ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr); 6789 ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr); 6790 PetscFunctionReturn(0); 6791 } 6792 6793 #undef __FUNCT__ 6794 #define __FUNCT__ "MatSetBlockSizes" 6795 /*@ 6796 MatSetBlockSizes - Sets the matrix block row and column sizes. 6797 6798 Logically Collective on Mat 6799 6800 Input Parameters: 6801 + mat - the matrix 6802 - rbs - row block size 6803 - cbs - column block size 6804 6805 Notes: 6806 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 6807 6808 Level: intermediate 6809 6810 Concepts: matrices^block size 6811 6812 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize() 6813 @*/ 6814 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 6815 { 6816 PetscErrorCode ierr; 6817 6818 PetscFunctionBegin; 6819 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6820 PetscValidLogicalCollectiveInt(mat,rbs,2); 6821 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 6822 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 6823 PetscFunctionReturn(0); 6824 } 6825 6826 #undef __FUNCT__ 6827 #define __FUNCT__ "MatGetRowIJ" 6828 /*@C 6829 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 6830 6831 Collective on Mat 6832 6833 Input Parameters: 6834 + mat - the matrix 6835 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 6836 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 6837 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6838 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6839 always used. 6840 6841 Output Parameters: 6842 + n - number of rows in the (possibly compressed) matrix 6843 . ia - the row pointers [of length n+1] 6844 . ja - the column indices 6845 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 6846 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 6847 6848 Level: developer 6849 6850 Notes: You CANNOT change any of the ia[] or ja[] values. 6851 6852 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values 6853 6854 Fortran Node 6855 6856 In Fortran use 6857 $ PetscInt ia(1), ja(1) 6858 $ PetscOffset iia, jja 6859 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 6860 $ 6861 $ or 6862 $ 6863 $ PetscScalar, pointer :: xx_v(:) 6864 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 6865 6866 6867 Acess the ith and jth entries via ia(iia + i) and ja(jja + j) 6868 6869 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 6870 @*/ 6871 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 6872 { 6873 PetscErrorCode ierr; 6874 6875 PetscFunctionBegin; 6876 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6877 PetscValidType(mat,1); 6878 PetscValidIntPointer(n,4); 6879 if (ia) PetscValidIntPointer(ia,5); 6880 if (ja) PetscValidIntPointer(ja,6); 6881 PetscValidIntPointer(done,7); 6882 MatCheckPreallocated(mat,1); 6883 if (!mat->ops->getrowij) *done = PETSC_FALSE; 6884 else { 6885 *done = PETSC_TRUE; 6886 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 6887 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6888 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 6889 } 6890 PetscFunctionReturn(0); 6891 } 6892 6893 #undef __FUNCT__ 6894 #define __FUNCT__ "MatGetColumnIJ" 6895 /*@C 6896 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 6897 6898 Collective on Mat 6899 6900 Input Parameters: 6901 + mat - the matrix 6902 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6903 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6904 symmetrized 6905 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6906 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6907 always used. 6908 6909 Output Parameters: 6910 + n - number of columns in the (possibly compressed) matrix 6911 . ia - the column pointers 6912 . ja - the row indices 6913 - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 6914 6915 Level: developer 6916 6917 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 6918 @*/ 6919 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 6920 { 6921 PetscErrorCode ierr; 6922 6923 PetscFunctionBegin; 6924 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6925 PetscValidType(mat,1); 6926 PetscValidIntPointer(n,4); 6927 if (ia) PetscValidIntPointer(ia,5); 6928 if (ja) PetscValidIntPointer(ja,6); 6929 PetscValidIntPointer(done,7); 6930 MatCheckPreallocated(mat,1); 6931 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 6932 else { 6933 *done = PETSC_TRUE; 6934 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6935 } 6936 PetscFunctionReturn(0); 6937 } 6938 6939 #undef __FUNCT__ 6940 #define __FUNCT__ "MatRestoreRowIJ" 6941 /*@C 6942 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 6943 MatGetRowIJ(). 6944 6945 Collective on Mat 6946 6947 Input Parameters: 6948 + mat - the matrix 6949 . shift - 1 or zero indicating we want the indices starting at 0 or 1 6950 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 6951 symmetrized 6952 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 6953 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 6954 always used. 6955 6956 Output Parameters: 6957 + n - size of (possibly compressed) matrix 6958 . ia - the row pointers 6959 . ja - the column indices 6960 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 6961 6962 Level: developer 6963 6964 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 6965 @*/ 6966 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 6967 { 6968 PetscErrorCode ierr; 6969 6970 PetscFunctionBegin; 6971 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6972 PetscValidType(mat,1); 6973 if (ia) PetscValidIntPointer(ia,5); 6974 if (ja) PetscValidIntPointer(ja,6); 6975 PetscValidIntPointer(done,7); 6976 MatCheckPreallocated(mat,1); 6977 6978 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 6979 else { 6980 *done = PETSC_TRUE; 6981 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 6982 if (n) *n = 0; 6983 if (ia) *ia = NULL; 6984 if (ja) *ja = NULL; 6985 } 6986 PetscFunctionReturn(0); 6987 } 6988 6989 #undef __FUNCT__ 6990 #define __FUNCT__ "MatRestoreColumnIJ" 6991 /*@C 6992 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 6993 MatGetColumnIJ(). 6994 6995 Collective on Mat 6996 6997 Input Parameters: 6998 + mat - the matrix 6999 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7000 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7001 symmetrized 7002 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7003 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7004 always used. 7005 7006 Output Parameters: 7007 + n - size of (possibly compressed) matrix 7008 . ia - the column pointers 7009 . ja - the row indices 7010 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7011 7012 Level: developer 7013 7014 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7015 @*/ 7016 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7017 { 7018 PetscErrorCode ierr; 7019 7020 PetscFunctionBegin; 7021 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7022 PetscValidType(mat,1); 7023 if (ia) PetscValidIntPointer(ia,5); 7024 if (ja) PetscValidIntPointer(ja,6); 7025 PetscValidIntPointer(done,7); 7026 MatCheckPreallocated(mat,1); 7027 7028 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7029 else { 7030 *done = PETSC_TRUE; 7031 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7032 if (n) *n = 0; 7033 if (ia) *ia = NULL; 7034 if (ja) *ja = NULL; 7035 } 7036 PetscFunctionReturn(0); 7037 } 7038 7039 #undef __FUNCT__ 7040 #define __FUNCT__ "MatColoringPatch" 7041 /*@C 7042 MatColoringPatch -Used inside matrix coloring routines that 7043 use MatGetRowIJ() and/or MatGetColumnIJ(). 7044 7045 Collective on Mat 7046 7047 Input Parameters: 7048 + mat - the matrix 7049 . ncolors - max color value 7050 . n - number of entries in colorarray 7051 - colorarray - array indicating color for each column 7052 7053 Output Parameters: 7054 . iscoloring - coloring generated using colorarray information 7055 7056 Level: developer 7057 7058 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7059 7060 @*/ 7061 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7062 { 7063 PetscErrorCode ierr; 7064 7065 PetscFunctionBegin; 7066 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7067 PetscValidType(mat,1); 7068 PetscValidIntPointer(colorarray,4); 7069 PetscValidPointer(iscoloring,5); 7070 MatCheckPreallocated(mat,1); 7071 7072 if (!mat->ops->coloringpatch) { 7073 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7074 } else { 7075 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7076 } 7077 PetscFunctionReturn(0); 7078 } 7079 7080 7081 #undef __FUNCT__ 7082 #define __FUNCT__ "MatSetUnfactored" 7083 /*@ 7084 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7085 7086 Logically Collective on Mat 7087 7088 Input Parameter: 7089 . mat - the factored matrix to be reset 7090 7091 Notes: 7092 This routine should be used only with factored matrices formed by in-place 7093 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7094 format). This option can save memory, for example, when solving nonlinear 7095 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7096 ILU(0) preconditioner. 7097 7098 Note that one can specify in-place ILU(0) factorization by calling 7099 .vb 7100 PCType(pc,PCILU); 7101 PCFactorSeUseInPlace(pc); 7102 .ve 7103 or by using the options -pc_type ilu -pc_factor_in_place 7104 7105 In-place factorization ILU(0) can also be used as a local 7106 solver for the blocks within the block Jacobi or additive Schwarz 7107 methods (runtime option: -sub_pc_factor_in_place). See the discussion 7108 of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting 7109 local solver options. 7110 7111 Most users should employ the simplified KSP interface for linear solvers 7112 instead of working directly with matrix algebra routines such as this. 7113 See, e.g., KSPCreate(). 7114 7115 Level: developer 7116 7117 .seealso: PCFactorSetUseInPlace() 7118 7119 Concepts: matrices^unfactored 7120 7121 @*/ 7122 PetscErrorCode MatSetUnfactored(Mat mat) 7123 { 7124 PetscErrorCode ierr; 7125 7126 PetscFunctionBegin; 7127 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7128 PetscValidType(mat,1); 7129 MatCheckPreallocated(mat,1); 7130 mat->factortype = MAT_FACTOR_NONE; 7131 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7132 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7133 PetscFunctionReturn(0); 7134 } 7135 7136 /*MC 7137 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7138 7139 Synopsis: 7140 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7141 7142 Not collective 7143 7144 Input Parameter: 7145 . x - matrix 7146 7147 Output Parameters: 7148 + xx_v - the Fortran90 pointer to the array 7149 - ierr - error code 7150 7151 Example of Usage: 7152 .vb 7153 PetscScalar, pointer xx_v(:,:) 7154 .... 7155 call MatDenseGetArrayF90(x,xx_v,ierr) 7156 a = xx_v(3) 7157 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7158 .ve 7159 7160 Level: advanced 7161 7162 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray() 7163 7164 Concepts: matrices^accessing array 7165 7166 M*/ 7167 7168 /*MC 7169 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7170 accessed with MatGetArrayF90(). 7171 7172 Synopsis: 7173 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7174 7175 Not collective 7176 7177 Input Parameters: 7178 + x - matrix 7179 - xx_v - the Fortran90 pointer to the array 7180 7181 Output Parameter: 7182 . ierr - error code 7183 7184 Example of Usage: 7185 .vb 7186 PetscScalar, pointer xx_v(:) 7187 .... 7188 call MatDenseGetArrayF90(x,xx_v,ierr) 7189 a = xx_v(3) 7190 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7191 .ve 7192 7193 Level: advanced 7194 7195 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray() 7196 7197 M*/ 7198 7199 7200 #undef __FUNCT__ 7201 #define __FUNCT__ "MatGetSubMatrix" 7202 /*@ 7203 MatGetSubMatrix - Gets a single submatrix on the same number of processors 7204 as the original matrix. 7205 7206 Collective on Mat 7207 7208 Input Parameters: 7209 + mat - the original matrix 7210 . isrow - parallel IS containing the rows this processor should obtain 7211 . 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. 7212 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7213 7214 Output Parameter: 7215 . newmat - the new submatrix, of the same type as the old 7216 7217 Level: advanced 7218 7219 Notes: 7220 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7221 7222 The rows in isrow will be sorted into the same order as the original matrix on each process. 7223 7224 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7225 the MatGetSubMatrix() routine will create the newmat for you. Any additional calls 7226 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7227 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7228 you are finished using it. 7229 7230 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7231 the input matrix. 7232 7233 If iscol is NULL then all columns are obtained (not supported in Fortran). 7234 7235 Example usage: 7236 Consider the following 8x8 matrix with 34 non-zero values, that is 7237 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7238 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7239 as follows: 7240 7241 .vb 7242 1 2 0 | 0 3 0 | 0 4 7243 Proc0 0 5 6 | 7 0 0 | 8 0 7244 9 0 10 | 11 0 0 | 12 0 7245 ------------------------------------- 7246 13 0 14 | 15 16 17 | 0 0 7247 Proc1 0 18 0 | 19 20 21 | 0 0 7248 0 0 0 | 22 23 0 | 24 0 7249 ------------------------------------- 7250 Proc2 25 26 27 | 0 0 28 | 29 0 7251 30 0 0 | 31 32 33 | 0 34 7252 .ve 7253 7254 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7255 7256 .vb 7257 2 0 | 0 3 0 | 0 7258 Proc0 5 6 | 7 0 0 | 8 7259 ------------------------------- 7260 Proc1 18 0 | 19 20 21 | 0 7261 ------------------------------- 7262 Proc2 26 27 | 0 0 28 | 29 7263 0 0 | 31 32 33 | 0 7264 .ve 7265 7266 7267 Concepts: matrices^submatrices 7268 7269 .seealso: MatGetSubMatrices() 7270 @*/ 7271 PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7272 { 7273 PetscErrorCode ierr; 7274 PetscMPIInt size; 7275 Mat *local; 7276 IS iscoltmp; 7277 7278 PetscFunctionBegin; 7279 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7280 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7281 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7282 PetscValidPointer(newmat,5); 7283 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7284 PetscValidType(mat,1); 7285 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7286 MatCheckPreallocated(mat,1); 7287 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7288 7289 if (!iscol) { 7290 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7291 } else { 7292 iscoltmp = iscol; 7293 } 7294 7295 /* if original matrix is on just one processor then use submatrix generated */ 7296 if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7297 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7298 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7299 PetscFunctionReturn(0); 7300 } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) { 7301 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7302 *newmat = *local; 7303 ierr = PetscFree(local);CHKERRQ(ierr); 7304 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7305 PetscFunctionReturn(0); 7306 } else if (!mat->ops->getsubmatrix) { 7307 /* Create a new matrix type that implements the operation using the full matrix */ 7308 switch (cll) { 7309 case MAT_INITIAL_MATRIX: 7310 ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7311 break; 7312 case MAT_REUSE_MATRIX: 7313 ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7314 break; 7315 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7316 } 7317 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7318 PetscFunctionReturn(0); 7319 } 7320 7321 if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7322 ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7323 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7324 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7325 PetscFunctionReturn(0); 7326 } 7327 7328 #undef __FUNCT__ 7329 #define __FUNCT__ "MatStashSetInitialSize" 7330 /*@ 7331 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7332 used during the assembly process to store values that belong to 7333 other processors. 7334 7335 Not Collective 7336 7337 Input Parameters: 7338 + mat - the matrix 7339 . size - the initial size of the stash. 7340 - bsize - the initial size of the block-stash(if used). 7341 7342 Options Database Keys: 7343 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7344 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7345 7346 Level: intermediate 7347 7348 Notes: 7349 The block-stash is used for values set with MatSetValuesBlocked() while 7350 the stash is used for values set with MatSetValues() 7351 7352 Run with the option -info and look for output of the form 7353 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7354 to determine the appropriate value, MM, to use for size and 7355 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7356 to determine the value, BMM to use for bsize 7357 7358 Concepts: stash^setting matrix size 7359 Concepts: matrices^stash 7360 7361 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7362 7363 @*/ 7364 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7365 { 7366 PetscErrorCode ierr; 7367 7368 PetscFunctionBegin; 7369 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7370 PetscValidType(mat,1); 7371 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7372 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7373 PetscFunctionReturn(0); 7374 } 7375 7376 #undef __FUNCT__ 7377 #define __FUNCT__ "MatInterpolateAdd" 7378 /*@ 7379 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7380 the matrix 7381 7382 Neighbor-wise Collective on Mat 7383 7384 Input Parameters: 7385 + mat - the matrix 7386 . x,y - the vectors 7387 - w - where the result is stored 7388 7389 Level: intermediate 7390 7391 Notes: 7392 w may be the same vector as y. 7393 7394 This allows one to use either the restriction or interpolation (its transpose) 7395 matrix to do the interpolation 7396 7397 Concepts: interpolation 7398 7399 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7400 7401 @*/ 7402 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7403 { 7404 PetscErrorCode ierr; 7405 PetscInt M,N,Ny; 7406 7407 PetscFunctionBegin; 7408 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7409 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7410 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7411 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7412 PetscValidType(A,1); 7413 MatCheckPreallocated(A,1); 7414 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7415 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7416 if (M == Ny) { 7417 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7418 } else { 7419 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7420 } 7421 PetscFunctionReturn(0); 7422 } 7423 7424 #undef __FUNCT__ 7425 #define __FUNCT__ "MatInterpolate" 7426 /*@ 7427 MatInterpolate - y = A*x or A'*x depending on the shape of 7428 the matrix 7429 7430 Neighbor-wise Collective on Mat 7431 7432 Input Parameters: 7433 + mat - the matrix 7434 - x,y - the vectors 7435 7436 Level: intermediate 7437 7438 Notes: 7439 This allows one to use either the restriction or interpolation (its transpose) 7440 matrix to do the interpolation 7441 7442 Concepts: matrices^interpolation 7443 7444 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7445 7446 @*/ 7447 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 7448 { 7449 PetscErrorCode ierr; 7450 PetscInt M,N,Ny; 7451 7452 PetscFunctionBegin; 7453 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7454 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7455 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7456 PetscValidType(A,1); 7457 MatCheckPreallocated(A,1); 7458 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7459 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7460 if (M == Ny) { 7461 ierr = MatMult(A,x,y);CHKERRQ(ierr); 7462 } else { 7463 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 7464 } 7465 PetscFunctionReturn(0); 7466 } 7467 7468 #undef __FUNCT__ 7469 #define __FUNCT__ "MatRestrict" 7470 /*@ 7471 MatRestrict - y = A*x or A'*x 7472 7473 Neighbor-wise Collective on Mat 7474 7475 Input Parameters: 7476 + mat - the matrix 7477 - x,y - the vectors 7478 7479 Level: intermediate 7480 7481 Notes: 7482 This allows one to use either the restriction or interpolation (its transpose) 7483 matrix to do the restriction 7484 7485 Concepts: matrices^restriction 7486 7487 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 7488 7489 @*/ 7490 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 7491 { 7492 PetscErrorCode ierr; 7493 PetscInt M,N,Ny; 7494 7495 PetscFunctionBegin; 7496 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7497 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7498 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7499 PetscValidType(A,1); 7500 MatCheckPreallocated(A,1); 7501 7502 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7503 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7504 if (M == Ny) { 7505 ierr = MatMult(A,x,y);CHKERRQ(ierr); 7506 } else { 7507 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 7508 } 7509 PetscFunctionReturn(0); 7510 } 7511 7512 #undef __FUNCT__ 7513 #define __FUNCT__ "MatGetNullSpace" 7514 /*@ 7515 MatGetNullSpace - retrieves the null space to a matrix. 7516 7517 Logically Collective on Mat and MatNullSpace 7518 7519 Input Parameters: 7520 + mat - the matrix 7521 - nullsp - the null space object 7522 7523 Level: developer 7524 7525 Notes: 7526 This null space is used by solvers. Overwrites any previous null space that may have been attached 7527 7528 Concepts: null space^attaching to matrix 7529 7530 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace() 7531 @*/ 7532 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 7533 { 7534 PetscFunctionBegin; 7535 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7536 PetscValidType(mat,1); 7537 PetscValidPointer(nullsp,2); 7538 *nullsp = mat->nullsp; 7539 PetscFunctionReturn(0); 7540 } 7541 7542 #undef __FUNCT__ 7543 #define __FUNCT__ "MatSetNullSpace" 7544 /*@ 7545 MatSetNullSpace - attaches a null space to a matrix. 7546 This null space will be removed from the resulting vector whenever 7547 MatMult() is called 7548 7549 Logically Collective on Mat and MatNullSpace 7550 7551 Input Parameters: 7552 + mat - the matrix 7553 - nullsp - the null space object 7554 7555 Level: advanced 7556 7557 Notes: 7558 This null space is used by solvers. Overwrites any previous null space that may have been attached 7559 7560 Concepts: null space^attaching to matrix 7561 7562 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace() 7563 @*/ 7564 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 7565 { 7566 PetscErrorCode ierr; 7567 7568 PetscFunctionBegin; 7569 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7570 PetscValidType(mat,1); 7571 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 7572 MatCheckPreallocated(mat,1); 7573 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 7574 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 7575 7576 mat->nullsp = nullsp; 7577 PetscFunctionReturn(0); 7578 } 7579 7580 #undef __FUNCT__ 7581 #define __FUNCT__ "MatSetNearNullSpace" 7582 /*@ 7583 MatSetNearNullSpace - attaches a null space to a matrix. 7584 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 7585 7586 Logically Collective on Mat and MatNullSpace 7587 7588 Input Parameters: 7589 + mat - the matrix 7590 - nullsp - the null space object 7591 7592 Level: advanced 7593 7594 Notes: 7595 Overwrites any previous near null space that may have been attached 7596 7597 Concepts: null space^attaching to matrix 7598 7599 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace() 7600 @*/ 7601 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 7602 { 7603 PetscErrorCode ierr; 7604 7605 PetscFunctionBegin; 7606 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7607 PetscValidType(mat,1); 7608 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 7609 MatCheckPreallocated(mat,1); 7610 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 7611 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 7612 7613 mat->nearnullsp = nullsp; 7614 PetscFunctionReturn(0); 7615 } 7616 7617 #undef __FUNCT__ 7618 #define __FUNCT__ "MatGetNearNullSpace" 7619 /*@ 7620 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 7621 7622 Not Collective 7623 7624 Input Parameters: 7625 . mat - the matrix 7626 7627 Output Parameters: 7628 . nullsp - the null space object, NULL if not set 7629 7630 Level: developer 7631 7632 Concepts: null space^attaching to matrix 7633 7634 .seealso: MatSetNearNullSpace(), MatGetNullSpace() 7635 @*/ 7636 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 7637 { 7638 PetscFunctionBegin; 7639 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7640 PetscValidType(mat,1); 7641 PetscValidPointer(nullsp,2); 7642 MatCheckPreallocated(mat,1); 7643 *nullsp = mat->nearnullsp; 7644 PetscFunctionReturn(0); 7645 } 7646 7647 #undef __FUNCT__ 7648 #define __FUNCT__ "MatICCFactor" 7649 /*@C 7650 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 7651 7652 Collective on Mat 7653 7654 Input Parameters: 7655 + mat - the matrix 7656 . row - row/column permutation 7657 . fill - expected fill factor >= 1.0 7658 - level - level of fill, for ICC(k) 7659 7660 Notes: 7661 Probably really in-place only when level of fill is zero, otherwise allocates 7662 new space to store factored matrix and deletes previous memory. 7663 7664 Most users should employ the simplified KSP interface for linear solvers 7665 instead of working directly with matrix algebra routines such as this. 7666 See, e.g., KSPCreate(). 7667 7668 Level: developer 7669 7670 Concepts: matrices^incomplete Cholesky factorization 7671 Concepts: Cholesky factorization 7672 7673 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 7674 7675 Developer Note: fortran interface is not autogenerated as the f90 7676 interface defintion cannot be generated correctly [due to MatFactorInfo] 7677 7678 @*/ 7679 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 7680 { 7681 PetscErrorCode ierr; 7682 7683 PetscFunctionBegin; 7684 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7685 PetscValidType(mat,1); 7686 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 7687 PetscValidPointer(info,3); 7688 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 7689 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7690 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7691 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7692 MatCheckPreallocated(mat,1); 7693 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 7694 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7695 PetscFunctionReturn(0); 7696 } 7697 7698 #undef __FUNCT__ 7699 #define __FUNCT__ "MatSetValuesAdifor" 7700 /*@ 7701 MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix. 7702 7703 Not Collective 7704 7705 Input Parameters: 7706 + mat - the matrix 7707 . nl - leading dimension of v 7708 - v - the values compute with ADIFOR 7709 7710 Level: developer 7711 7712 Notes: 7713 Must call MatSetColoring() before using this routine. Also this matrix must already 7714 have its nonzero pattern determined. 7715 7716 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 7717 MatSetValues(), MatSetColoring() 7718 @*/ 7719 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v) 7720 { 7721 PetscErrorCode ierr; 7722 7723 PetscFunctionBegin; 7724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7725 PetscValidType(mat,1); 7726 PetscValidPointer(v,3); 7727 7728 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7729 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7730 if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7731 ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr); 7732 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 7733 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7734 PetscFunctionReturn(0); 7735 } 7736 7737 #undef __FUNCT__ 7738 #define __FUNCT__ "MatDiagonalScaleLocal" 7739 /*@ 7740 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 7741 ghosted ones. 7742 7743 Not Collective 7744 7745 Input Parameters: 7746 + mat - the matrix 7747 - diag = the diagonal values, including ghost ones 7748 7749 Level: developer 7750 7751 Notes: Works only for MPIAIJ and MPIBAIJ matrices 7752 7753 .seealso: MatDiagonalScale() 7754 @*/ 7755 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 7756 { 7757 PetscErrorCode ierr; 7758 PetscMPIInt size; 7759 7760 PetscFunctionBegin; 7761 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7762 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 7763 PetscValidType(mat,1); 7764 7765 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 7766 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 7767 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7768 if (size == 1) { 7769 PetscInt n,m; 7770 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 7771 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 7772 if (m == n) { 7773 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 7774 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 7775 } else { 7776 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 7777 } 7778 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 7779 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7780 PetscFunctionReturn(0); 7781 } 7782 7783 #undef __FUNCT__ 7784 #define __FUNCT__ "MatGetInertia" 7785 /*@ 7786 MatGetInertia - Gets the inertia from a factored matrix 7787 7788 Collective on Mat 7789 7790 Input Parameter: 7791 . mat - the matrix 7792 7793 Output Parameters: 7794 + nneg - number of negative eigenvalues 7795 . nzero - number of zero eigenvalues 7796 - npos - number of positive eigenvalues 7797 7798 Level: advanced 7799 7800 Notes: Matrix must have been factored by MatCholeskyFactor() 7801 7802 7803 @*/ 7804 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 7805 { 7806 PetscErrorCode ierr; 7807 7808 PetscFunctionBegin; 7809 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7810 PetscValidType(mat,1); 7811 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 7812 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 7813 if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7814 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 7815 PetscFunctionReturn(0); 7816 } 7817 7818 /* ----------------------------------------------------------------*/ 7819 #undef __FUNCT__ 7820 #define __FUNCT__ "MatSolves" 7821 /*@C 7822 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 7823 7824 Neighbor-wise Collective on Mat and Vecs 7825 7826 Input Parameters: 7827 + mat - the factored matrix 7828 - b - the right-hand-side vectors 7829 7830 Output Parameter: 7831 . x - the result vectors 7832 7833 Notes: 7834 The vectors b and x cannot be the same. I.e., one cannot 7835 call MatSolves(A,x,x). 7836 7837 Notes: 7838 Most users should employ the simplified KSP interface for linear solvers 7839 instead of working directly with matrix algebra routines such as this. 7840 See, e.g., KSPCreate(). 7841 7842 Level: developer 7843 7844 Concepts: matrices^triangular solves 7845 7846 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 7847 @*/ 7848 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 7849 { 7850 PetscErrorCode ierr; 7851 7852 PetscFunctionBegin; 7853 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7854 PetscValidType(mat,1); 7855 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 7856 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 7857 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 7858 7859 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7860 MatCheckPreallocated(mat,1); 7861 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 7862 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 7863 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 7864 PetscFunctionReturn(0); 7865 } 7866 7867 #undef __FUNCT__ 7868 #define __FUNCT__ "MatIsSymmetric" 7869 /*@ 7870 MatIsSymmetric - Test whether a matrix is symmetric 7871 7872 Collective on Mat 7873 7874 Input Parameter: 7875 + A - the matrix to test 7876 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 7877 7878 Output Parameters: 7879 . flg - the result 7880 7881 Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 7882 7883 Level: intermediate 7884 7885 Concepts: matrix^symmetry 7886 7887 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 7888 @*/ 7889 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 7890 { 7891 PetscErrorCode ierr; 7892 7893 PetscFunctionBegin; 7894 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7895 PetscValidPointer(flg,2); 7896 7897 if (!A->symmetric_set) { 7898 if (!A->ops->issymmetric) { 7899 MatType mattype; 7900 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7901 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 7902 } 7903 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 7904 if (!tol) { 7905 A->symmetric_set = PETSC_TRUE; 7906 A->symmetric = *flg; 7907 if (A->symmetric) { 7908 A->structurally_symmetric_set = PETSC_TRUE; 7909 A->structurally_symmetric = PETSC_TRUE; 7910 } 7911 } 7912 } else if (A->symmetric) { 7913 *flg = PETSC_TRUE; 7914 } else if (!tol) { 7915 *flg = PETSC_FALSE; 7916 } else { 7917 if (!A->ops->issymmetric) { 7918 MatType mattype; 7919 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7920 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 7921 } 7922 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 7923 } 7924 PetscFunctionReturn(0); 7925 } 7926 7927 #undef __FUNCT__ 7928 #define __FUNCT__ "MatIsHermitian" 7929 /*@ 7930 MatIsHermitian - Test whether a matrix is Hermitian 7931 7932 Collective on Mat 7933 7934 Input Parameter: 7935 + A - the matrix to test 7936 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 7937 7938 Output Parameters: 7939 . flg - the result 7940 7941 Level: intermediate 7942 7943 Concepts: matrix^symmetry 7944 7945 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 7946 MatIsSymmetricKnown(), MatIsSymmetric() 7947 @*/ 7948 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 7949 { 7950 PetscErrorCode ierr; 7951 7952 PetscFunctionBegin; 7953 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7954 PetscValidPointer(flg,2); 7955 7956 if (!A->hermitian_set) { 7957 if (!A->ops->ishermitian) { 7958 MatType mattype; 7959 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7960 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 7961 } 7962 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 7963 if (!tol) { 7964 A->hermitian_set = PETSC_TRUE; 7965 A->hermitian = *flg; 7966 if (A->hermitian) { 7967 A->structurally_symmetric_set = PETSC_TRUE; 7968 A->structurally_symmetric = PETSC_TRUE; 7969 } 7970 } 7971 } else if (A->hermitian) { 7972 *flg = PETSC_TRUE; 7973 } else if (!tol) { 7974 *flg = PETSC_FALSE; 7975 } else { 7976 if (!A->ops->ishermitian) { 7977 MatType mattype; 7978 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 7979 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 7980 } 7981 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 7982 } 7983 PetscFunctionReturn(0); 7984 } 7985 7986 #undef __FUNCT__ 7987 #define __FUNCT__ "MatIsSymmetricKnown" 7988 /*@ 7989 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 7990 7991 Not Collective 7992 7993 Input Parameter: 7994 . A - the matrix to check 7995 7996 Output Parameters: 7997 + set - if the symmetric flag is set (this tells you if the next flag is valid) 7998 - flg - the result 7999 8000 Level: advanced 8001 8002 Concepts: matrix^symmetry 8003 8004 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8005 if you want it explicitly checked 8006 8007 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8008 @*/ 8009 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8010 { 8011 PetscFunctionBegin; 8012 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8013 PetscValidPointer(set,2); 8014 PetscValidPointer(flg,3); 8015 if (A->symmetric_set) { 8016 *set = PETSC_TRUE; 8017 *flg = A->symmetric; 8018 } else { 8019 *set = PETSC_FALSE; 8020 } 8021 PetscFunctionReturn(0); 8022 } 8023 8024 #undef __FUNCT__ 8025 #define __FUNCT__ "MatIsHermitianKnown" 8026 /*@ 8027 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8028 8029 Not Collective 8030 8031 Input Parameter: 8032 . A - the matrix to check 8033 8034 Output Parameters: 8035 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8036 - flg - the result 8037 8038 Level: advanced 8039 8040 Concepts: matrix^symmetry 8041 8042 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8043 if you want it explicitly checked 8044 8045 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8046 @*/ 8047 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8048 { 8049 PetscFunctionBegin; 8050 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8051 PetscValidPointer(set,2); 8052 PetscValidPointer(flg,3); 8053 if (A->hermitian_set) { 8054 *set = PETSC_TRUE; 8055 *flg = A->hermitian; 8056 } else { 8057 *set = PETSC_FALSE; 8058 } 8059 PetscFunctionReturn(0); 8060 } 8061 8062 #undef __FUNCT__ 8063 #define __FUNCT__ "MatIsStructurallySymmetric" 8064 /*@ 8065 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8066 8067 Collective on Mat 8068 8069 Input Parameter: 8070 . A - the matrix to test 8071 8072 Output Parameters: 8073 . flg - the result 8074 8075 Level: intermediate 8076 8077 Concepts: matrix^symmetry 8078 8079 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8080 @*/ 8081 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8082 { 8083 PetscErrorCode ierr; 8084 8085 PetscFunctionBegin; 8086 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8087 PetscValidPointer(flg,2); 8088 if (!A->structurally_symmetric_set) { 8089 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8090 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8091 8092 A->structurally_symmetric_set = PETSC_TRUE; 8093 } 8094 *flg = A->structurally_symmetric; 8095 PetscFunctionReturn(0); 8096 } 8097 8098 #undef __FUNCT__ 8099 #define __FUNCT__ "MatStashGetInfo" 8100 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*); 8101 /*@ 8102 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8103 to be communicated to other processors during the MatAssemblyBegin/End() process 8104 8105 Not collective 8106 8107 Input Parameter: 8108 . vec - the vector 8109 8110 Output Parameters: 8111 + nstash - the size of the stash 8112 . reallocs - the number of additional mallocs incurred. 8113 . bnstash - the size of the block stash 8114 - breallocs - the number of additional mallocs incurred.in the block stash 8115 8116 Level: advanced 8117 8118 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8119 8120 @*/ 8121 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8122 { 8123 PetscErrorCode ierr; 8124 8125 PetscFunctionBegin; 8126 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8127 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8128 PetscFunctionReturn(0); 8129 } 8130 8131 #undef __FUNCT__ 8132 #define __FUNCT__ "MatGetVecs" 8133 /*@C 8134 MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same 8135 parallel layout 8136 8137 Collective on Mat 8138 8139 Input Parameter: 8140 . mat - the matrix 8141 8142 Output Parameter: 8143 + right - (optional) vector that the matrix can be multiplied against 8144 - left - (optional) vector that the matrix vector product can be stored in 8145 8146 Level: advanced 8147 8148 .seealso: MatCreate() 8149 @*/ 8150 PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left) 8151 { 8152 PetscErrorCode ierr; 8153 8154 PetscFunctionBegin; 8155 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8156 PetscValidType(mat,1); 8157 MatCheckPreallocated(mat,1); 8158 if (mat->ops->getvecs) { 8159 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8160 } else { 8161 PetscMPIInt size; 8162 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);CHKERRQ(ierr); 8163 if (right) { 8164 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8165 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8166 ierr = VecSetBlockSize(*right,mat->rmap->bs);CHKERRQ(ierr); 8167 ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr); 8168 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8169 } 8170 if (left) { 8171 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8172 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8173 ierr = VecSetBlockSize(*left,mat->rmap->bs);CHKERRQ(ierr); 8174 ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr); 8175 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8176 } 8177 } 8178 PetscFunctionReturn(0); 8179 } 8180 8181 #undef __FUNCT__ 8182 #define __FUNCT__ "MatFactorInfoInitialize" 8183 /*@C 8184 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8185 with default values. 8186 8187 Not Collective 8188 8189 Input Parameters: 8190 . info - the MatFactorInfo data structure 8191 8192 8193 Notes: The solvers are generally used through the KSP and PC objects, for example 8194 PCLU, PCILU, PCCHOLESKY, PCICC 8195 8196 Level: developer 8197 8198 .seealso: MatFactorInfo 8199 8200 Developer Note: fortran interface is not autogenerated as the f90 8201 interface defintion cannot be generated correctly [due to MatFactorInfo] 8202 8203 @*/ 8204 8205 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8206 { 8207 PetscErrorCode ierr; 8208 8209 PetscFunctionBegin; 8210 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8211 PetscFunctionReturn(0); 8212 } 8213 8214 #undef __FUNCT__ 8215 #define __FUNCT__ "MatPtAP" 8216 /*@ 8217 MatPtAP - Creates the matrix product C = P^T * A * P 8218 8219 Neighbor-wise Collective on Mat 8220 8221 Input Parameters: 8222 + A - the matrix 8223 . P - the projection matrix 8224 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8225 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)) 8226 8227 Output Parameters: 8228 . C - the product matrix 8229 8230 Notes: 8231 C will be created and must be destroyed by the user with MatDestroy(). 8232 8233 This routine is currently only implemented for pairs of AIJ matrices and classes 8234 which inherit from AIJ. 8235 8236 Level: intermediate 8237 8238 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 8239 @*/ 8240 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 8241 { 8242 PetscErrorCode ierr; 8243 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8244 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 8245 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 8246 PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE; 8247 8248 PetscFunctionBegin; 8249 ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr); 8250 ierr = PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr); 8251 8252 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8253 PetscValidType(A,1); 8254 MatCheckPreallocated(A,1); 8255 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8256 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8257 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8258 PetscValidType(P,2); 8259 MatCheckPreallocated(P,2); 8260 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8261 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8262 8263 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); 8264 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8265 8266 if (scall == MAT_REUSE_MATRIX) { 8267 PetscValidPointer(*C,5); 8268 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 8269 if (viatranspose || viamatmatmatmult) { 8270 Mat Pt; 8271 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 8272 if (viamatmatmatmult) { 8273 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 8274 } else { 8275 Mat AP; 8276 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 8277 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 8278 ierr = MatDestroy(&AP);CHKERRQ(ierr); 8279 } 8280 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 8281 } else { 8282 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8283 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8284 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 8285 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8286 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8287 } 8288 PetscFunctionReturn(0); 8289 } 8290 8291 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8292 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8293 8294 fA = A->ops->ptap; 8295 fP = P->ops->ptap; 8296 if (fP == fA) { 8297 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 8298 ptap = fA; 8299 } else { 8300 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 8301 char ptapname[256]; 8302 ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr); 8303 ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8304 ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr); 8305 ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr); 8306 ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 8307 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 8308 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); 8309 } 8310 8311 if (viatranspose || viamatmatmatmult) { 8312 Mat Pt; 8313 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 8314 if (viamatmatmatmult) { 8315 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 8316 ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr); 8317 } else { 8318 Mat AP; 8319 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 8320 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 8321 ierr = MatDestroy(&AP);CHKERRQ(ierr); 8322 ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr); 8323 } 8324 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 8325 } else { 8326 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8327 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 8328 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 8329 } 8330 PetscFunctionReturn(0); 8331 } 8332 8333 #undef __FUNCT__ 8334 #define __FUNCT__ "MatPtAPNumeric" 8335 /*@ 8336 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 8337 8338 Neighbor-wise Collective on Mat 8339 8340 Input Parameters: 8341 + A - the matrix 8342 - P - the projection matrix 8343 8344 Output Parameters: 8345 . C - the product matrix 8346 8347 Notes: 8348 C must have been created by calling MatPtAPSymbolic and must be destroyed by 8349 the user using MatDeatroy(). 8350 8351 This routine is currently only implemented for pairs of AIJ matrices and classes 8352 which inherit from AIJ. C will be of type MATAIJ. 8353 8354 Level: intermediate 8355 8356 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 8357 @*/ 8358 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 8359 { 8360 PetscErrorCode ierr; 8361 8362 PetscFunctionBegin; 8363 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8364 PetscValidType(A,1); 8365 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8366 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8367 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8368 PetscValidType(P,2); 8369 MatCheckPreallocated(P,2); 8370 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8371 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8372 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8373 PetscValidType(C,3); 8374 MatCheckPreallocated(C,3); 8375 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8376 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); 8377 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); 8378 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); 8379 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); 8380 MatCheckPreallocated(A,1); 8381 8382 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8383 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 8384 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 8385 PetscFunctionReturn(0); 8386 } 8387 8388 #undef __FUNCT__ 8389 #define __FUNCT__ "MatPtAPSymbolic" 8390 /*@ 8391 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 8392 8393 Neighbor-wise Collective on Mat 8394 8395 Input Parameters: 8396 + A - the matrix 8397 - P - the projection matrix 8398 8399 Output Parameters: 8400 . C - the (i,j) structure of the product matrix 8401 8402 Notes: 8403 C will be created and must be destroyed by the user with MatDestroy(). 8404 8405 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 8406 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 8407 this (i,j) structure by calling MatPtAPNumeric(). 8408 8409 Level: intermediate 8410 8411 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 8412 @*/ 8413 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 8414 { 8415 PetscErrorCode ierr; 8416 8417 PetscFunctionBegin; 8418 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8419 PetscValidType(A,1); 8420 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8421 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8422 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8423 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 8424 PetscValidType(P,2); 8425 MatCheckPreallocated(P,2); 8426 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8427 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8428 PetscValidPointer(C,3); 8429 8430 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); 8431 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); 8432 MatCheckPreallocated(A,1); 8433 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 8434 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 8435 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 8436 8437 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 8438 PetscFunctionReturn(0); 8439 } 8440 8441 #undef __FUNCT__ 8442 #define __FUNCT__ "MatRARt" 8443 /*@ 8444 MatRARt - Creates the matrix product C = R * A * R^T 8445 8446 Neighbor-wise Collective on Mat 8447 8448 Input Parameters: 8449 + A - the matrix 8450 . R - the projection matrix 8451 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8452 - fill - expected fill as ratio of nnz(C)/nnz(A) 8453 8454 Output Parameters: 8455 . C - the product matrix 8456 8457 Notes: 8458 C will be created and must be destroyed by the user with MatDestroy(). 8459 8460 This routine is currently only implemented for pairs of AIJ matrices and classes 8461 which inherit from AIJ. 8462 8463 Level: intermediate 8464 8465 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 8466 @*/ 8467 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 8468 { 8469 PetscErrorCode ierr; 8470 8471 PetscFunctionBegin; 8472 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8473 PetscValidType(A,1); 8474 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8475 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8476 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8477 PetscValidType(R,2); 8478 MatCheckPreallocated(R,2); 8479 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8480 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8481 PetscValidPointer(C,3); 8482 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); 8483 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8484 MatCheckPreallocated(A,1); 8485 8486 if (!A->ops->rart) { 8487 MatType mattype; 8488 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8489 SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype); 8490 } 8491 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 8492 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 8493 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 8494 PetscFunctionReturn(0); 8495 } 8496 8497 #undef __FUNCT__ 8498 #define __FUNCT__ "MatRARtNumeric" 8499 /*@ 8500 MatRARtNumeric - Computes the matrix product C = R * A * R^T 8501 8502 Neighbor-wise Collective on Mat 8503 8504 Input Parameters: 8505 + A - the matrix 8506 - R - the projection matrix 8507 8508 Output Parameters: 8509 . C - the product matrix 8510 8511 Notes: 8512 C must have been created by calling MatRARtSymbolic and must be destroyed by 8513 the user using MatDeatroy(). 8514 8515 This routine is currently only implemented for pairs of AIJ matrices and classes 8516 which inherit from AIJ. C will be of type MATAIJ. 8517 8518 Level: intermediate 8519 8520 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 8521 @*/ 8522 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 8523 { 8524 PetscErrorCode ierr; 8525 8526 PetscFunctionBegin; 8527 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8528 PetscValidType(A,1); 8529 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8530 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8531 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8532 PetscValidType(R,2); 8533 MatCheckPreallocated(R,2); 8534 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8535 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8536 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 8537 PetscValidType(C,3); 8538 MatCheckPreallocated(C,3); 8539 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8540 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); 8541 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); 8542 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); 8543 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); 8544 MatCheckPreallocated(A,1); 8545 8546 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 8547 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 8548 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 8549 PetscFunctionReturn(0); 8550 } 8551 8552 #undef __FUNCT__ 8553 #define __FUNCT__ "MatRARtSymbolic" 8554 /*@ 8555 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 8556 8557 Neighbor-wise Collective on Mat 8558 8559 Input Parameters: 8560 + A - the matrix 8561 - R - the projection matrix 8562 8563 Output Parameters: 8564 . C - the (i,j) structure of the product matrix 8565 8566 Notes: 8567 C will be created and must be destroyed by the user with MatDestroy(). 8568 8569 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 8570 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 8571 this (i,j) structure by calling MatRARtNumeric(). 8572 8573 Level: intermediate 8574 8575 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 8576 @*/ 8577 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 8578 { 8579 PetscErrorCode ierr; 8580 8581 PetscFunctionBegin; 8582 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8583 PetscValidType(A,1); 8584 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8585 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8586 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8587 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 8588 PetscValidType(R,2); 8589 MatCheckPreallocated(R,2); 8590 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8591 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8592 PetscValidPointer(C,3); 8593 8594 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); 8595 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); 8596 MatCheckPreallocated(A,1); 8597 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 8598 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 8599 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 8600 8601 ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); 8602 PetscFunctionReturn(0); 8603 } 8604 8605 #undef __FUNCT__ 8606 #define __FUNCT__ "MatMatMult" 8607 /*@ 8608 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 8609 8610 Neighbor-wise Collective on Mat 8611 8612 Input Parameters: 8613 + A - the left matrix 8614 . B - the right matrix 8615 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8616 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 8617 if the result is a dense matrix this is irrelevent 8618 8619 Output Parameters: 8620 . C - the product matrix 8621 8622 Notes: 8623 Unless scall is MAT_REUSE_MATRIX C will be created. 8624 8625 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8626 8627 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8628 actually needed. 8629 8630 If you have many matrices with the same non-zero structure to multiply, you 8631 should either 8632 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 8633 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 8634 8635 Level: intermediate 8636 8637 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 8638 @*/ 8639 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8640 { 8641 PetscErrorCode ierr; 8642 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8643 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8644 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 8645 8646 PetscFunctionBegin; 8647 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8648 PetscValidType(A,1); 8649 MatCheckPreallocated(A,1); 8650 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8651 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8652 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8653 PetscValidType(B,2); 8654 MatCheckPreallocated(B,2); 8655 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8656 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8657 PetscValidPointer(C,3); 8658 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); 8659 if (scall == MAT_REUSE_MATRIX) { 8660 PetscValidPointer(*C,5); 8661 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 8662 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8663 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8664 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 8665 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8666 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8667 PetscFunctionReturn(0); 8668 } 8669 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8670 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 8671 8672 fA = A->ops->matmult; 8673 fB = B->ops->matmult; 8674 if (fB == fA) { 8675 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 8676 mult = fB; 8677 } else { 8678 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 8679 char multname[256]; 8680 ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr); 8681 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8682 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 8683 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8684 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 8685 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 8686 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); 8687 } 8688 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8689 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 8690 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 8691 PetscFunctionReturn(0); 8692 } 8693 8694 #undef __FUNCT__ 8695 #define __FUNCT__ "MatMatMultSymbolic" 8696 /*@ 8697 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 8698 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 8699 8700 Neighbor-wise Collective on Mat 8701 8702 Input Parameters: 8703 + A - the left matrix 8704 . B - the right matrix 8705 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 8706 if C is a dense matrix this is irrelevent 8707 8708 Output Parameters: 8709 . C - the product matrix 8710 8711 Notes: 8712 Unless scall is MAT_REUSE_MATRIX C will be created. 8713 8714 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8715 actually needed. 8716 8717 This routine is currently implemented for 8718 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 8719 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 8720 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 8721 8722 Level: intermediate 8723 8724 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 8725 We should incorporate them into PETSc. 8726 8727 .seealso: MatMatMult(), MatMatMultNumeric() 8728 @*/ 8729 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 8730 { 8731 PetscErrorCode ierr; 8732 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 8733 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 8734 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 8735 8736 PetscFunctionBegin; 8737 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8738 PetscValidType(A,1); 8739 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8740 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8741 8742 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8743 PetscValidType(B,2); 8744 MatCheckPreallocated(B,2); 8745 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8746 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8747 PetscValidPointer(C,3); 8748 8749 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); 8750 if (fill == PETSC_DEFAULT) fill = 2.0; 8751 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8752 MatCheckPreallocated(A,1); 8753 8754 Asymbolic = A->ops->matmultsymbolic; 8755 Bsymbolic = B->ops->matmultsymbolic; 8756 if (Asymbolic == Bsymbolic) { 8757 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 8758 symbolic = Bsymbolic; 8759 } else { /* dispatch based on the type of A and B */ 8760 char symbolicname[256]; 8761 ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr); 8762 ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8763 ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr); 8764 ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8765 ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr); 8766 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 8767 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); 8768 } 8769 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8770 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 8771 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8772 PetscFunctionReturn(0); 8773 } 8774 8775 #undef __FUNCT__ 8776 #define __FUNCT__ "MatMatMultNumeric" 8777 /*@ 8778 MatMatMultNumeric - Performs the numeric matrix-matrix product. 8779 Call this routine after first calling MatMatMultSymbolic(). 8780 8781 Neighbor-wise Collective on Mat 8782 8783 Input Parameters: 8784 + A - the left matrix 8785 - B - the right matrix 8786 8787 Output Parameters: 8788 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 8789 8790 Notes: 8791 C must have been created with MatMatMultSymbolic(). 8792 8793 This routine is currently implemented for 8794 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 8795 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 8796 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 8797 8798 Level: intermediate 8799 8800 .seealso: MatMatMult(), MatMatMultSymbolic() 8801 @*/ 8802 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 8803 { 8804 PetscErrorCode ierr; 8805 8806 PetscFunctionBegin; 8807 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 8808 PetscFunctionReturn(0); 8809 } 8810 8811 #undef __FUNCT__ 8812 #define __FUNCT__ "MatMatTransposeMult" 8813 /*@ 8814 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 8815 8816 Neighbor-wise Collective on Mat 8817 8818 Input Parameters: 8819 + A - the left matrix 8820 . B - the right matrix 8821 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8822 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 8823 8824 Output Parameters: 8825 . C - the product matrix 8826 8827 Notes: 8828 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 8829 8830 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8831 8832 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8833 actually needed. 8834 8835 This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ. 8836 8837 Level: intermediate 8838 8839 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 8840 @*/ 8841 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8842 { 8843 PetscErrorCode ierr; 8844 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8845 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8846 8847 PetscFunctionBegin; 8848 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8849 PetscValidType(A,1); 8850 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8851 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8852 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8853 PetscValidType(B,2); 8854 MatCheckPreallocated(B,2); 8855 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8856 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8857 PetscValidPointer(C,3); 8858 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); 8859 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8860 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8861 MatCheckPreallocated(A,1); 8862 8863 fA = A->ops->mattransposemult; 8864 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 8865 fB = B->ops->mattransposemult; 8866 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 8867 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); 8868 8869 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 8870 if (scall == MAT_INITIAL_MATRIX) { 8871 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8872 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 8873 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 8874 } 8875 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 8876 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 8877 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 8878 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 8879 PetscFunctionReturn(0); 8880 } 8881 8882 #undef __FUNCT__ 8883 #define __FUNCT__ "MatTransposeMatMult" 8884 /*@ 8885 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 8886 8887 Neighbor-wise Collective on Mat 8888 8889 Input Parameters: 8890 + A - the left matrix 8891 . B - the right matrix 8892 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8893 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 8894 8895 Output Parameters: 8896 . C - the product matrix 8897 8898 Notes: 8899 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 8900 8901 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 8902 8903 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8904 actually needed. 8905 8906 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 8907 which inherit from SeqAIJ. C will be of same type as the input matrices. 8908 8909 Level: intermediate 8910 8911 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 8912 @*/ 8913 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 8914 { 8915 PetscErrorCode ierr; 8916 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 8917 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 8918 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 8919 8920 PetscFunctionBegin; 8921 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8922 PetscValidType(A,1); 8923 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8924 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8925 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8926 PetscValidType(B,2); 8927 MatCheckPreallocated(B,2); 8928 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8929 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8930 PetscValidPointer(C,3); 8931 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); 8932 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 8933 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill); 8934 MatCheckPreallocated(A,1); 8935 8936 fA = A->ops->transposematmult; 8937 fB = B->ops->transposematmult; 8938 if (fB==fA) { 8939 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 8940 transposematmult = fA; 8941 } else { 8942 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 8943 char multname[256]; 8944 ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr); 8945 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 8946 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 8947 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 8948 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 8949 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 8950 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); 8951 } 8952 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 8953 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 8954 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 8955 PetscFunctionReturn(0); 8956 } 8957 8958 #undef __FUNCT__ 8959 #define __FUNCT__ "MatMatMatMult" 8960 /*@ 8961 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 8962 8963 Neighbor-wise Collective on Mat 8964 8965 Input Parameters: 8966 + A - the left matrix 8967 . B - the middle matrix 8968 . C - the right matrix 8969 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8970 - 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 8971 if the result is a dense matrix this is irrelevent 8972 8973 Output Parameters: 8974 . D - the product matrix 8975 8976 Notes: 8977 Unless scall is MAT_REUSE_MATRIX D will be created. 8978 8979 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 8980 8981 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 8982 actually needed. 8983 8984 If you have many matrices with the same non-zero structure to multiply, you 8985 should either 8986 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 8987 $ 2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed 8988 8989 Level: intermediate 8990 8991 .seealso: MatMatMult, MatPtAP() 8992 @*/ 8993 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 8994 { 8995 PetscErrorCode ierr; 8996 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 8997 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 8998 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 8999 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9000 9001 PetscFunctionBegin; 9002 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9003 PetscValidType(A,1); 9004 MatCheckPreallocated(A,1); 9005 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9006 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9007 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9008 PetscValidType(B,2); 9009 MatCheckPreallocated(B,2); 9010 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9011 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9012 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9013 PetscValidPointer(C,3); 9014 MatCheckPreallocated(C,3); 9015 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9016 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9017 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); 9018 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); 9019 if (scall == MAT_REUSE_MATRIX) { 9020 PetscValidPointer(*D,6); 9021 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9022 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9023 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9024 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9025 PetscFunctionReturn(0); 9026 } 9027 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9028 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill); 9029 9030 fA = A->ops->matmatmult; 9031 fB = B->ops->matmatmult; 9032 fC = C->ops->matmatmult; 9033 if (fA == fB && fA == fC) { 9034 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9035 mult = fA; 9036 } else { 9037 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9038 char multname[256]; 9039 ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr); 9040 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9041 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9042 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9043 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9044 ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr); 9045 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); 9046 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9047 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); 9048 } 9049 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9050 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9051 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9052 PetscFunctionReturn(0); 9053 } 9054 9055 #undef __FUNCT__ 9056 #define __FUNCT__ "MatGetRedundantMatrix" 9057 /*@C 9058 MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9059 9060 Collective on Mat 9061 9062 Input Parameters: 9063 + mat - the matrix 9064 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9065 . subcomm - MPI communicator split from the communicator where mat resides in 9066 . mlocal_red - number of local rows of the redundant matrix 9067 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9068 9069 Output Parameter: 9070 . matredundant - redundant matrix 9071 9072 Notes: 9073 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9074 original matrix has not changed from that last call to MatGetRedundantMatrix(). 9075 9076 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9077 calling it. 9078 9079 Only MPIAIJ matrix is supported. 9080 9081 Level: advanced 9082 9083 Concepts: subcommunicator 9084 Concepts: duplicate matrix 9085 9086 .seealso: MatDestroy() 9087 @*/ 9088 PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant) 9089 { 9090 PetscErrorCode ierr; 9091 9092 PetscFunctionBegin; 9093 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9094 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9095 PetscValidPointer(*matredundant,6); 9096 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,6); 9097 } 9098 if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9099 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9100 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9101 MatCheckPreallocated(mat,1); 9102 9103 ierr = PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr); 9104 ierr = (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);CHKERRQ(ierr); 9105 ierr = PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);CHKERRQ(ierr); 9106 PetscFunctionReturn(0); 9107 } 9108 9109 #undef __FUNCT__ 9110 #define __FUNCT__ "MatGetMultiProcBlock" 9111 /*@C 9112 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 9113 a given 'mat' object. Each submatrix can span multiple procs. 9114 9115 Collective on Mat 9116 9117 Input Parameters: 9118 + mat - the matrix 9119 . subcomm - the subcommunicator obtained by com_split(comm) 9120 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9121 9122 Output Parameter: 9123 . subMat - 'parallel submatrices each spans a given subcomm 9124 9125 Notes: 9126 The submatrix partition across processors is dictated by 'subComm' a 9127 communicator obtained by com_split(comm). The comm_split 9128 is not restriced to be grouped with consecutive original ranks. 9129 9130 Due the comm_split() usage, the parallel layout of the submatrices 9131 map directly to the layout of the original matrix [wrt the local 9132 row,col partitioning]. So the original 'DiagonalMat' naturally maps 9133 into the 'DiagonalMat' of the subMat, hence it is used directly from 9134 the subMat. However the offDiagMat looses some columns - and this is 9135 reconstructed with MatSetValues() 9136 9137 Level: advanced 9138 9139 Concepts: subcommunicator 9140 Concepts: submatrices 9141 9142 .seealso: MatGetSubMatrices() 9143 @*/ 9144 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 9145 { 9146 PetscErrorCode ierr; 9147 PetscMPIInt commsize,subCommSize; 9148 9149 PetscFunctionBegin; 9150 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 9151 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 9152 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 9153 9154 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9155 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 9156 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 9157 PetscFunctionReturn(0); 9158 } 9159 9160 #undef __FUNCT__ 9161 #define __FUNCT__ "MatGetLocalSubMatrix" 9162 /*@ 9163 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 9164 9165 Not Collective 9166 9167 Input Arguments: 9168 mat - matrix to extract local submatrix from 9169 isrow - local row indices for submatrix 9170 iscol - local column indices for submatrix 9171 9172 Output Arguments: 9173 submat - the submatrix 9174 9175 Level: intermediate 9176 9177 Notes: 9178 The submat should be returned with MatRestoreLocalSubMatrix(). 9179 9180 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 9181 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 9182 9183 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 9184 MatSetValuesBlockedLocal() will also be implemented. 9185 9186 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef() 9187 @*/ 9188 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9189 { 9190 PetscErrorCode ierr; 9191 9192 PetscFunctionBegin; 9193 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9194 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9195 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9196 PetscCheckSameComm(isrow,2,iscol,3); 9197 PetscValidPointer(submat,4); 9198 9199 if (mat->ops->getlocalsubmatrix) { 9200 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9201 } else { 9202 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 9203 } 9204 PetscFunctionReturn(0); 9205 } 9206 9207 #undef __FUNCT__ 9208 #define __FUNCT__ "MatRestoreLocalSubMatrix" 9209 /*@ 9210 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 9211 9212 Not Collective 9213 9214 Input Arguments: 9215 mat - matrix to extract local submatrix from 9216 isrow - local row indices for submatrix 9217 iscol - local column indices for submatrix 9218 submat - the submatrix 9219 9220 Level: intermediate 9221 9222 .seealso: MatGetLocalSubMatrix() 9223 @*/ 9224 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 9225 { 9226 PetscErrorCode ierr; 9227 9228 PetscFunctionBegin; 9229 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9230 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 9231 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 9232 PetscCheckSameComm(isrow,2,iscol,3); 9233 PetscValidPointer(submat,4); 9234 if (*submat) { 9235 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 9236 } 9237 9238 if (mat->ops->restorelocalsubmatrix) { 9239 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 9240 } else { 9241 ierr = MatDestroy(submat);CHKERRQ(ierr); 9242 } 9243 *submat = NULL; 9244 PetscFunctionReturn(0); 9245 } 9246 9247 /* --------------------------------------------------------*/ 9248 #undef __FUNCT__ 9249 #define __FUNCT__ "MatFindZeroDiagonals" 9250 /*@ 9251 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix 9252 9253 Collective on Mat 9254 9255 Input Parameter: 9256 . mat - the matrix 9257 9258 Output Parameter: 9259 . is - if any rows have zero diagonals this contains the list of them 9260 9261 Level: developer 9262 9263 Concepts: matrix-vector product 9264 9265 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 9266 @*/ 9267 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 9268 { 9269 PetscErrorCode ierr; 9270 9271 PetscFunctionBegin; 9272 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9273 PetscValidType(mat,1); 9274 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9275 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9276 9277 if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined"); 9278 ierr = (*mat->ops->findzerodiagonals)(mat,is);CHKERRQ(ierr); 9279 PetscFunctionReturn(0); 9280 } 9281 9282 #undef __FUNCT__ 9283 #define __FUNCT__ "MatInvertBlockDiagonal" 9284 /*@C 9285 MatInvertBlockDiagonal - Inverts the block diagonal entries. 9286 9287 Collective on Mat 9288 9289 Input Parameters: 9290 . mat - the matrix 9291 9292 Output Parameters: 9293 . values - the block inverses in column major order (FORTRAN-like) 9294 9295 Note: 9296 This routine is not available from Fortran. 9297 9298 Level: advanced 9299 @*/ 9300 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 9301 { 9302 PetscErrorCode ierr; 9303 9304 PetscFunctionBegin; 9305 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9306 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9307 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9308 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 9309 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 9310 PetscFunctionReturn(0); 9311 } 9312 9313 #undef __FUNCT__ 9314 #define __FUNCT__ "MatTransposeColoringDestroy" 9315 /*@C 9316 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 9317 via MatTransposeColoringCreate(). 9318 9319 Collective on MatTransposeColoring 9320 9321 Input Parameter: 9322 . c - coloring context 9323 9324 Level: intermediate 9325 9326 .seealso: MatTransposeColoringCreate() 9327 @*/ 9328 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 9329 { 9330 PetscErrorCode ierr; 9331 MatTransposeColoring matcolor=*c; 9332 9333 PetscFunctionBegin; 9334 if (!matcolor) PetscFunctionReturn(0); 9335 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 9336 9337 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 9338 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 9339 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 9340 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 9341 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 9342 if (matcolor->brows>0) { 9343 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 9344 } 9345 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 9346 PetscFunctionReturn(0); 9347 } 9348 9349 #undef __FUNCT__ 9350 #define __FUNCT__ "MatTransColoringApplySpToDen" 9351 /*@C 9352 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 9353 a MatTransposeColoring context has been created, computes a dense B^T by Apply 9354 MatTransposeColoring to sparse B. 9355 9356 Collective on MatTransposeColoring 9357 9358 Input Parameters: 9359 + B - sparse matrix B 9360 . Btdense - symbolic dense matrix B^T 9361 - coloring - coloring context created with MatTransposeColoringCreate() 9362 9363 Output Parameter: 9364 . Btdense - dense matrix B^T 9365 9366 Options Database Keys: 9367 + -mat_transpose_coloring_view - Activates basic viewing or coloring 9368 . -mat_transpose_coloring_view_draw - Activates drawing of coloring 9369 - -mat_transpose_coloring_view_info - Activates viewing of coloring info 9370 9371 Level: intermediate 9372 9373 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy() 9374 9375 .keywords: coloring 9376 @*/ 9377 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 9378 { 9379 PetscErrorCode ierr; 9380 9381 PetscFunctionBegin; 9382 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 9383 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 9384 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 9385 9386 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 9387 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 9388 PetscFunctionReturn(0); 9389 } 9390 9391 #undef __FUNCT__ 9392 #define __FUNCT__ "MatTransColoringApplyDenToSp" 9393 /*@C 9394 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 9395 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 9396 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 9397 Csp from Cden. 9398 9399 Collective on MatTransposeColoring 9400 9401 Input Parameters: 9402 + coloring - coloring context created with MatTransposeColoringCreate() 9403 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 9404 9405 Output Parameter: 9406 . Csp - sparse matrix 9407 9408 Options Database Keys: 9409 + -mat_multtranspose_coloring_view - Activates basic viewing or coloring 9410 . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring 9411 - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info 9412 9413 Level: intermediate 9414 9415 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 9416 9417 .keywords: coloring 9418 @*/ 9419 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 9420 { 9421 PetscErrorCode ierr; 9422 9423 PetscFunctionBegin; 9424 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 9425 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 9426 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 9427 9428 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 9429 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 9430 PetscFunctionReturn(0); 9431 } 9432 9433 #undef __FUNCT__ 9434 #define __FUNCT__ "MatTransposeColoringCreate" 9435 /*@C 9436 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 9437 9438 Collective on Mat 9439 9440 Input Parameters: 9441 + mat - the matrix product C 9442 - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring() 9443 9444 Output Parameter: 9445 . color - the new coloring context 9446 9447 Level: intermediate 9448 9449 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(), 9450 MatTransColoringApplyDenToSp(), MatTransposeColoringView(), 9451 @*/ 9452 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 9453 { 9454 MatTransposeColoring c; 9455 MPI_Comm comm; 9456 PetscErrorCode ierr; 9457 9458 PetscFunctionBegin; 9459 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 9460 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9461 ierr = PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);CHKERRQ(ierr); 9462 9463 c->ctype = iscoloring->ctype; 9464 if (mat->ops->transposecoloringcreate) { 9465 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 9466 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 9467 9468 *color = c; 9469 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 9470 PetscFunctionReturn(0); 9471 } 9472