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