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