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/isimpl.h> 8 #include <petsc/private/vecimpl.h> 9 10 /* Logging support */ 11 PetscClassId MAT_CLASSID; 12 PetscClassId MAT_COLORING_CLASSID; 13 PetscClassId MAT_FDCOLORING_CLASSID; 14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 15 16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 36 PetscLogEvent MAT_ViennaCLCopyToGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 39 40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 41 42 /*@ 43 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations 44 45 Logically Collective on Mat 46 47 Input Parameters: 48 + x - the matrix 49 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 50 it will create one internally. 51 52 Output Parameter: 53 . x - the matrix 54 55 Example of Usage: 56 .vb 57 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 58 MatSetRandom(x,rctx); 59 PetscRandomDestroy(rctx); 60 .ve 61 62 Level: intermediate 63 64 Concepts: matrix^setting to random 65 Concepts: random^matrix 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 70 { 71 PetscErrorCode ierr; 72 PetscRandom randObj = NULL; 73 74 PetscFunctionBegin; 75 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 77 PetscValidType(x,1); 78 79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 86 rctx = randObj; 87 } 88 89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 92 93 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 94 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 95 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on Mat 103 104 Input Parameters: 105 . mat - the factored matrix 106 107 Output Parameter: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 117 118 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 119 120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 121 @*/ 122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 123 { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 126 *pivot = mat->factorerror_zeropivot_value; 127 *row = mat->factorerror_zeropivot_row; 128 PetscFunctionReturn(0); 129 } 130 131 /*@ 132 MatFactorGetError - gets the error code from a factorization 133 134 Logically Collective on Mat 135 136 Input Parameters: 137 . mat - the factored matrix 138 139 Output Parameter: 140 . err - the error code 141 142 Level: advanced 143 144 Notes: 145 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 146 147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 148 @*/ 149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 150 { 151 PetscFunctionBegin; 152 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 153 *err = mat->factorerrortype; 154 PetscFunctionReturn(0); 155 } 156 157 /*@ 158 MatFactorClearError - clears the error code in a factorization 159 160 Logically Collective on Mat 161 162 Input Parameter: 163 . mat - the factored matrix 164 165 Level: developer 166 167 Notes: 168 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 169 170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 171 @*/ 172 PetscErrorCode MatFactorClearError(Mat mat) 173 { 174 PetscFunctionBegin; 175 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 176 mat->factorerrortype = MAT_FACTOR_NOERROR; 177 mat->factorerror_zeropivot_value = 0.0; 178 mat->factorerror_zeropivot_row = 0; 179 PetscFunctionReturn(0); 180 } 181 182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 183 { 184 PetscErrorCode ierr; 185 Vec r,l; 186 const PetscScalar *al; 187 PetscInt i,nz,gnz,N,n; 188 189 PetscFunctionBegin; 190 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 191 if (!cols) { /* nonzero rows */ 192 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 193 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 194 ierr = VecSet(l,0.0);CHKERRQ(ierr); 195 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 196 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 197 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 198 } else { /* nonzero columns */ 199 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 200 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 201 ierr = VecSet(r,0.0);CHKERRQ(ierr); 202 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 203 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 204 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 205 } 206 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 207 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 208 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 209 if (gnz != N) { 210 PetscInt *nzr; 211 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 212 if (nz) { 213 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 215 } 216 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 217 } else *nonzero = NULL; 218 if (!cols) { /* nonzero rows */ 219 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 220 } else { 221 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 222 } 223 ierr = VecDestroy(&l);CHKERRQ(ierr); 224 ierr = VecDestroy(&r);CHKERRQ(ierr); 225 PetscFunctionReturn(0); 226 } 227 228 /*@ 229 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 230 231 Input Parameter: 232 . A - the matrix 233 234 Output Parameter: 235 . keptrows - the rows that are not completely zero 236 237 Notes: 238 keptrows is set to NULL if all rows are nonzero. 239 240 Level: intermediate 241 242 @*/ 243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 249 PetscValidType(mat,1); 250 PetscValidPointer(keptrows,2); 251 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 252 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 253 if (!mat->ops->findnonzerorows) { 254 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 255 } else { 256 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 257 } 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 MatFindZeroRows - Locate all rows that are completely zero in the matrix 263 264 Input Parameter: 265 . A - the matrix 266 267 Output Parameter: 268 . zerorows - the rows that are completely zero 269 270 Notes: 271 zerorows is set to NULL if no rows are zero. 272 273 Level: intermediate 274 275 @*/ 276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 277 { 278 PetscErrorCode ierr; 279 IS keptrows; 280 PetscInt m, n; 281 282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 283 PetscValidType(mat,1); 284 285 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 286 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 287 In keeping with this convention, we set zerorows to NULL if there are no zero 288 rows. */ 289 if (keptrows == NULL) { 290 *zerorows = NULL; 291 } else { 292 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 293 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 294 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 295 } 296 PetscFunctionReturn(0); 297 } 298 299 /*@ 300 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 301 302 Not Collective 303 304 Input Parameters: 305 . A - the matrix 306 307 Output Parameters: 308 . a - the diagonal part (which is a SEQUENTIAL matrix) 309 310 Notes: 311 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 312 Use caution, as the reference count on the returned matrix is not incremented and it is used as 313 part of the containing MPI Mat's normal operation. 314 315 Level: advanced 316 317 @*/ 318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 319 { 320 PetscErrorCode ierr; 321 322 PetscFunctionBegin; 323 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 324 PetscValidType(A,1); 325 PetscValidPointer(a,3); 326 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 327 if (!A->ops->getdiagonalblock) { 328 PetscMPIInt size; 329 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 330 if (size == 1) { 331 *a = A; 332 PetscFunctionReturn(0); 333 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 334 } 335 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 336 PetscFunctionReturn(0); 337 } 338 339 /*@ 340 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 341 342 Collective on Mat 343 344 Input Parameters: 345 . mat - the matrix 346 347 Output Parameter: 348 . trace - the sum of the diagonal entries 349 350 Level: advanced 351 352 @*/ 353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 354 { 355 PetscErrorCode ierr; 356 Vec diag; 357 358 PetscFunctionBegin; 359 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 360 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 361 ierr = VecSum(diag,trace);CHKERRQ(ierr); 362 ierr = VecDestroy(&diag);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 MatRealPart - Zeros out the imaginary part of the matrix 368 369 Logically Collective on Mat 370 371 Input Parameters: 372 . mat - the matrix 373 374 Level: advanced 375 376 377 .seealso: MatImaginaryPart() 378 @*/ 379 PetscErrorCode MatRealPart(Mat mat) 380 { 381 PetscErrorCode ierr; 382 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 385 PetscValidType(mat,1); 386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 388 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 389 MatCheckPreallocated(mat,1); 390 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 391 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 392 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 393 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 394 } 395 #endif 396 PetscFunctionReturn(0); 397 } 398 399 /*@C 400 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 401 402 Collective on Mat 403 404 Input Parameter: 405 . mat - the matrix 406 407 Output Parameters: 408 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 409 - ghosts - the global indices of the ghost points 410 411 Notes: 412 the nghosts and ghosts are suitable to pass into VecCreateGhost() 413 414 Level: advanced 415 416 @*/ 417 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 418 { 419 PetscErrorCode ierr; 420 421 PetscFunctionBegin; 422 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 423 PetscValidType(mat,1); 424 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 425 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 426 if (!mat->ops->getghosts) { 427 if (nghosts) *nghosts = 0; 428 if (ghosts) *ghosts = 0; 429 } else { 430 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 431 } 432 PetscFunctionReturn(0); 433 } 434 435 436 /*@ 437 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 438 439 Logically Collective on Mat 440 441 Input Parameters: 442 . mat - the matrix 443 444 Level: advanced 445 446 447 .seealso: MatRealPart() 448 @*/ 449 PetscErrorCode MatImaginaryPart(Mat mat) 450 { 451 PetscErrorCode ierr; 452 453 PetscFunctionBegin; 454 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 455 PetscValidType(mat,1); 456 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 457 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 458 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 459 MatCheckPreallocated(mat,1); 460 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 461 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 462 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 463 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 464 } 465 #endif 466 PetscFunctionReturn(0); 467 } 468 469 /*@ 470 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 471 472 Not Collective 473 474 Input Parameter: 475 . mat - the matrix 476 477 Output Parameters: 478 + missing - is any diagonal missing 479 - dd - first diagonal entry that is missing (optional) on this process 480 481 Level: advanced 482 483 484 .seealso: MatRealPart() 485 @*/ 486 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 487 { 488 PetscErrorCode ierr; 489 490 PetscFunctionBegin; 491 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 492 PetscValidType(mat,1); 493 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 494 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 495 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 496 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 497 PetscFunctionReturn(0); 498 } 499 500 /*@C 501 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 502 for each row that you get to ensure that your application does 503 not bleed memory. 504 505 Not Collective 506 507 Input Parameters: 508 + mat - the matrix 509 - row - the row to get 510 511 Output Parameters: 512 + ncols - if not NULL, the number of nonzeros in the row 513 . cols - if not NULL, the column numbers 514 - vals - if not NULL, the values 515 516 Notes: 517 This routine is provided for people who need to have direct access 518 to the structure of a matrix. We hope that we provide enough 519 high-level matrix routines that few users will need it. 520 521 MatGetRow() always returns 0-based column indices, regardless of 522 whether the internal representation is 0-based (default) or 1-based. 523 524 For better efficiency, set cols and/or vals to NULL if you do 525 not wish to extract these quantities. 526 527 The user can only examine the values extracted with MatGetRow(); 528 the values cannot be altered. To change the matrix entries, one 529 must use MatSetValues(). 530 531 You can only have one call to MatGetRow() outstanding for a particular 532 matrix at a time, per processor. MatGetRow() can only obtain rows 533 associated with the given processor, it cannot get rows from the 534 other processors; for that we suggest using MatCreateSubMatrices(), then 535 MatGetRow() on the submatrix. The row index passed to MatGetRow() 536 is in the global number of rows. 537 538 Fortran Notes: 539 The calling sequence from Fortran is 540 .vb 541 MatGetRow(matrix,row,ncols,cols,values,ierr) 542 Mat matrix (input) 543 integer row (input) 544 integer ncols (output) 545 integer cols(maxcols) (output) 546 double precision (or double complex) values(maxcols) output 547 .ve 548 where maxcols >= maximum nonzeros in any row of the matrix. 549 550 551 Caution: 552 Do not try to change the contents of the output arrays (cols and vals). 553 In some cases, this may corrupt the matrix. 554 555 Level: advanced 556 557 Concepts: matrices^row access 558 559 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 560 @*/ 561 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 562 { 563 PetscErrorCode ierr; 564 PetscInt incols; 565 566 PetscFunctionBegin; 567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 568 PetscValidType(mat,1); 569 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 570 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 571 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 572 MatCheckPreallocated(mat,1); 573 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 574 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 575 if (ncols) *ncols = incols; 576 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 577 PetscFunctionReturn(0); 578 } 579 580 /*@ 581 MatConjugate - replaces the matrix values with their complex conjugates 582 583 Logically Collective on Mat 584 585 Input Parameters: 586 . mat - the matrix 587 588 Level: advanced 589 590 .seealso: VecConjugate() 591 @*/ 592 PetscErrorCode MatConjugate(Mat mat) 593 { 594 #if defined(PETSC_USE_COMPLEX) 595 PetscErrorCode ierr; 596 597 PetscFunctionBegin; 598 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 599 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 600 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"); 601 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 602 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 603 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 604 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 605 } 606 #endif 607 PetscFunctionReturn(0); 608 #else 609 return 0; 610 #endif 611 } 612 613 /*@C 614 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 615 616 Not Collective 617 618 Input Parameters: 619 + mat - the matrix 620 . row - the row to get 621 . ncols, cols - the number of nonzeros and their columns 622 - vals - if nonzero the column values 623 624 Notes: 625 This routine should be called after you have finished examining the entries. 626 627 This routine zeros out ncols, cols, and vals. This is to prevent accidental 628 us of the array after it has been restored. If you pass NULL, it will 629 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 630 631 Fortran Notes: 632 The calling sequence from Fortran is 633 .vb 634 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 635 Mat matrix (input) 636 integer row (input) 637 integer ncols (output) 638 integer cols(maxcols) (output) 639 double precision (or double complex) values(maxcols) output 640 .ve 641 Where maxcols >= maximum nonzeros in any row of the matrix. 642 643 In Fortran MatRestoreRow() MUST be called after MatGetRow() 644 before another call to MatGetRow() can be made. 645 646 Level: advanced 647 648 .seealso: MatGetRow() 649 @*/ 650 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 651 { 652 PetscErrorCode ierr; 653 654 PetscFunctionBegin; 655 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 656 if (ncols) PetscValidIntPointer(ncols,3); 657 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 658 if (!mat->ops->restorerow) PetscFunctionReturn(0); 659 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 660 if (ncols) *ncols = 0; 661 if (cols) *cols = NULL; 662 if (vals) *vals = NULL; 663 PetscFunctionReturn(0); 664 } 665 666 /*@ 667 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 668 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 669 670 Not Collective 671 672 Input Parameters: 673 + mat - the matrix 674 675 Notes: 676 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. 677 678 Level: advanced 679 680 Concepts: matrices^row access 681 682 .seealso: MatRestoreRowRowUpperTriangular() 683 @*/ 684 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 685 { 686 PetscErrorCode ierr; 687 688 PetscFunctionBegin; 689 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 690 PetscValidType(mat,1); 691 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 692 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 693 if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 694 MatCheckPreallocated(mat,1); 695 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 696 PetscFunctionReturn(0); 697 } 698 699 /*@ 700 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 701 702 Not Collective 703 704 Input Parameters: 705 + mat - the matrix 706 707 Notes: 708 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 709 710 711 Level: advanced 712 713 .seealso: MatGetRowUpperTriangular() 714 @*/ 715 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 716 { 717 PetscErrorCode ierr; 718 719 PetscFunctionBegin; 720 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 721 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 722 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 723 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 724 PetscFunctionReturn(0); 725 } 726 727 /*@C 728 MatSetOptionsPrefix - Sets the prefix used for searching for all 729 Mat options in the database. 730 731 Logically Collective on Mat 732 733 Input Parameter: 734 + A - the Mat context 735 - prefix - the prefix to prepend to all option names 736 737 Notes: 738 A hyphen (-) must NOT be given at the beginning of the prefix name. 739 The first character of all runtime options is AUTOMATICALLY the hyphen. 740 741 Level: advanced 742 743 .keywords: Mat, set, options, prefix, database 744 745 .seealso: MatSetFromOptions() 746 @*/ 747 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 748 { 749 PetscErrorCode ierr; 750 751 PetscFunctionBegin; 752 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 753 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 754 PetscFunctionReturn(0); 755 } 756 757 /*@C 758 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 759 Mat options in the database. 760 761 Logically Collective on Mat 762 763 Input Parameters: 764 + A - the Mat context 765 - prefix - the prefix to prepend to all option names 766 767 Notes: 768 A hyphen (-) must NOT be given at the beginning of the prefix name. 769 The first character of all runtime options is AUTOMATICALLY the hyphen. 770 771 Level: advanced 772 773 .keywords: Mat, append, options, prefix, database 774 775 .seealso: MatGetOptionsPrefix() 776 @*/ 777 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 778 { 779 PetscErrorCode ierr; 780 781 PetscFunctionBegin; 782 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 783 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 784 PetscFunctionReturn(0); 785 } 786 787 /*@C 788 MatGetOptionsPrefix - Sets the prefix used for searching for all 789 Mat options in the database. 790 791 Not Collective 792 793 Input Parameter: 794 . A - the Mat context 795 796 Output Parameter: 797 . prefix - pointer to the prefix string used 798 799 Notes: 800 On the fortran side, the user should pass in a string 'prefix' of 801 sufficient length to hold the prefix. 802 803 Level: advanced 804 805 .keywords: Mat, get, options, prefix, database 806 807 .seealso: MatAppendOptionsPrefix() 808 @*/ 809 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 810 { 811 PetscErrorCode ierr; 812 813 PetscFunctionBegin; 814 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 815 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 816 PetscFunctionReturn(0); 817 } 818 819 /*@ 820 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 821 822 Collective on Mat 823 824 Input Parameters: 825 . A - the Mat context 826 827 Notes: 828 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 829 Currently support MPIAIJ and SEQAIJ. 830 831 Level: beginner 832 833 .keywords: Mat, ResetPreallocation 834 835 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 836 @*/ 837 PetscErrorCode MatResetPreallocation(Mat A) 838 { 839 PetscErrorCode ierr; 840 841 PetscFunctionBegin; 842 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 843 PetscValidType(A,1); 844 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 845 PetscFunctionReturn(0); 846 } 847 848 849 /*@ 850 MatSetUp - Sets up the internal matrix data structures for the later use. 851 852 Collective on Mat 853 854 Input Parameters: 855 . A - the Mat context 856 857 Notes: 858 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 859 860 If a suitable preallocation routine is used, this function does not need to be called. 861 862 See the Performance chapter of the PETSc users manual for how to preallocate matrices 863 864 Level: beginner 865 866 .keywords: Mat, setup 867 868 .seealso: MatCreate(), MatDestroy() 869 @*/ 870 PetscErrorCode MatSetUp(Mat A) 871 { 872 PetscMPIInt size; 873 PetscErrorCode ierr; 874 875 PetscFunctionBegin; 876 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 877 if (!((PetscObject)A)->type_name) { 878 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 879 if (size == 1) { 880 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 881 } else { 882 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 883 } 884 } 885 if (!A->preallocated && A->ops->setup) { 886 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 887 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 888 } 889 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 890 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 891 A->preallocated = PETSC_TRUE; 892 PetscFunctionReturn(0); 893 } 894 895 #if defined(PETSC_HAVE_SAWS) 896 #include <petscviewersaws.h> 897 #endif 898 /*@C 899 MatView - Visualizes a matrix object. 900 901 Collective on Mat 902 903 Input Parameters: 904 + mat - the matrix 905 - viewer - visualization context 906 907 Notes: 908 The available visualization contexts include 909 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 910 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 911 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 912 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 913 914 The user can open alternative visualization contexts with 915 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 916 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 917 specified file; corresponding input uses MatLoad() 918 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 919 an X window display 920 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 921 Currently only the sequential dense and AIJ 922 matrix types support the Socket viewer. 923 924 The user can call PetscViewerPushFormat() to specify the output 925 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 926 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 927 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 928 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 929 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 930 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 931 format common among all matrix types 932 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 933 format (which is in many cases the same as the default) 934 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 935 size and structure (not the matrix entries) 936 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 937 the matrix structure 938 939 Options Database Keys: 940 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 941 . -mat_view ::ascii_info_detail - Prints more detailed info 942 . -mat_view - Prints matrix in ASCII format 943 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 944 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 945 . -display <name> - Sets display name (default is host) 946 . -draw_pause <sec> - Sets number of seconds to pause after display 947 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 948 . -viewer_socket_machine <machine> - 949 . -viewer_socket_port <port> - 950 . -mat_view binary - save matrix to file in binary format 951 - -viewer_binary_filename <name> - 952 Level: beginner 953 954 Notes: 955 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 956 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 957 958 See the manual page for MatLoad() for the exact format of the binary file when the binary 959 viewer is used. 960 961 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 962 viewer is used. 963 964 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 965 and then use the following mouse functions. 966 + left mouse: zoom in 967 . middle mouse: zoom out 968 - right mouse: continue with the simulation 969 970 Concepts: matrices^viewing 971 Concepts: matrices^plotting 972 Concepts: matrices^printing 973 974 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 975 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 976 @*/ 977 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 978 { 979 PetscErrorCode ierr; 980 PetscInt rows,cols,rbs,cbs; 981 PetscBool iascii,ibinary; 982 PetscViewerFormat format; 983 PetscMPIInt size; 984 #if defined(PETSC_HAVE_SAWS) 985 PetscBool issaws; 986 #endif 987 988 PetscFunctionBegin; 989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 990 PetscValidType(mat,1); 991 if (!viewer) { 992 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 993 } 994 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 995 PetscCheckSameComm(mat,1,viewer,2); 996 MatCheckPreallocated(mat,1); 997 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 998 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 999 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1000 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 1001 if (ibinary) { 1002 PetscBool mpiio; 1003 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 1004 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1005 } 1006 1007 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1008 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1009 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1010 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1011 } 1012 1013 #if defined(PETSC_HAVE_SAWS) 1014 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1015 #endif 1016 if (iascii) { 1017 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1018 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1019 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1020 MatNullSpace nullsp,transnullsp; 1021 1022 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1023 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1024 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1025 if (rbs != 1 || cbs != 1) { 1026 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1027 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1028 } else { 1029 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1030 } 1031 if (mat->factortype) { 1032 MatSolverType solver; 1033 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1034 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1035 } 1036 if (mat->ops->getinfo) { 1037 MatInfo info; 1038 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1039 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1040 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1041 } 1042 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1043 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1044 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1045 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1046 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1047 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1048 } 1049 #if defined(PETSC_HAVE_SAWS) 1050 } else if (issaws) { 1051 PetscMPIInt rank; 1052 1053 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1054 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1055 if (!((PetscObject)mat)->amsmem && !rank) { 1056 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1057 } 1058 #endif 1059 } 1060 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1061 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1062 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1063 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1064 } else if (mat->ops->view) { 1065 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1066 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1067 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1068 } 1069 if (iascii) { 1070 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1071 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1072 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1073 } 1074 } 1075 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1076 PetscFunctionReturn(0); 1077 } 1078 1079 #if defined(PETSC_USE_DEBUG) 1080 #include <../src/sys/totalview/tv_data_display.h> 1081 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1082 { 1083 TV_add_row("Local rows", "int", &mat->rmap->n); 1084 TV_add_row("Local columns", "int", &mat->cmap->n); 1085 TV_add_row("Global rows", "int", &mat->rmap->N); 1086 TV_add_row("Global columns", "int", &mat->cmap->N); 1087 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1088 return TV_format_OK; 1089 } 1090 #endif 1091 1092 /*@C 1093 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1094 with MatView(). The matrix format is determined from the options database. 1095 Generates a parallel MPI matrix if the communicator has more than one 1096 processor. The default matrix type is AIJ. 1097 1098 Collective on PetscViewer 1099 1100 Input Parameters: 1101 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1102 or some related function before a call to MatLoad() 1103 - viewer - binary/HDF5 file viewer 1104 1105 Options Database Keys: 1106 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1107 block size 1108 . -matload_block_size <bs> 1109 1110 Level: beginner 1111 1112 Notes: 1113 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1114 Mat before calling this routine if you wish to set it from the options database. 1115 1116 MatLoad() automatically loads into the options database any options 1117 given in the file filename.info where filename is the name of the file 1118 that was passed to the PetscViewerBinaryOpen(). The options in the info 1119 file will be ignored if you use the -viewer_binary_skip_info option. 1120 1121 If the type or size of newmat is not set before a call to MatLoad, PETSc 1122 sets the default matrix type AIJ and sets the local and global sizes. 1123 If type and/or size is already set, then the same are used. 1124 1125 In parallel, each processor can load a subset of rows (or the 1126 entire matrix). This routine is especially useful when a large 1127 matrix is stored on disk and only part of it is desired on each 1128 processor. For example, a parallel solver may access only some of 1129 the rows from each processor. The algorithm used here reads 1130 relatively small blocks of data rather than reading the entire 1131 matrix and then subsetting it. 1132 1133 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1134 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1135 or the sequence like 1136 $ PetscViewer v; 1137 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1138 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1139 $ PetscViewerSetFromOptions(v); 1140 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1141 $ PetscViewerFileSetName(v,"datafile"); 1142 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1143 $ -viewer_type {binary,hdf5} 1144 1145 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1146 and src/mat/examples/tutorials/ex10.c with the second approach. 1147 1148 Notes about the PETSc binary format: 1149 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1150 is read onto rank 0 and then shipped to its destination rank, one after another. 1151 Multiple objects, both matrices and vectors, can be stored within the same file. 1152 Their PetscObject name is ignored; they are loaded in the order of their storage. 1153 1154 Most users should not need to know the details of the binary storage 1155 format, since MatLoad() and MatView() completely hide these details. 1156 But for anyone who's interested, the standard binary matrix storage 1157 format is 1158 1159 $ int MAT_FILE_CLASSID 1160 $ int number of rows 1161 $ int number of columns 1162 $ int total number of nonzeros 1163 $ int *number nonzeros in each row 1164 $ int *column indices of all nonzeros (starting index is zero) 1165 $ PetscScalar *values of all nonzeros 1166 1167 PETSc automatically does the byte swapping for 1168 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1169 linux, Windows and the paragon; thus if you write your own binary 1170 read/write routines you have to swap the bytes; see PetscBinaryRead() 1171 and PetscBinaryWrite() to see how this may be done. 1172 1173 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1174 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1175 Each processor's chunk is loaded independently by its owning rank. 1176 Multiple objects, both matrices and vectors, can be stored within the same file. 1177 They are looked up by their PetscObject name. 1178 1179 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1180 by default the same structure and naming of the AIJ arrays and column count 1181 (see PetscViewerHDF5SetAIJNames()) 1182 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1183 $ save example.mat A b -v7.3 1184 can be directly read by this routine (see Reference 1 for details). 1185 Note that depending on your MATLAB version, this format might be a default, 1186 otherwise you can set it as default in Preferences. 1187 1188 Unless -nocompression flag is used to save the file in MATLAB, 1189 PETSc must be configured with ZLIB package. 1190 1191 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1192 1193 Current HDF5 (MAT-File) limitations: 1194 This reader currently supports only real MATSEQAIJ and MATMPIAIJ matrices. 1195 1196 Corresponding MatView() is not yet implemented. 1197 1198 The loaded matrix is actually a transpose of the original one in MATLAB, 1199 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1200 With this format, matrix is automatically transposed by PETSc, 1201 unless the matrix is marked as SPD or symmetric 1202 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1203 1204 References: 1205 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1206 1207 .keywords: matrix, load, binary, input, HDF5 1208 1209 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), PetscViewerHDF5SetAIJNames(), MatView(), VecLoad() 1210 1211 @*/ 1212 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1213 { 1214 PetscErrorCode ierr; 1215 PetscBool flg; 1216 1217 PetscFunctionBegin; 1218 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1219 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1220 1221 if (!((PetscObject)newmat)->type_name) { 1222 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1223 } 1224 1225 flg = PETSC_FALSE; 1226 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1227 if (flg) { 1228 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1229 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1230 } 1231 flg = PETSC_FALSE; 1232 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1233 if (flg) { 1234 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1235 } 1236 1237 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1238 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1239 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1240 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1241 PetscFunctionReturn(0); 1242 } 1243 1244 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1245 { 1246 PetscErrorCode ierr; 1247 Mat_Redundant *redund = *redundant; 1248 PetscInt i; 1249 1250 PetscFunctionBegin; 1251 if (redund){ 1252 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1253 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1254 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1255 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1256 } else { 1257 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1258 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1259 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1260 for (i=0; i<redund->nrecvs; i++) { 1261 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1262 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1263 } 1264 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1265 } 1266 1267 if (redund->subcomm) { 1268 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1269 } 1270 ierr = PetscFree(redund);CHKERRQ(ierr); 1271 } 1272 PetscFunctionReturn(0); 1273 } 1274 1275 /*@ 1276 MatDestroy - Frees space taken by a matrix. 1277 1278 Collective on Mat 1279 1280 Input Parameter: 1281 . A - the matrix 1282 1283 Level: beginner 1284 1285 @*/ 1286 PetscErrorCode MatDestroy(Mat *A) 1287 { 1288 PetscErrorCode ierr; 1289 1290 PetscFunctionBegin; 1291 if (!*A) PetscFunctionReturn(0); 1292 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1293 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1294 1295 /* if memory was published with SAWs then destroy it */ 1296 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1297 if ((*A)->ops->destroy) { 1298 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1299 } 1300 1301 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1302 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1303 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1304 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1305 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1306 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1307 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1308 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1309 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1310 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1311 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1312 PetscFunctionReturn(0); 1313 } 1314 1315 /*@C 1316 MatSetValues - Inserts or adds a block of values into a matrix. 1317 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1318 MUST be called after all calls to MatSetValues() have been completed. 1319 1320 Not Collective 1321 1322 Input Parameters: 1323 + mat - the matrix 1324 . v - a logically two-dimensional array of values 1325 . m, idxm - the number of rows and their global indices 1326 . n, idxn - the number of columns and their global indices 1327 - addv - either ADD_VALUES or INSERT_VALUES, where 1328 ADD_VALUES adds values to any existing entries, and 1329 INSERT_VALUES replaces existing entries with new values 1330 1331 Notes: 1332 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1333 MatSetUp() before using this routine 1334 1335 By default the values, v, are row-oriented. See MatSetOption() for other options. 1336 1337 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1338 options cannot be mixed without intervening calls to the assembly 1339 routines. 1340 1341 MatSetValues() uses 0-based row and column numbers in Fortran 1342 as well as in C. 1343 1344 Negative indices may be passed in idxm and idxn, these rows and columns are 1345 simply ignored. This allows easily inserting element stiffness matrices 1346 with homogeneous Dirchlet boundary conditions that you don't want represented 1347 in the matrix. 1348 1349 Efficiency Alert: 1350 The routine MatSetValuesBlocked() may offer much better efficiency 1351 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1352 1353 Level: beginner 1354 1355 Developer Notes: 1356 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1357 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1358 1359 Concepts: matrices^putting entries in 1360 1361 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1362 InsertMode, INSERT_VALUES, ADD_VALUES 1363 @*/ 1364 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1365 { 1366 PetscErrorCode ierr; 1367 #if defined(PETSC_USE_DEBUG) 1368 PetscInt i,j; 1369 #endif 1370 1371 PetscFunctionBeginHot; 1372 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1373 PetscValidType(mat,1); 1374 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1375 PetscValidIntPointer(idxm,3); 1376 PetscValidIntPointer(idxn,5); 1377 PetscValidScalarPointer(v,6); 1378 MatCheckPreallocated(mat,1); 1379 if (mat->insertmode == NOT_SET_VALUES) { 1380 mat->insertmode = addv; 1381 } 1382 #if defined(PETSC_USE_DEBUG) 1383 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1384 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1385 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1386 1387 for (i=0; i<m; i++) { 1388 for (j=0; j<n; j++) { 1389 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1390 #if defined(PETSC_USE_COMPLEX) 1391 SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1392 #else 1393 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1394 #endif 1395 } 1396 } 1397 #endif 1398 1399 if (mat->assembled) { 1400 mat->was_assembled = PETSC_TRUE; 1401 mat->assembled = PETSC_FALSE; 1402 } 1403 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1404 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1405 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1406 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1407 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1408 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1409 } 1410 #endif 1411 PetscFunctionReturn(0); 1412 } 1413 1414 1415 /*@ 1416 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1417 values into a matrix 1418 1419 Not Collective 1420 1421 Input Parameters: 1422 + mat - the matrix 1423 . row - the (block) row to set 1424 - v - a logically two-dimensional array of values 1425 1426 Notes: 1427 By the values, v, are column-oriented (for the block version) and sorted 1428 1429 All the nonzeros in the row must be provided 1430 1431 The matrix must have previously had its column indices set 1432 1433 The row must belong to this process 1434 1435 Level: intermediate 1436 1437 Concepts: matrices^putting entries in 1438 1439 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1440 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1441 @*/ 1442 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1443 { 1444 PetscErrorCode ierr; 1445 PetscInt globalrow; 1446 1447 PetscFunctionBegin; 1448 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1449 PetscValidType(mat,1); 1450 PetscValidScalarPointer(v,2); 1451 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1452 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1453 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1454 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1455 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1456 } 1457 #endif 1458 PetscFunctionReturn(0); 1459 } 1460 1461 /*@ 1462 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1463 values into a matrix 1464 1465 Not Collective 1466 1467 Input Parameters: 1468 + mat - the matrix 1469 . row - the (block) row to set 1470 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values 1471 1472 Notes: 1473 The values, v, are column-oriented for the block version. 1474 1475 All the nonzeros in the row must be provided 1476 1477 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1478 1479 The row must belong to this process 1480 1481 Level: advanced 1482 1483 Concepts: matrices^putting entries in 1484 1485 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1486 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1487 @*/ 1488 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1489 { 1490 PetscErrorCode ierr; 1491 1492 PetscFunctionBeginHot; 1493 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1494 PetscValidType(mat,1); 1495 MatCheckPreallocated(mat,1); 1496 PetscValidScalarPointer(v,2); 1497 #if defined(PETSC_USE_DEBUG) 1498 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1499 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1500 #endif 1501 mat->insertmode = INSERT_VALUES; 1502 1503 if (mat->assembled) { 1504 mat->was_assembled = PETSC_TRUE; 1505 mat->assembled = PETSC_FALSE; 1506 } 1507 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1508 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1509 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1510 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1511 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1512 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1513 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1514 } 1515 #endif 1516 PetscFunctionReturn(0); 1517 } 1518 1519 /*@ 1520 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1521 Using structured grid indexing 1522 1523 Not Collective 1524 1525 Input Parameters: 1526 + mat - the matrix 1527 . m - number of rows being entered 1528 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1529 . n - number of columns being entered 1530 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1531 . v - a logically two-dimensional array of values 1532 - addv - either ADD_VALUES or INSERT_VALUES, where 1533 ADD_VALUES adds values to any existing entries, and 1534 INSERT_VALUES replaces existing entries with new values 1535 1536 Notes: 1537 By default the values, v, are row-oriented. See MatSetOption() for other options. 1538 1539 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1540 options cannot be mixed without intervening calls to the assembly 1541 routines. 1542 1543 The grid coordinates are across the entire grid, not just the local portion 1544 1545 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1546 as well as in C. 1547 1548 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1549 1550 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1551 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1552 1553 The columns and rows in the stencil passed in MUST be contained within the 1554 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1555 if you create a DMDA with an overlap of one grid level and on a particular process its first 1556 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1557 first i index you can use in your column and row indices in MatSetStencil() is 5. 1558 1559 In Fortran idxm and idxn should be declared as 1560 $ MatStencil idxm(4,m),idxn(4,n) 1561 and the values inserted using 1562 $ idxm(MatStencil_i,1) = i 1563 $ idxm(MatStencil_j,1) = j 1564 $ idxm(MatStencil_k,1) = k 1565 $ idxm(MatStencil_c,1) = c 1566 etc 1567 1568 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1569 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1570 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1571 DM_BOUNDARY_PERIODIC boundary type. 1572 1573 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 1574 a single value per point) you can skip filling those indices. 1575 1576 Inspired by the structured grid interface to the HYPRE package 1577 (http://www.llnl.gov/CASC/hypre) 1578 1579 Efficiency Alert: 1580 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1581 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1582 1583 Level: beginner 1584 1585 Concepts: matrices^putting entries in 1586 1587 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1588 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1589 @*/ 1590 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1591 { 1592 PetscErrorCode ierr; 1593 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1594 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1595 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1596 1597 PetscFunctionBegin; 1598 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1599 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1600 PetscValidType(mat,1); 1601 PetscValidIntPointer(idxm,3); 1602 PetscValidIntPointer(idxn,5); 1603 PetscValidScalarPointer(v,6); 1604 1605 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1606 jdxm = buf; jdxn = buf+m; 1607 } else { 1608 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1609 jdxm = bufm; jdxn = bufn; 1610 } 1611 for (i=0; i<m; i++) { 1612 for (j=0; j<3-sdim; j++) dxm++; 1613 tmp = *dxm++ - starts[0]; 1614 for (j=0; j<dim-1; j++) { 1615 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1616 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1617 } 1618 if (mat->stencil.noc) dxm++; 1619 jdxm[i] = tmp; 1620 } 1621 for (i=0; i<n; i++) { 1622 for (j=0; j<3-sdim; j++) dxn++; 1623 tmp = *dxn++ - starts[0]; 1624 for (j=0; j<dim-1; j++) { 1625 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1626 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1627 } 1628 if (mat->stencil.noc) dxn++; 1629 jdxn[i] = tmp; 1630 } 1631 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1632 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1633 PetscFunctionReturn(0); 1634 } 1635 1636 /*@ 1637 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1638 Using structured grid indexing 1639 1640 Not Collective 1641 1642 Input Parameters: 1643 + mat - the matrix 1644 . m - number of rows being entered 1645 . idxm - grid coordinates for matrix rows being entered 1646 . n - number of columns being entered 1647 . idxn - grid coordinates for matrix columns being entered 1648 . v - a logically two-dimensional array of values 1649 - addv - either ADD_VALUES or INSERT_VALUES, where 1650 ADD_VALUES adds values to any existing entries, and 1651 INSERT_VALUES replaces existing entries with new values 1652 1653 Notes: 1654 By default the values, v, are row-oriented and unsorted. 1655 See MatSetOption() for other options. 1656 1657 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1658 options cannot be mixed without intervening calls to the assembly 1659 routines. 1660 1661 The grid coordinates are across the entire grid, not just the local portion 1662 1663 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1664 as well as in C. 1665 1666 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1667 1668 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1669 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1670 1671 The columns and rows in the stencil passed in MUST be contained within the 1672 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1673 if you create a DMDA with an overlap of one grid level and on a particular process its first 1674 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1675 first i index you can use in your column and row indices in MatSetStencil() is 5. 1676 1677 In Fortran idxm and idxn should be declared as 1678 $ MatStencil idxm(4,m),idxn(4,n) 1679 and the values inserted using 1680 $ idxm(MatStencil_i,1) = i 1681 $ idxm(MatStencil_j,1) = j 1682 $ idxm(MatStencil_k,1) = k 1683 etc 1684 1685 Negative indices may be passed in idxm and idxn, these rows and columns are 1686 simply ignored. This allows easily inserting element stiffness matrices 1687 with homogeneous Dirchlet boundary conditions that you don't want represented 1688 in the matrix. 1689 1690 Inspired by the structured grid interface to the HYPRE package 1691 (http://www.llnl.gov/CASC/hypre) 1692 1693 Level: beginner 1694 1695 Concepts: matrices^putting entries in 1696 1697 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1698 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1699 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1700 @*/ 1701 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1702 { 1703 PetscErrorCode ierr; 1704 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1705 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1706 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1707 1708 PetscFunctionBegin; 1709 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1710 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1711 PetscValidType(mat,1); 1712 PetscValidIntPointer(idxm,3); 1713 PetscValidIntPointer(idxn,5); 1714 PetscValidScalarPointer(v,6); 1715 1716 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1717 jdxm = buf; jdxn = buf+m; 1718 } else { 1719 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1720 jdxm = bufm; jdxn = bufn; 1721 } 1722 for (i=0; i<m; i++) { 1723 for (j=0; j<3-sdim; j++) dxm++; 1724 tmp = *dxm++ - starts[0]; 1725 for (j=0; j<sdim-1; j++) { 1726 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1727 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1728 } 1729 dxm++; 1730 jdxm[i] = tmp; 1731 } 1732 for (i=0; i<n; i++) { 1733 for (j=0; j<3-sdim; j++) dxn++; 1734 tmp = *dxn++ - starts[0]; 1735 for (j=0; j<sdim-1; j++) { 1736 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1737 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1738 } 1739 dxn++; 1740 jdxn[i] = tmp; 1741 } 1742 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1743 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1744 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1745 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1746 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1747 } 1748 #endif 1749 PetscFunctionReturn(0); 1750 } 1751 1752 /*@ 1753 MatSetStencil - Sets the grid information for setting values into a matrix via 1754 MatSetValuesStencil() 1755 1756 Not Collective 1757 1758 Input Parameters: 1759 + mat - the matrix 1760 . dim - dimension of the grid 1, 2, or 3 1761 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1762 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1763 - dof - number of degrees of freedom per node 1764 1765 1766 Inspired by the structured grid interface to the HYPRE package 1767 (www.llnl.gov/CASC/hyper) 1768 1769 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1770 user. 1771 1772 Level: beginner 1773 1774 Concepts: matrices^putting entries in 1775 1776 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1777 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1778 @*/ 1779 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1780 { 1781 PetscInt i; 1782 1783 PetscFunctionBegin; 1784 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1785 PetscValidIntPointer(dims,3); 1786 PetscValidIntPointer(starts,4); 1787 1788 mat->stencil.dim = dim + (dof > 1); 1789 for (i=0; i<dim; i++) { 1790 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1791 mat->stencil.starts[i] = starts[dim-i-1]; 1792 } 1793 mat->stencil.dims[dim] = dof; 1794 mat->stencil.starts[dim] = 0; 1795 mat->stencil.noc = (PetscBool)(dof == 1); 1796 PetscFunctionReturn(0); 1797 } 1798 1799 /*@C 1800 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1801 1802 Not Collective 1803 1804 Input Parameters: 1805 + mat - the matrix 1806 . v - a logically two-dimensional array of values 1807 . m, idxm - the number of block rows and their global block indices 1808 . n, idxn - the number of block columns and their global block indices 1809 - addv - either ADD_VALUES or INSERT_VALUES, where 1810 ADD_VALUES adds values to any existing entries, and 1811 INSERT_VALUES replaces existing entries with new values 1812 1813 Notes: 1814 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1815 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1816 1817 The m and n count the NUMBER of blocks in the row direction and column direction, 1818 NOT the total number of rows/columns; for example, if the block size is 2 and 1819 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1820 The values in idxm would be 1 2; that is the first index for each block divided by 1821 the block size. 1822 1823 Note that you must call MatSetBlockSize() when constructing this matrix (before 1824 preallocating it). 1825 1826 By default the values, v, are row-oriented, so the layout of 1827 v is the same as for MatSetValues(). See MatSetOption() for other options. 1828 1829 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1830 options cannot be mixed without intervening calls to the assembly 1831 routines. 1832 1833 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1834 as well as in C. 1835 1836 Negative indices may be passed in idxm and idxn, these rows and columns are 1837 simply ignored. This allows easily inserting element stiffness matrices 1838 with homogeneous Dirchlet boundary conditions that you don't want represented 1839 in the matrix. 1840 1841 Each time an entry is set within a sparse matrix via MatSetValues(), 1842 internal searching must be done to determine where to place the 1843 data in the matrix storage space. By instead inserting blocks of 1844 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1845 reduced. 1846 1847 Example: 1848 $ Suppose m=n=2 and block size(bs) = 2 The array is 1849 $ 1850 $ 1 2 | 3 4 1851 $ 5 6 | 7 8 1852 $ - - - | - - - 1853 $ 9 10 | 11 12 1854 $ 13 14 | 15 16 1855 $ 1856 $ v[] should be passed in like 1857 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1858 $ 1859 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1860 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1861 1862 Level: intermediate 1863 1864 Concepts: matrices^putting entries in blocked 1865 1866 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1867 @*/ 1868 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1869 { 1870 PetscErrorCode ierr; 1871 1872 PetscFunctionBeginHot; 1873 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1874 PetscValidType(mat,1); 1875 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1876 PetscValidIntPointer(idxm,3); 1877 PetscValidIntPointer(idxn,5); 1878 PetscValidScalarPointer(v,6); 1879 MatCheckPreallocated(mat,1); 1880 if (mat->insertmode == NOT_SET_VALUES) { 1881 mat->insertmode = addv; 1882 } 1883 #if defined(PETSC_USE_DEBUG) 1884 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1885 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1886 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1887 #endif 1888 1889 if (mat->assembled) { 1890 mat->was_assembled = PETSC_TRUE; 1891 mat->assembled = PETSC_FALSE; 1892 } 1893 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1894 if (mat->ops->setvaluesblocked) { 1895 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1896 } else { 1897 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1898 PetscInt i,j,bs,cbs; 1899 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1900 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1901 iidxm = buf; iidxn = buf + m*bs; 1902 } else { 1903 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1904 iidxm = bufr; iidxn = bufc; 1905 } 1906 for (i=0; i<m; i++) { 1907 for (j=0; j<bs; j++) { 1908 iidxm[i*bs+j] = bs*idxm[i] + j; 1909 } 1910 } 1911 for (i=0; i<n; i++) { 1912 for (j=0; j<cbs; j++) { 1913 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1914 } 1915 } 1916 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1917 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1918 } 1919 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1920 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1921 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1922 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1923 } 1924 #endif 1925 PetscFunctionReturn(0); 1926 } 1927 1928 /*@ 1929 MatGetValues - Gets a block of values from a matrix. 1930 1931 Not Collective; currently only returns a local block 1932 1933 Input Parameters: 1934 + mat - the matrix 1935 . v - a logically two-dimensional array for storing the values 1936 . m, idxm - the number of rows and their global indices 1937 - n, idxn - the number of columns and their global indices 1938 1939 Notes: 1940 The user must allocate space (m*n PetscScalars) for the values, v. 1941 The values, v, are then returned in a row-oriented format, 1942 analogous to that used by default in MatSetValues(). 1943 1944 MatGetValues() uses 0-based row and column numbers in 1945 Fortran as well as in C. 1946 1947 MatGetValues() requires that the matrix has been assembled 1948 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1949 MatSetValues() and MatGetValues() CANNOT be made in succession 1950 without intermediate matrix assembly. 1951 1952 Negative row or column indices will be ignored and those locations in v[] will be 1953 left unchanged. 1954 1955 Level: advanced 1956 1957 Concepts: matrices^accessing values 1958 1959 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1960 @*/ 1961 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1962 { 1963 PetscErrorCode ierr; 1964 1965 PetscFunctionBegin; 1966 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1967 PetscValidType(mat,1); 1968 if (!m || !n) PetscFunctionReturn(0); 1969 PetscValidIntPointer(idxm,3); 1970 PetscValidIntPointer(idxn,5); 1971 PetscValidScalarPointer(v,6); 1972 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1973 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1974 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1975 MatCheckPreallocated(mat,1); 1976 1977 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1978 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1979 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1980 PetscFunctionReturn(0); 1981 } 1982 1983 /*@ 1984 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1985 the same size. Currently, this can only be called once and creates the given matrix. 1986 1987 Not Collective 1988 1989 Input Parameters: 1990 + mat - the matrix 1991 . nb - the number of blocks 1992 . bs - the number of rows (and columns) in each block 1993 . rows - a concatenation of the rows for each block 1994 - v - a concatenation of logically two-dimensional arrays of values 1995 1996 Notes: 1997 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1998 1999 Level: advanced 2000 2001 Concepts: matrices^putting entries in 2002 2003 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 2004 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 2005 @*/ 2006 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2007 { 2008 PetscErrorCode ierr; 2009 2010 PetscFunctionBegin; 2011 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2012 PetscValidType(mat,1); 2013 PetscValidScalarPointer(rows,4); 2014 PetscValidScalarPointer(v,5); 2015 #if defined(PETSC_USE_DEBUG) 2016 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2017 #endif 2018 2019 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2020 if (mat->ops->setvaluesbatch) { 2021 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 2022 } else { 2023 PetscInt b; 2024 for (b = 0; b < nb; ++b) { 2025 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 2026 } 2027 } 2028 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2029 PetscFunctionReturn(0); 2030 } 2031 2032 /*@ 2033 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2034 the routine MatSetValuesLocal() to allow users to insert matrix entries 2035 using a local (per-processor) numbering. 2036 2037 Not Collective 2038 2039 Input Parameters: 2040 + x - the matrix 2041 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2042 - cmapping - column mapping 2043 2044 Level: intermediate 2045 2046 Concepts: matrices^local to global mapping 2047 Concepts: local to global mapping^for matrices 2048 2049 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2050 @*/ 2051 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2052 { 2053 PetscErrorCode ierr; 2054 2055 PetscFunctionBegin; 2056 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2057 PetscValidType(x,1); 2058 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2059 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2060 2061 if (x->ops->setlocaltoglobalmapping) { 2062 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2063 } else { 2064 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2065 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2066 } 2067 PetscFunctionReturn(0); 2068 } 2069 2070 2071 /*@ 2072 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2073 2074 Not Collective 2075 2076 Input Parameters: 2077 . A - the matrix 2078 2079 Output Parameters: 2080 + rmapping - row mapping 2081 - cmapping - column mapping 2082 2083 Level: advanced 2084 2085 Concepts: matrices^local to global mapping 2086 Concepts: local to global mapping^for matrices 2087 2088 .seealso: MatSetValuesLocal() 2089 @*/ 2090 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2091 { 2092 PetscFunctionBegin; 2093 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2094 PetscValidType(A,1); 2095 if (rmapping) PetscValidPointer(rmapping,2); 2096 if (cmapping) PetscValidPointer(cmapping,3); 2097 if (rmapping) *rmapping = A->rmap->mapping; 2098 if (cmapping) *cmapping = A->cmap->mapping; 2099 PetscFunctionReturn(0); 2100 } 2101 2102 /*@ 2103 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2104 2105 Not Collective 2106 2107 Input Parameters: 2108 . A - the matrix 2109 2110 Output Parameters: 2111 + rmap - row layout 2112 - cmap - column layout 2113 2114 Level: advanced 2115 2116 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2117 @*/ 2118 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2119 { 2120 PetscFunctionBegin; 2121 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2122 PetscValidType(A,1); 2123 if (rmap) PetscValidPointer(rmap,2); 2124 if (cmap) PetscValidPointer(cmap,3); 2125 if (rmap) *rmap = A->rmap; 2126 if (cmap) *cmap = A->cmap; 2127 PetscFunctionReturn(0); 2128 } 2129 2130 /*@C 2131 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2132 using a local ordering of the nodes. 2133 2134 Not Collective 2135 2136 Input Parameters: 2137 + mat - the matrix 2138 . nrow, irow - number of rows and their local indices 2139 . ncol, icol - number of columns and their local indices 2140 . y - a logically two-dimensional array of values 2141 - addv - either INSERT_VALUES or ADD_VALUES, where 2142 ADD_VALUES adds values to any existing entries, and 2143 INSERT_VALUES replaces existing entries with new values 2144 2145 Notes: 2146 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2147 MatSetUp() before using this routine 2148 2149 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2150 2151 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2152 options cannot be mixed without intervening calls to the assembly 2153 routines. 2154 2155 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2156 MUST be called after all calls to MatSetValuesLocal() have been completed. 2157 2158 Level: intermediate 2159 2160 Concepts: matrices^putting entries in with local numbering 2161 2162 Developer Notes: 2163 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2164 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2165 2166 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2167 MatSetValueLocal() 2168 @*/ 2169 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2170 { 2171 PetscErrorCode ierr; 2172 2173 PetscFunctionBeginHot; 2174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2175 PetscValidType(mat,1); 2176 MatCheckPreallocated(mat,1); 2177 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2178 PetscValidIntPointer(irow,3); 2179 PetscValidIntPointer(icol,5); 2180 PetscValidScalarPointer(y,6); 2181 if (mat->insertmode == NOT_SET_VALUES) { 2182 mat->insertmode = addv; 2183 } 2184 #if defined(PETSC_USE_DEBUG) 2185 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2186 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2187 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2188 #endif 2189 2190 if (mat->assembled) { 2191 mat->was_assembled = PETSC_TRUE; 2192 mat->assembled = PETSC_FALSE; 2193 } 2194 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2195 if (mat->ops->setvalueslocal) { 2196 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2197 } else { 2198 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2199 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2200 irowm = buf; icolm = buf+nrow; 2201 } else { 2202 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2203 irowm = bufr; icolm = bufc; 2204 } 2205 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2206 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2207 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2208 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2209 } 2210 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2211 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2212 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2213 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2214 } 2215 #endif 2216 PetscFunctionReturn(0); 2217 } 2218 2219 /*@C 2220 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2221 using a local ordering of the nodes a block at a time. 2222 2223 Not Collective 2224 2225 Input Parameters: 2226 + x - the matrix 2227 . nrow, irow - number of rows and their local indices 2228 . ncol, icol - number of columns and their local indices 2229 . y - a logically two-dimensional array of values 2230 - addv - either INSERT_VALUES or ADD_VALUES, where 2231 ADD_VALUES adds values to any existing entries, and 2232 INSERT_VALUES replaces existing entries with new values 2233 2234 Notes: 2235 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2236 MatSetUp() before using this routine 2237 2238 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2239 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2240 2241 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2242 options cannot be mixed without intervening calls to the assembly 2243 routines. 2244 2245 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2246 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2247 2248 Level: intermediate 2249 2250 Developer Notes: 2251 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2252 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2253 2254 Concepts: matrices^putting blocked values in with local numbering 2255 2256 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2257 MatSetValuesLocal(), MatSetValuesBlocked() 2258 @*/ 2259 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2260 { 2261 PetscErrorCode ierr; 2262 2263 PetscFunctionBeginHot; 2264 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2265 PetscValidType(mat,1); 2266 MatCheckPreallocated(mat,1); 2267 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2268 PetscValidIntPointer(irow,3); 2269 PetscValidIntPointer(icol,5); 2270 PetscValidScalarPointer(y,6); 2271 if (mat->insertmode == NOT_SET_VALUES) { 2272 mat->insertmode = addv; 2273 } 2274 #if defined(PETSC_USE_DEBUG) 2275 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2276 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2277 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); 2278 #endif 2279 2280 if (mat->assembled) { 2281 mat->was_assembled = PETSC_TRUE; 2282 mat->assembled = PETSC_FALSE; 2283 } 2284 #if defined(PETSC_USE_DEBUG) 2285 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2286 if (mat->rmap->mapping) { 2287 PetscInt irbs, rbs; 2288 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2289 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2290 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2291 } 2292 if (mat->cmap->mapping) { 2293 PetscInt icbs, cbs; 2294 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2295 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2296 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2297 } 2298 #endif 2299 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2300 if (mat->ops->setvaluesblockedlocal) { 2301 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2302 } else { 2303 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2304 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2305 irowm = buf; icolm = buf + nrow; 2306 } else { 2307 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2308 irowm = bufr; icolm = bufc; 2309 } 2310 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2311 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2312 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2313 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2314 } 2315 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2316 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2317 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2318 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2319 } 2320 #endif 2321 PetscFunctionReturn(0); 2322 } 2323 2324 /*@ 2325 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2326 2327 Collective on Mat and Vec 2328 2329 Input Parameters: 2330 + mat - the matrix 2331 - x - the vector to be multiplied 2332 2333 Output Parameters: 2334 . y - the result 2335 2336 Notes: 2337 The vectors x and y cannot be the same. I.e., one cannot 2338 call MatMult(A,y,y). 2339 2340 Level: developer 2341 2342 Concepts: matrix-vector product 2343 2344 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2345 @*/ 2346 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2347 { 2348 PetscErrorCode ierr; 2349 2350 PetscFunctionBegin; 2351 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2352 PetscValidType(mat,1); 2353 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2354 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2355 2356 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2357 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2358 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2359 MatCheckPreallocated(mat,1); 2360 2361 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2362 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2363 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2364 PetscFunctionReturn(0); 2365 } 2366 2367 /* --------------------------------------------------------*/ 2368 /*@ 2369 MatMult - Computes the matrix-vector product, y = Ax. 2370 2371 Neighbor-wise Collective on Mat and Vec 2372 2373 Input Parameters: 2374 + mat - the matrix 2375 - x - the vector to be multiplied 2376 2377 Output Parameters: 2378 . y - the result 2379 2380 Notes: 2381 The vectors x and y cannot be the same. I.e., one cannot 2382 call MatMult(A,y,y). 2383 2384 Level: beginner 2385 2386 Concepts: matrix-vector product 2387 2388 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2389 @*/ 2390 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2391 { 2392 PetscErrorCode ierr; 2393 2394 PetscFunctionBegin; 2395 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2396 PetscValidType(mat,1); 2397 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2398 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2399 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2400 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2401 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2402 #if !defined(PETSC_HAVE_CONSTRAINTS) 2403 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); 2404 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); 2405 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); 2406 #endif 2407 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2408 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2409 MatCheckPreallocated(mat,1); 2410 2411 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2412 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2413 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2414 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2415 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2416 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2417 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2418 PetscFunctionReturn(0); 2419 } 2420 2421 /*@ 2422 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2423 2424 Neighbor-wise Collective on Mat and Vec 2425 2426 Input Parameters: 2427 + mat - the matrix 2428 - x - the vector to be multiplied 2429 2430 Output Parameters: 2431 . y - the result 2432 2433 Notes: 2434 The vectors x and y cannot be the same. I.e., one cannot 2435 call MatMultTranspose(A,y,y). 2436 2437 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2438 use MatMultHermitianTranspose() 2439 2440 Level: beginner 2441 2442 Concepts: matrix vector product^transpose 2443 2444 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2445 @*/ 2446 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2447 { 2448 PetscErrorCode ierr; 2449 2450 PetscFunctionBegin; 2451 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2452 PetscValidType(mat,1); 2453 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2454 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2455 2456 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2457 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2458 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2459 #if !defined(PETSC_HAVE_CONSTRAINTS) 2460 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); 2461 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); 2462 #endif 2463 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2464 MatCheckPreallocated(mat,1); 2465 2466 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2467 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2468 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2469 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2470 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2471 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2472 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2473 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2474 PetscFunctionReturn(0); 2475 } 2476 2477 /*@ 2478 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2479 2480 Neighbor-wise Collective on Mat and Vec 2481 2482 Input Parameters: 2483 + mat - the matrix 2484 - x - the vector to be multilplied 2485 2486 Output Parameters: 2487 . y - the result 2488 2489 Notes: 2490 The vectors x and y cannot be the same. I.e., one cannot 2491 call MatMultHermitianTranspose(A,y,y). 2492 2493 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2494 2495 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2496 2497 Level: beginner 2498 2499 Concepts: matrix vector product^transpose 2500 2501 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2502 @*/ 2503 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2504 { 2505 PetscErrorCode ierr; 2506 Vec w; 2507 2508 PetscFunctionBegin; 2509 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2510 PetscValidType(mat,1); 2511 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2512 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2513 2514 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2515 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2516 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2517 #if !defined(PETSC_HAVE_CONSTRAINTS) 2518 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); 2519 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); 2520 #endif 2521 MatCheckPreallocated(mat,1); 2522 2523 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2524 if (mat->ops->multhermitiantranspose) { 2525 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2526 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2527 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2528 } else { 2529 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2530 ierr = VecCopy(x,w);CHKERRQ(ierr); 2531 ierr = VecConjugate(w);CHKERRQ(ierr); 2532 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2533 ierr = VecDestroy(&w);CHKERRQ(ierr); 2534 ierr = VecConjugate(y);CHKERRQ(ierr); 2535 } 2536 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2537 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2538 PetscFunctionReturn(0); 2539 } 2540 2541 /*@ 2542 MatMultAdd - Computes v3 = v2 + A * v1. 2543 2544 Neighbor-wise Collective on Mat and Vec 2545 2546 Input Parameters: 2547 + mat - the matrix 2548 - v1, v2 - the vectors 2549 2550 Output Parameters: 2551 . v3 - the result 2552 2553 Notes: 2554 The vectors v1 and v3 cannot be the same. I.e., one cannot 2555 call MatMultAdd(A,v1,v2,v1). 2556 2557 Level: beginner 2558 2559 Concepts: matrix vector product^addition 2560 2561 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2562 @*/ 2563 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2564 { 2565 PetscErrorCode ierr; 2566 2567 PetscFunctionBegin; 2568 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2569 PetscValidType(mat,1); 2570 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2571 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2572 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2573 2574 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2575 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2576 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); 2577 /* 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); 2578 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); */ 2579 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); 2580 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); 2581 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2582 MatCheckPreallocated(mat,1); 2583 2584 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2585 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2586 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2587 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2588 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2589 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2590 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2591 PetscFunctionReturn(0); 2592 } 2593 2594 /*@ 2595 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2596 2597 Neighbor-wise Collective on Mat and Vec 2598 2599 Input Parameters: 2600 + mat - the matrix 2601 - v1, v2 - the vectors 2602 2603 Output Parameters: 2604 . v3 - the result 2605 2606 Notes: 2607 The vectors v1 and v3 cannot be the same. I.e., one cannot 2608 call MatMultTransposeAdd(A,v1,v2,v1). 2609 2610 Level: beginner 2611 2612 Concepts: matrix vector product^transpose and addition 2613 2614 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2615 @*/ 2616 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2617 { 2618 PetscErrorCode ierr; 2619 2620 PetscFunctionBegin; 2621 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2622 PetscValidType(mat,1); 2623 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2624 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2625 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2626 2627 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2628 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2629 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2630 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2631 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); 2632 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); 2633 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); 2634 MatCheckPreallocated(mat,1); 2635 2636 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2637 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2638 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2639 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2640 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2641 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2642 PetscFunctionReturn(0); 2643 } 2644 2645 /*@ 2646 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2647 2648 Neighbor-wise Collective on Mat and Vec 2649 2650 Input Parameters: 2651 + mat - the matrix 2652 - v1, v2 - the vectors 2653 2654 Output Parameters: 2655 . v3 - the result 2656 2657 Notes: 2658 The vectors v1 and v3 cannot be the same. I.e., one cannot 2659 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2660 2661 Level: beginner 2662 2663 Concepts: matrix vector product^transpose and addition 2664 2665 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2666 @*/ 2667 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2668 { 2669 PetscErrorCode ierr; 2670 2671 PetscFunctionBegin; 2672 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2673 PetscValidType(mat,1); 2674 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2675 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2676 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2677 2678 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2679 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2680 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2681 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); 2682 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); 2683 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); 2684 MatCheckPreallocated(mat,1); 2685 2686 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2687 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2688 if (mat->ops->multhermitiantransposeadd) { 2689 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2690 } else { 2691 Vec w,z; 2692 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2693 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2694 ierr = VecConjugate(w);CHKERRQ(ierr); 2695 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2696 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2697 ierr = VecDestroy(&w);CHKERRQ(ierr); 2698 ierr = VecConjugate(z);CHKERRQ(ierr); 2699 if (v2 != v3) { 2700 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2701 } else { 2702 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2703 } 2704 ierr = VecDestroy(&z);CHKERRQ(ierr); 2705 } 2706 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2707 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2708 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2709 PetscFunctionReturn(0); 2710 } 2711 2712 /*@ 2713 MatMultConstrained - The inner multiplication routine for a 2714 constrained matrix P^T A P. 2715 2716 Neighbor-wise Collective on Mat and Vec 2717 2718 Input Parameters: 2719 + mat - the matrix 2720 - x - the vector to be multilplied 2721 2722 Output Parameters: 2723 . y - the result 2724 2725 Notes: 2726 The vectors x and y cannot be the same. I.e., one cannot 2727 call MatMult(A,y,y). 2728 2729 Level: beginner 2730 2731 .keywords: matrix, multiply, matrix-vector product, constraint 2732 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2733 @*/ 2734 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2735 { 2736 PetscErrorCode ierr; 2737 2738 PetscFunctionBegin; 2739 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2740 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2741 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2742 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2743 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2744 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2745 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); 2746 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); 2747 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); 2748 2749 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2750 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2751 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2752 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2753 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2754 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2755 PetscFunctionReturn(0); 2756 } 2757 2758 /*@ 2759 MatMultTransposeConstrained - The inner multiplication routine for a 2760 constrained matrix P^T A^T P. 2761 2762 Neighbor-wise Collective on Mat and Vec 2763 2764 Input Parameters: 2765 + mat - the matrix 2766 - x - the vector to be multilplied 2767 2768 Output Parameters: 2769 . y - the result 2770 2771 Notes: 2772 The vectors x and y cannot be the same. I.e., one cannot 2773 call MatMult(A,y,y). 2774 2775 Level: beginner 2776 2777 .keywords: matrix, multiply, matrix-vector product, constraint 2778 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2779 @*/ 2780 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2781 { 2782 PetscErrorCode ierr; 2783 2784 PetscFunctionBegin; 2785 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2786 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2787 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2788 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2789 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2790 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2791 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); 2792 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); 2793 2794 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2795 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2796 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2797 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2798 PetscFunctionReturn(0); 2799 } 2800 2801 /*@C 2802 MatGetFactorType - gets the type of factorization it is 2803 2804 Not Collective 2805 2806 Input Parameters: 2807 . mat - the matrix 2808 2809 Output Parameters: 2810 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2811 2812 Level: intermediate 2813 2814 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2815 @*/ 2816 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2817 { 2818 PetscFunctionBegin; 2819 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2820 PetscValidType(mat,1); 2821 PetscValidPointer(t,2); 2822 *t = mat->factortype; 2823 PetscFunctionReturn(0); 2824 } 2825 2826 /*@C 2827 MatSetFactorType - sets the type of factorization it is 2828 2829 Logically Collective on Mat 2830 2831 Input Parameters: 2832 + mat - the matrix 2833 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2834 2835 Level: intermediate 2836 2837 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2838 @*/ 2839 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2840 { 2841 PetscFunctionBegin; 2842 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2843 PetscValidType(mat,1); 2844 mat->factortype = t; 2845 PetscFunctionReturn(0); 2846 } 2847 2848 /* ------------------------------------------------------------*/ 2849 /*@C 2850 MatGetInfo - Returns information about matrix storage (number of 2851 nonzeros, memory, etc.). 2852 2853 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2854 2855 Input Parameters: 2856 . mat - the matrix 2857 2858 Output Parameters: 2859 + flag - flag indicating the type of parameters to be returned 2860 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2861 MAT_GLOBAL_SUM - sum over all processors) 2862 - info - matrix information context 2863 2864 Notes: 2865 The MatInfo context contains a variety of matrix data, including 2866 number of nonzeros allocated and used, number of mallocs during 2867 matrix assembly, etc. Additional information for factored matrices 2868 is provided (such as the fill ratio, number of mallocs during 2869 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2870 when using the runtime options 2871 $ -info -mat_view ::ascii_info 2872 2873 Example for C/C++ Users: 2874 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2875 data within the MatInfo context. For example, 2876 .vb 2877 MatInfo info; 2878 Mat A; 2879 double mal, nz_a, nz_u; 2880 2881 MatGetInfo(A,MAT_LOCAL,&info); 2882 mal = info.mallocs; 2883 nz_a = info.nz_allocated; 2884 .ve 2885 2886 Example for Fortran Users: 2887 Fortran users should declare info as a double precision 2888 array of dimension MAT_INFO_SIZE, and then extract the parameters 2889 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2890 a complete list of parameter names. 2891 .vb 2892 double precision info(MAT_INFO_SIZE) 2893 double precision mal, nz_a 2894 Mat A 2895 integer ierr 2896 2897 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2898 mal = info(MAT_INFO_MALLOCS) 2899 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2900 .ve 2901 2902 Level: intermediate 2903 2904 Concepts: matrices^getting information on 2905 2906 Developer Note: fortran interface is not autogenerated as the f90 2907 interface defintion cannot be generated correctly [due to MatInfo] 2908 2909 .seealso: MatStashGetInfo() 2910 2911 @*/ 2912 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2913 { 2914 PetscErrorCode ierr; 2915 2916 PetscFunctionBegin; 2917 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2918 PetscValidType(mat,1); 2919 PetscValidPointer(info,3); 2920 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2921 MatCheckPreallocated(mat,1); 2922 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2923 PetscFunctionReturn(0); 2924 } 2925 2926 /* 2927 This is used by external packages where it is not easy to get the info from the actual 2928 matrix factorization. 2929 */ 2930 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2931 { 2932 PetscErrorCode ierr; 2933 2934 PetscFunctionBegin; 2935 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2936 PetscFunctionReturn(0); 2937 } 2938 2939 /* ----------------------------------------------------------*/ 2940 2941 /*@C 2942 MatLUFactor - Performs in-place LU factorization of matrix. 2943 2944 Collective on Mat 2945 2946 Input Parameters: 2947 + mat - the matrix 2948 . row - row permutation 2949 . col - column permutation 2950 - info - options for factorization, includes 2951 $ fill - expected fill as ratio of original fill. 2952 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2953 $ Run with the option -info to determine an optimal value to use 2954 2955 Notes: 2956 Most users should employ the simplified KSP interface for linear solvers 2957 instead of working directly with matrix algebra routines such as this. 2958 See, e.g., KSPCreate(). 2959 2960 This changes the state of the matrix to a factored matrix; it cannot be used 2961 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2962 2963 Level: developer 2964 2965 Concepts: matrices^LU factorization 2966 2967 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2968 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2969 2970 Developer Note: fortran interface is not autogenerated as the f90 2971 interface defintion cannot be generated correctly [due to MatFactorInfo] 2972 2973 @*/ 2974 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2975 { 2976 PetscErrorCode ierr; 2977 MatFactorInfo tinfo; 2978 2979 PetscFunctionBegin; 2980 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2981 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2982 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2983 if (info) PetscValidPointer(info,4); 2984 PetscValidType(mat,1); 2985 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2986 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2987 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2988 MatCheckPreallocated(mat,1); 2989 if (!info) { 2990 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2991 info = &tinfo; 2992 } 2993 2994 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2995 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2996 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2997 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2998 PetscFunctionReturn(0); 2999 } 3000 3001 /*@C 3002 MatILUFactor - Performs in-place ILU factorization of matrix. 3003 3004 Collective on Mat 3005 3006 Input Parameters: 3007 + mat - the matrix 3008 . row - row permutation 3009 . col - column permutation 3010 - info - structure containing 3011 $ levels - number of levels of fill. 3012 $ expected fill - as ratio of original fill. 3013 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3014 missing diagonal entries) 3015 3016 Notes: 3017 Probably really in-place only when level of fill is zero, otherwise allocates 3018 new space to store factored matrix and deletes previous memory. 3019 3020 Most users should employ the simplified KSP interface for linear solvers 3021 instead of working directly with matrix algebra routines such as this. 3022 See, e.g., KSPCreate(). 3023 3024 Level: developer 3025 3026 Concepts: matrices^ILU factorization 3027 3028 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 3029 3030 Developer Note: fortran interface is not autogenerated as the f90 3031 interface defintion cannot be generated correctly [due to MatFactorInfo] 3032 3033 @*/ 3034 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3035 { 3036 PetscErrorCode ierr; 3037 3038 PetscFunctionBegin; 3039 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3040 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3041 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3042 PetscValidPointer(info,4); 3043 PetscValidType(mat,1); 3044 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3045 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3046 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3047 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3048 MatCheckPreallocated(mat,1); 3049 3050 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3051 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 3052 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3053 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3054 PetscFunctionReturn(0); 3055 } 3056 3057 /*@C 3058 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3059 Call this routine before calling MatLUFactorNumeric(). 3060 3061 Collective on Mat 3062 3063 Input Parameters: 3064 + fact - the factor matrix obtained with MatGetFactor() 3065 . mat - the matrix 3066 . row, col - row and column permutations 3067 - info - options for factorization, includes 3068 $ fill - expected fill as ratio of original fill. 3069 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3070 $ Run with the option -info to determine an optimal value to use 3071 3072 3073 Notes: 3074 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3075 3076 Most users should employ the simplified KSP interface for linear solvers 3077 instead of working directly with matrix algebra routines such as this. 3078 See, e.g., KSPCreate(). 3079 3080 Level: developer 3081 3082 Concepts: matrices^LU symbolic factorization 3083 3084 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 3085 3086 Developer Note: fortran interface is not autogenerated as the f90 3087 interface defintion cannot be generated correctly [due to MatFactorInfo] 3088 3089 @*/ 3090 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3091 { 3092 PetscErrorCode ierr; 3093 3094 PetscFunctionBegin; 3095 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3096 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3097 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3098 if (info) PetscValidPointer(info,4); 3099 PetscValidType(mat,1); 3100 PetscValidPointer(fact,5); 3101 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3102 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3103 if (!(fact)->ops->lufactorsymbolic) { 3104 MatSolverType spackage; 3105 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3106 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3107 } 3108 MatCheckPreallocated(mat,2); 3109 3110 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3111 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3112 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3113 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3114 PetscFunctionReturn(0); 3115 } 3116 3117 /*@C 3118 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3119 Call this routine after first calling MatLUFactorSymbolic(). 3120 3121 Collective on Mat 3122 3123 Input Parameters: 3124 + fact - the factor matrix obtained with MatGetFactor() 3125 . mat - the matrix 3126 - info - options for factorization 3127 3128 Notes: 3129 See MatLUFactor() for in-place factorization. See 3130 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3131 3132 Most users should employ the simplified KSP interface for linear solvers 3133 instead of working directly with matrix algebra routines such as this. 3134 See, e.g., KSPCreate(). 3135 3136 Level: developer 3137 3138 Concepts: matrices^LU numeric factorization 3139 3140 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3141 3142 Developer Note: fortran interface is not autogenerated as the f90 3143 interface defintion cannot be generated correctly [due to MatFactorInfo] 3144 3145 @*/ 3146 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3147 { 3148 PetscErrorCode ierr; 3149 3150 PetscFunctionBegin; 3151 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3152 PetscValidType(mat,1); 3153 PetscValidPointer(fact,2); 3154 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3155 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3156 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); 3157 3158 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3159 MatCheckPreallocated(mat,2); 3160 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3161 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3162 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3163 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3164 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3165 PetscFunctionReturn(0); 3166 } 3167 3168 /*@C 3169 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3170 symmetric matrix. 3171 3172 Collective on Mat 3173 3174 Input Parameters: 3175 + mat - the matrix 3176 . perm - row and column permutations 3177 - f - expected fill as ratio of original fill 3178 3179 Notes: 3180 See MatLUFactor() for the nonsymmetric case. See also 3181 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3182 3183 Most users should employ the simplified KSP interface for linear solvers 3184 instead of working directly with matrix algebra routines such as this. 3185 See, e.g., KSPCreate(). 3186 3187 Level: developer 3188 3189 Concepts: matrices^Cholesky factorization 3190 3191 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3192 MatGetOrdering() 3193 3194 Developer Note: fortran interface is not autogenerated as the f90 3195 interface defintion cannot be generated correctly [due to MatFactorInfo] 3196 3197 @*/ 3198 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3199 { 3200 PetscErrorCode ierr; 3201 3202 PetscFunctionBegin; 3203 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3204 PetscValidType(mat,1); 3205 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3206 if (info) PetscValidPointer(info,3); 3207 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3208 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3209 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3210 if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name); 3211 MatCheckPreallocated(mat,1); 3212 3213 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3214 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3215 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3216 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3217 PetscFunctionReturn(0); 3218 } 3219 3220 /*@C 3221 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3222 of a symmetric matrix. 3223 3224 Collective on Mat 3225 3226 Input Parameters: 3227 + fact - the factor matrix obtained with MatGetFactor() 3228 . mat - the matrix 3229 . perm - row and column permutations 3230 - info - options for factorization, includes 3231 $ fill - expected fill as ratio of original fill. 3232 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3233 $ Run with the option -info to determine an optimal value to use 3234 3235 Notes: 3236 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3237 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3238 3239 Most users should employ the simplified KSP interface for linear solvers 3240 instead of working directly with matrix algebra routines such as this. 3241 See, e.g., KSPCreate(). 3242 3243 Level: developer 3244 3245 Concepts: matrices^Cholesky symbolic factorization 3246 3247 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3248 MatGetOrdering() 3249 3250 Developer Note: fortran interface is not autogenerated as the f90 3251 interface defintion cannot be generated correctly [due to MatFactorInfo] 3252 3253 @*/ 3254 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3255 { 3256 PetscErrorCode ierr; 3257 3258 PetscFunctionBegin; 3259 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3260 PetscValidType(mat,1); 3261 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3262 if (info) PetscValidPointer(info,3); 3263 PetscValidPointer(fact,4); 3264 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3265 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3266 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3267 if (!(fact)->ops->choleskyfactorsymbolic) { 3268 MatSolverType spackage; 3269 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3270 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3271 } 3272 MatCheckPreallocated(mat,2); 3273 3274 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3275 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3276 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3277 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3278 PetscFunctionReturn(0); 3279 } 3280 3281 /*@C 3282 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3283 of a symmetric matrix. Call this routine after first calling 3284 MatCholeskyFactorSymbolic(). 3285 3286 Collective on Mat 3287 3288 Input Parameters: 3289 + fact - the factor matrix obtained with MatGetFactor() 3290 . mat - the initial matrix 3291 . info - options for factorization 3292 - fact - the symbolic factor of mat 3293 3294 3295 Notes: 3296 Most users should employ the simplified KSP interface for linear solvers 3297 instead of working directly with matrix algebra routines such as this. 3298 See, e.g., KSPCreate(). 3299 3300 Level: developer 3301 3302 Concepts: matrices^Cholesky numeric factorization 3303 3304 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3305 3306 Developer Note: fortran interface is not autogenerated as the f90 3307 interface defintion cannot be generated correctly [due to MatFactorInfo] 3308 3309 @*/ 3310 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3311 { 3312 PetscErrorCode ierr; 3313 3314 PetscFunctionBegin; 3315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3316 PetscValidType(mat,1); 3317 PetscValidPointer(fact,2); 3318 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3319 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3320 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3321 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); 3322 MatCheckPreallocated(mat,2); 3323 3324 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3325 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3326 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3327 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3328 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3329 PetscFunctionReturn(0); 3330 } 3331 3332 /* ----------------------------------------------------------------*/ 3333 /*@ 3334 MatSolve - Solves A x = b, given a factored matrix. 3335 3336 Neighbor-wise Collective on Mat and Vec 3337 3338 Input Parameters: 3339 + mat - the factored matrix 3340 - b - the right-hand-side vector 3341 3342 Output Parameter: 3343 . x - the result vector 3344 3345 Notes: 3346 The vectors b and x cannot be the same. I.e., one cannot 3347 call MatSolve(A,x,x). 3348 3349 Notes: 3350 Most users should employ the simplified KSP interface for linear solvers 3351 instead of working directly with matrix algebra routines such as this. 3352 See, e.g., KSPCreate(). 3353 3354 Level: developer 3355 3356 Concepts: matrices^triangular solves 3357 3358 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3359 @*/ 3360 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3361 { 3362 PetscErrorCode ierr; 3363 3364 PetscFunctionBegin; 3365 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3366 PetscValidType(mat,1); 3367 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3368 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3369 PetscCheckSameComm(mat,1,b,2); 3370 PetscCheckSameComm(mat,1,x,3); 3371 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3372 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); 3373 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); 3374 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); 3375 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3376 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3377 MatCheckPreallocated(mat,1); 3378 3379 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3380 if (mat->factorerrortype) { 3381 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3382 ierr = VecSetInf(x);CHKERRQ(ierr); 3383 } else { 3384 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3385 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3386 } 3387 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3388 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3389 PetscFunctionReturn(0); 3390 } 3391 3392 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3393 { 3394 PetscErrorCode ierr; 3395 Vec b,x; 3396 PetscInt m,N,i; 3397 PetscScalar *bb,*xx; 3398 PetscBool flg; 3399 3400 PetscFunctionBegin; 3401 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3402 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3403 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3404 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3405 3406 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3407 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3408 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3409 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3410 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3411 for (i=0; i<N; i++) { 3412 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3413 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3414 if (trans) { 3415 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3416 } else { 3417 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3418 } 3419 ierr = VecResetArray(x);CHKERRQ(ierr); 3420 ierr = VecResetArray(b);CHKERRQ(ierr); 3421 } 3422 ierr = VecDestroy(&b);CHKERRQ(ierr); 3423 ierr = VecDestroy(&x);CHKERRQ(ierr); 3424 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3425 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3426 PetscFunctionReturn(0); 3427 } 3428 3429 /*@ 3430 MatMatSolve - Solves A X = B, given a factored matrix. 3431 3432 Neighbor-wise Collective on Mat 3433 3434 Input Parameters: 3435 + A - the factored matrix 3436 - B - the right-hand-side matrix (dense matrix) 3437 3438 Output Parameter: 3439 . X - the result matrix (dense matrix) 3440 3441 Notes: 3442 The matrices b and x cannot be the same. I.e., one cannot 3443 call MatMatSolve(A,x,x). 3444 3445 Notes: 3446 Most users should usually employ the simplified KSP interface for linear solvers 3447 instead of working directly with matrix algebra routines such as this. 3448 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3449 at a time. 3450 3451 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3452 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3453 3454 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3455 3456 Level: developer 3457 3458 Concepts: matrices^triangular solves 3459 3460 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3461 @*/ 3462 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3463 { 3464 PetscErrorCode ierr; 3465 3466 PetscFunctionBegin; 3467 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3468 PetscValidType(A,1); 3469 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3470 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3471 PetscCheckSameComm(A,1,B,2); 3472 PetscCheckSameComm(A,1,X,3); 3473 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3474 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); 3475 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); 3476 if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3477 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3478 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3479 MatCheckPreallocated(A,1); 3480 3481 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3482 if (!A->ops->matsolve) { 3483 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3484 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3485 } else { 3486 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3487 } 3488 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3489 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3490 PetscFunctionReturn(0); 3491 } 3492 3493 /*@ 3494 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3495 3496 Neighbor-wise Collective on Mat 3497 3498 Input Parameters: 3499 + A - the factored matrix 3500 - B - the right-hand-side matrix (dense matrix) 3501 3502 Output Parameter: 3503 . X - the result matrix (dense matrix) 3504 3505 Notes: 3506 The matrices B and X cannot be the same. I.e., one cannot 3507 call MatMatSolveTranspose(A,X,X). 3508 3509 Notes: 3510 Most users should usually employ the simplified KSP interface for linear solvers 3511 instead of working directly with matrix algebra routines such as this. 3512 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3513 at a time. 3514 3515 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3516 3517 Level: developer 3518 3519 Concepts: matrices^triangular solves 3520 3521 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3522 @*/ 3523 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3524 { 3525 PetscErrorCode ierr; 3526 3527 PetscFunctionBegin; 3528 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3529 PetscValidType(A,1); 3530 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3531 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3532 PetscCheckSameComm(A,1,B,2); 3533 PetscCheckSameComm(A,1,X,3); 3534 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3535 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); 3536 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); 3537 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); 3538 if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3539 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3540 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3541 MatCheckPreallocated(A,1); 3542 3543 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3544 if (!A->ops->matsolvetranspose) { 3545 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3546 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3547 } else { 3548 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3549 } 3550 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3551 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3552 PetscFunctionReturn(0); 3553 } 3554 3555 /*@ 3556 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3557 3558 Neighbor-wise Collective on Mat 3559 3560 Input Parameters: 3561 + A - the factored matrix 3562 - Bt - the transpose of right-hand-side matrix 3563 3564 Output Parameter: 3565 . X - the result matrix (dense matrix) 3566 3567 Notes: 3568 Most users should usually employ the simplified KSP interface for linear solvers 3569 instead of working directly with matrix algebra routines such as this. 3570 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3571 at a time. 3572 3573 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3574 3575 Level: developer 3576 3577 Concepts: matrices^triangular solves 3578 3579 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3580 @*/ 3581 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3582 { 3583 PetscErrorCode ierr; 3584 3585 PetscFunctionBegin; 3586 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3587 PetscValidType(A,1); 3588 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3589 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3590 PetscCheckSameComm(A,1,Bt,2); 3591 PetscCheckSameComm(A,1,X,3); 3592 3593 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3594 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); 3595 if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N); 3596 if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3597 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3598 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3599 MatCheckPreallocated(A,1); 3600 3601 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3602 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3603 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3604 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3605 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3606 PetscFunctionReturn(0); 3607 } 3608 3609 /*@ 3610 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3611 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3612 3613 Neighbor-wise Collective on Mat and Vec 3614 3615 Input Parameters: 3616 + mat - the factored matrix 3617 - b - the right-hand-side vector 3618 3619 Output Parameter: 3620 . x - the result vector 3621 3622 Notes: 3623 MatSolve() should be used for most applications, as it performs 3624 a forward solve followed by a backward solve. 3625 3626 The vectors b and x cannot be the same, i.e., one cannot 3627 call MatForwardSolve(A,x,x). 3628 3629 For matrix in seqsbaij format with block size larger than 1, 3630 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3631 MatForwardSolve() solves U^T*D y = b, and 3632 MatBackwardSolve() solves U x = y. 3633 Thus they do not provide a symmetric preconditioner. 3634 3635 Most users should employ the simplified KSP interface for linear solvers 3636 instead of working directly with matrix algebra routines such as this. 3637 See, e.g., KSPCreate(). 3638 3639 Level: developer 3640 3641 Concepts: matrices^forward solves 3642 3643 .seealso: MatSolve(), MatBackwardSolve() 3644 @*/ 3645 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3646 { 3647 PetscErrorCode ierr; 3648 3649 PetscFunctionBegin; 3650 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3651 PetscValidType(mat,1); 3652 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3653 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3654 PetscCheckSameComm(mat,1,b,2); 3655 PetscCheckSameComm(mat,1,x,3); 3656 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3657 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); 3658 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); 3659 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); 3660 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3661 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3662 MatCheckPreallocated(mat,1); 3663 3664 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3665 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3666 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3667 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3668 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3669 PetscFunctionReturn(0); 3670 } 3671 3672 /*@ 3673 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3674 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3675 3676 Neighbor-wise Collective on Mat and Vec 3677 3678 Input Parameters: 3679 + mat - the factored matrix 3680 - b - the right-hand-side vector 3681 3682 Output Parameter: 3683 . x - the result vector 3684 3685 Notes: 3686 MatSolve() should be used for most applications, as it performs 3687 a forward solve followed by a backward solve. 3688 3689 The vectors b and x cannot be the same. I.e., one cannot 3690 call MatBackwardSolve(A,x,x). 3691 3692 For matrix in seqsbaij format with block size larger than 1, 3693 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3694 MatForwardSolve() solves U^T*D y = b, and 3695 MatBackwardSolve() solves U x = y. 3696 Thus they do not provide a symmetric preconditioner. 3697 3698 Most users should employ the simplified KSP interface for linear solvers 3699 instead of working directly with matrix algebra routines such as this. 3700 See, e.g., KSPCreate(). 3701 3702 Level: developer 3703 3704 Concepts: matrices^backward solves 3705 3706 .seealso: MatSolve(), MatForwardSolve() 3707 @*/ 3708 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3709 { 3710 PetscErrorCode ierr; 3711 3712 PetscFunctionBegin; 3713 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3714 PetscValidType(mat,1); 3715 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3716 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3717 PetscCheckSameComm(mat,1,b,2); 3718 PetscCheckSameComm(mat,1,x,3); 3719 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3720 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); 3721 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); 3722 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); 3723 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3724 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3725 MatCheckPreallocated(mat,1); 3726 3727 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3728 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3729 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3730 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3731 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3732 PetscFunctionReturn(0); 3733 } 3734 3735 /*@ 3736 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3737 3738 Neighbor-wise Collective on Mat and Vec 3739 3740 Input Parameters: 3741 + mat - the factored matrix 3742 . b - the right-hand-side vector 3743 - y - the vector to be added to 3744 3745 Output Parameter: 3746 . x - the result vector 3747 3748 Notes: 3749 The vectors b and x cannot be the same. I.e., one cannot 3750 call MatSolveAdd(A,x,y,x). 3751 3752 Most users should employ the simplified KSP interface for linear solvers 3753 instead of working directly with matrix algebra routines such as this. 3754 See, e.g., KSPCreate(). 3755 3756 Level: developer 3757 3758 Concepts: matrices^triangular solves 3759 3760 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3761 @*/ 3762 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3763 { 3764 PetscScalar one = 1.0; 3765 Vec tmp; 3766 PetscErrorCode ierr; 3767 3768 PetscFunctionBegin; 3769 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3770 PetscValidType(mat,1); 3771 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3772 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3773 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3774 PetscCheckSameComm(mat,1,b,2); 3775 PetscCheckSameComm(mat,1,y,2); 3776 PetscCheckSameComm(mat,1,x,3); 3777 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3778 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); 3779 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); 3780 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); 3781 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); 3782 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); 3783 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3784 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3785 MatCheckPreallocated(mat,1); 3786 3787 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3788 if (mat->ops->solveadd) { 3789 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3790 } else { 3791 /* do the solve then the add manually */ 3792 if (x != y) { 3793 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3794 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3795 } else { 3796 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3797 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3798 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3799 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3800 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3801 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3802 } 3803 } 3804 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3805 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3806 PetscFunctionReturn(0); 3807 } 3808 3809 /*@ 3810 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3811 3812 Neighbor-wise Collective on Mat and Vec 3813 3814 Input Parameters: 3815 + mat - the factored matrix 3816 - b - the right-hand-side vector 3817 3818 Output Parameter: 3819 . x - the result vector 3820 3821 Notes: 3822 The vectors b and x cannot be the same. I.e., one cannot 3823 call MatSolveTranspose(A,x,x). 3824 3825 Most users should employ the simplified KSP interface for linear solvers 3826 instead of working directly with matrix algebra routines such as this. 3827 See, e.g., KSPCreate(). 3828 3829 Level: developer 3830 3831 Concepts: matrices^triangular solves 3832 3833 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3834 @*/ 3835 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3836 { 3837 PetscErrorCode ierr; 3838 3839 PetscFunctionBegin; 3840 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3841 PetscValidType(mat,1); 3842 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3843 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3844 PetscCheckSameComm(mat,1,b,2); 3845 PetscCheckSameComm(mat,1,x,3); 3846 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3847 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); 3848 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); 3849 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3850 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3851 MatCheckPreallocated(mat,1); 3852 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3853 if (mat->factorerrortype) { 3854 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3855 ierr = VecSetInf(x);CHKERRQ(ierr); 3856 } else { 3857 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3858 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3859 } 3860 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3861 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3862 PetscFunctionReturn(0); 3863 } 3864 3865 /*@ 3866 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3867 factored matrix. 3868 3869 Neighbor-wise Collective on Mat and Vec 3870 3871 Input Parameters: 3872 + mat - the factored matrix 3873 . b - the right-hand-side vector 3874 - y - the vector to be added to 3875 3876 Output Parameter: 3877 . x - the result vector 3878 3879 Notes: 3880 The vectors b and x cannot be the same. I.e., one cannot 3881 call MatSolveTransposeAdd(A,x,y,x). 3882 3883 Most users should employ the simplified KSP interface for linear solvers 3884 instead of working directly with matrix algebra routines such as this. 3885 See, e.g., KSPCreate(). 3886 3887 Level: developer 3888 3889 Concepts: matrices^triangular solves 3890 3891 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3892 @*/ 3893 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3894 { 3895 PetscScalar one = 1.0; 3896 PetscErrorCode ierr; 3897 Vec tmp; 3898 3899 PetscFunctionBegin; 3900 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3901 PetscValidType(mat,1); 3902 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3903 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3904 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3905 PetscCheckSameComm(mat,1,b,2); 3906 PetscCheckSameComm(mat,1,y,3); 3907 PetscCheckSameComm(mat,1,x,4); 3908 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3909 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); 3910 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); 3911 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); 3912 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); 3913 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3914 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3915 MatCheckPreallocated(mat,1); 3916 3917 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3918 if (mat->ops->solvetransposeadd) { 3919 if (mat->factorerrortype) { 3920 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3921 ierr = VecSetInf(x);CHKERRQ(ierr); 3922 } else { 3923 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3924 } 3925 } else { 3926 /* do the solve then the add manually */ 3927 if (x != y) { 3928 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3929 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3930 } else { 3931 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3932 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3933 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3934 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3935 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3936 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3937 } 3938 } 3939 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3940 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3941 PetscFunctionReturn(0); 3942 } 3943 /* ----------------------------------------------------------------*/ 3944 3945 /*@ 3946 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3947 3948 Neighbor-wise Collective on Mat and Vec 3949 3950 Input Parameters: 3951 + mat - the matrix 3952 . b - the right hand side 3953 . omega - the relaxation factor 3954 . flag - flag indicating the type of SOR (see below) 3955 . shift - diagonal shift 3956 . its - the number of iterations 3957 - lits - the number of local iterations 3958 3959 Output Parameters: 3960 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3961 3962 SOR Flags: 3963 . SOR_FORWARD_SWEEP - forward SOR 3964 . SOR_BACKWARD_SWEEP - backward SOR 3965 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3966 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3967 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3968 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3969 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3970 upper/lower triangular part of matrix to 3971 vector (with omega) 3972 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3973 3974 Notes: 3975 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3976 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3977 on each processor. 3978 3979 Application programmers will not generally use MatSOR() directly, 3980 but instead will employ the KSP/PC interface. 3981 3982 Notes: 3983 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3984 3985 Notes for Advanced Users: 3986 The flags are implemented as bitwise inclusive or operations. 3987 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3988 to specify a zero initial guess for SSOR. 3989 3990 Most users should employ the simplified KSP interface for linear solvers 3991 instead of working directly with matrix algebra routines such as this. 3992 See, e.g., KSPCreate(). 3993 3994 Vectors x and b CANNOT be the same 3995 3996 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3997 3998 Level: developer 3999 4000 Concepts: matrices^relaxation 4001 Concepts: matrices^SOR 4002 Concepts: matrices^Gauss-Seidel 4003 4004 @*/ 4005 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4006 { 4007 PetscErrorCode ierr; 4008 4009 PetscFunctionBegin; 4010 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4011 PetscValidType(mat,1); 4012 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4013 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4014 PetscCheckSameComm(mat,1,b,2); 4015 PetscCheckSameComm(mat,1,x,8); 4016 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4017 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4018 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4019 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); 4020 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); 4021 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); 4022 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 4023 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 4024 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4025 4026 MatCheckPreallocated(mat,1); 4027 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4028 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 4029 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4030 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4031 PetscFunctionReturn(0); 4032 } 4033 4034 /* 4035 Default matrix copy routine. 4036 */ 4037 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4038 { 4039 PetscErrorCode ierr; 4040 PetscInt i,rstart = 0,rend = 0,nz; 4041 const PetscInt *cwork; 4042 const PetscScalar *vwork; 4043 4044 PetscFunctionBegin; 4045 if (B->assembled) { 4046 ierr = MatZeroEntries(B);CHKERRQ(ierr); 4047 } 4048 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 4049 for (i=rstart; i<rend; i++) { 4050 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4051 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 4052 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4053 } 4054 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4055 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4056 PetscFunctionReturn(0); 4057 } 4058 4059 /*@ 4060 MatCopy - Copys a matrix to another matrix. 4061 4062 Collective on Mat 4063 4064 Input Parameters: 4065 + A - the matrix 4066 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4067 4068 Output Parameter: 4069 . B - where the copy is put 4070 4071 Notes: 4072 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 4073 same nonzero pattern or the routine will crash. 4074 4075 MatCopy() copies the matrix entries of a matrix to another existing 4076 matrix (after first zeroing the second matrix). A related routine is 4077 MatConvert(), which first creates a new matrix and then copies the data. 4078 4079 Level: intermediate 4080 4081 Concepts: matrices^copying 4082 4083 .seealso: MatConvert(), MatDuplicate() 4084 4085 @*/ 4086 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4087 { 4088 PetscErrorCode ierr; 4089 PetscInt i; 4090 4091 PetscFunctionBegin; 4092 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4093 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4094 PetscValidType(A,1); 4095 PetscValidType(B,2); 4096 PetscCheckSameComm(A,1,B,2); 4097 MatCheckPreallocated(B,2); 4098 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4099 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4100 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); 4101 MatCheckPreallocated(A,1); 4102 if (A == B) PetscFunctionReturn(0); 4103 4104 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4105 if (A->ops->copy) { 4106 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4107 } else { /* generic conversion */ 4108 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4109 } 4110 4111 B->stencil.dim = A->stencil.dim; 4112 B->stencil.noc = A->stencil.noc; 4113 for (i=0; i<=A->stencil.dim; i++) { 4114 B->stencil.dims[i] = A->stencil.dims[i]; 4115 B->stencil.starts[i] = A->stencil.starts[i]; 4116 } 4117 4118 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4119 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4120 PetscFunctionReturn(0); 4121 } 4122 4123 /*@C 4124 MatConvert - Converts a matrix to another matrix, either of the same 4125 or different type. 4126 4127 Collective on Mat 4128 4129 Input Parameters: 4130 + mat - the matrix 4131 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4132 same type as the original matrix. 4133 - reuse - denotes if the destination matrix is to be created or reused. 4134 Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use 4135 MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused). 4136 4137 Output Parameter: 4138 . M - pointer to place new matrix 4139 4140 Notes: 4141 MatConvert() first creates a new matrix and then copies the data from 4142 the first matrix. A related routine is MatCopy(), which copies the matrix 4143 entries of one matrix to another already existing matrix context. 4144 4145 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4146 the MPI communicator of the generated matrix is always the same as the communicator 4147 of the input matrix. 4148 4149 Level: intermediate 4150 4151 Concepts: matrices^converting between storage formats 4152 4153 .seealso: MatCopy(), MatDuplicate() 4154 @*/ 4155 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4156 { 4157 PetscErrorCode ierr; 4158 PetscBool sametype,issame,flg; 4159 char convname[256],mtype[256]; 4160 Mat B; 4161 4162 PetscFunctionBegin; 4163 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4164 PetscValidType(mat,1); 4165 PetscValidPointer(M,3); 4166 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4167 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4168 MatCheckPreallocated(mat,1); 4169 4170 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4171 if (flg) { 4172 newtype = mtype; 4173 } 4174 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4175 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4176 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4177 if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4178 4179 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4180 4181 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4182 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4183 } else { 4184 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4185 const char *prefix[3] = {"seq","mpi",""}; 4186 PetscInt i; 4187 /* 4188 Order of precedence: 4189 0) See if newtype is a superclass of the current matrix. 4190 1) See if a specialized converter is known to the current matrix. 4191 2) See if a specialized converter is known to the desired matrix class. 4192 3) See if a good general converter is registered for the desired class 4193 (as of 6/27/03 only MATMPIADJ falls into this category). 4194 4) See if a good general converter is known for the current matrix. 4195 5) Use a really basic converter. 4196 */ 4197 4198 /* 0) See if newtype is a superclass of the current matrix. 4199 i.e mat is mpiaij and newtype is aij */ 4200 for (i=0; i<2; i++) { 4201 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4202 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4203 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4204 if (flg) { 4205 if (reuse == MAT_INPLACE_MATRIX) { 4206 PetscFunctionReturn(0); 4207 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4208 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4209 PetscFunctionReturn(0); 4210 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4211 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4212 PetscFunctionReturn(0); 4213 } 4214 } 4215 } 4216 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4217 for (i=0; i<3; i++) { 4218 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4219 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4220 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4221 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4222 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4223 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4224 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4225 if (conv) goto foundconv; 4226 } 4227 4228 /* 2) See if a specialized converter is known to the desired matrix class. */ 4229 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4230 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4231 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4232 for (i=0; i<3; i++) { 4233 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4234 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4235 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4236 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4237 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4238 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4239 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4240 if (conv) { 4241 ierr = MatDestroy(&B);CHKERRQ(ierr); 4242 goto foundconv; 4243 } 4244 } 4245 4246 /* 3) See if a good general converter is registered for the desired class */ 4247 conv = B->ops->convertfrom; 4248 ierr = MatDestroy(&B);CHKERRQ(ierr); 4249 if (conv) goto foundconv; 4250 4251 /* 4) See if a good general converter is known for the current matrix */ 4252 if (mat->ops->convert) { 4253 conv = mat->ops->convert; 4254 } 4255 if (conv) goto foundconv; 4256 4257 /* 5) Use a really basic converter. */ 4258 conv = MatConvert_Basic; 4259 4260 foundconv: 4261 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4262 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4263 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4264 /* the block sizes must be same if the mappings are copied over */ 4265 (*M)->rmap->bs = mat->rmap->bs; 4266 (*M)->cmap->bs = mat->cmap->bs; 4267 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4268 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4269 (*M)->rmap->mapping = mat->rmap->mapping; 4270 (*M)->cmap->mapping = mat->cmap->mapping; 4271 } 4272 (*M)->stencil.dim = mat->stencil.dim; 4273 (*M)->stencil.noc = mat->stencil.noc; 4274 for (i=0; i<=mat->stencil.dim; i++) { 4275 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4276 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4277 } 4278 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4279 } 4280 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4281 4282 /* Copy Mat options */ 4283 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4284 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4285 PetscFunctionReturn(0); 4286 } 4287 4288 /*@C 4289 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4290 4291 Not Collective 4292 4293 Input Parameter: 4294 . mat - the matrix, must be a factored matrix 4295 4296 Output Parameter: 4297 . type - the string name of the package (do not free this string) 4298 4299 Notes: 4300 In Fortran you pass in a empty string and the package name will be copied into it. 4301 (Make sure the string is long enough) 4302 4303 Level: intermediate 4304 4305 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4306 @*/ 4307 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4308 { 4309 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4310 4311 PetscFunctionBegin; 4312 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4313 PetscValidType(mat,1); 4314 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4315 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4316 if (!conv) { 4317 *type = MATSOLVERPETSC; 4318 } else { 4319 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4320 } 4321 PetscFunctionReturn(0); 4322 } 4323 4324 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4325 struct _MatSolverTypeForSpecifcType { 4326 MatType mtype; 4327 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4328 MatSolverTypeForSpecifcType next; 4329 }; 4330 4331 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4332 struct _MatSolverTypeHolder { 4333 char *name; 4334 MatSolverTypeForSpecifcType handlers; 4335 MatSolverTypeHolder next; 4336 }; 4337 4338 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4339 4340 /*@C 4341 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4342 4343 Input Parameters: 4344 + package - name of the package, for example petsc or superlu 4345 . mtype - the matrix type that works with this package 4346 . ftype - the type of factorization supported by the package 4347 - getfactor - routine that will create the factored matrix ready to be used 4348 4349 Level: intermediate 4350 4351 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4352 @*/ 4353 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4354 { 4355 PetscErrorCode ierr; 4356 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4357 PetscBool flg; 4358 MatSolverTypeForSpecifcType inext,iprev = NULL; 4359 4360 PetscFunctionBegin; 4361 ierr = MatInitializePackage();CHKERRQ(ierr); 4362 if (!next) { 4363 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4364 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4365 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4366 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4367 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4368 PetscFunctionReturn(0); 4369 } 4370 while (next) { 4371 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4372 if (flg) { 4373 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4374 inext = next->handlers; 4375 while (inext) { 4376 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4377 if (flg) { 4378 inext->getfactor[(int)ftype-1] = getfactor; 4379 PetscFunctionReturn(0); 4380 } 4381 iprev = inext; 4382 inext = inext->next; 4383 } 4384 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4385 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4386 iprev->next->getfactor[(int)ftype-1] = getfactor; 4387 PetscFunctionReturn(0); 4388 } 4389 prev = next; 4390 next = next->next; 4391 } 4392 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4393 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4394 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4395 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4396 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4397 PetscFunctionReturn(0); 4398 } 4399 4400 /*@C 4401 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4402 4403 Input Parameters: 4404 + package - name of the package, for example petsc or superlu 4405 . ftype - the type of factorization supported by the package 4406 - mtype - the matrix type that works with this package 4407 4408 Output Parameters: 4409 + foundpackage - PETSC_TRUE if the package was registered 4410 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4411 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4412 4413 Level: intermediate 4414 4415 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4416 @*/ 4417 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4418 { 4419 PetscErrorCode ierr; 4420 MatSolverTypeHolder next = MatSolverTypeHolders; 4421 PetscBool flg; 4422 MatSolverTypeForSpecifcType inext; 4423 4424 PetscFunctionBegin; 4425 if (foundpackage) *foundpackage = PETSC_FALSE; 4426 if (foundmtype) *foundmtype = PETSC_FALSE; 4427 if (getfactor) *getfactor = NULL; 4428 4429 if (package) { 4430 while (next) { 4431 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4432 if (flg) { 4433 if (foundpackage) *foundpackage = PETSC_TRUE; 4434 inext = next->handlers; 4435 while (inext) { 4436 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4437 if (flg) { 4438 if (foundmtype) *foundmtype = PETSC_TRUE; 4439 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4440 PetscFunctionReturn(0); 4441 } 4442 inext = inext->next; 4443 } 4444 } 4445 next = next->next; 4446 } 4447 } else { 4448 while (next) { 4449 inext = next->handlers; 4450 while (inext) { 4451 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4452 if (flg && inext->getfactor[(int)ftype-1]) { 4453 if (foundpackage) *foundpackage = PETSC_TRUE; 4454 if (foundmtype) *foundmtype = PETSC_TRUE; 4455 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4456 PetscFunctionReturn(0); 4457 } 4458 inext = inext->next; 4459 } 4460 next = next->next; 4461 } 4462 } 4463 PetscFunctionReturn(0); 4464 } 4465 4466 PetscErrorCode MatSolverTypeDestroy(void) 4467 { 4468 PetscErrorCode ierr; 4469 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4470 MatSolverTypeForSpecifcType inext,iprev; 4471 4472 PetscFunctionBegin; 4473 while (next) { 4474 ierr = PetscFree(next->name);CHKERRQ(ierr); 4475 inext = next->handlers; 4476 while (inext) { 4477 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4478 iprev = inext; 4479 inext = inext->next; 4480 ierr = PetscFree(iprev);CHKERRQ(ierr); 4481 } 4482 prev = next; 4483 next = next->next; 4484 ierr = PetscFree(prev);CHKERRQ(ierr); 4485 } 4486 MatSolverTypeHolders = NULL; 4487 PetscFunctionReturn(0); 4488 } 4489 4490 /*@C 4491 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4492 4493 Collective on Mat 4494 4495 Input Parameters: 4496 + mat - the matrix 4497 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4498 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4499 4500 Output Parameters: 4501 . f - the factor matrix used with MatXXFactorSymbolic() calls 4502 4503 Notes: 4504 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4505 such as pastix, superlu, mumps etc. 4506 4507 PETSc must have been ./configure to use the external solver, using the option --download-package 4508 4509 Level: intermediate 4510 4511 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4512 @*/ 4513 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4514 { 4515 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4516 PetscBool foundpackage,foundmtype; 4517 4518 PetscFunctionBegin; 4519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4520 PetscValidType(mat,1); 4521 4522 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4523 MatCheckPreallocated(mat,1); 4524 4525 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4526 if (!foundpackage) { 4527 if (type) { 4528 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4529 } else { 4530 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4531 } 4532 } 4533 4534 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4535 if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4536 4537 #if defined(PETSC_USE_COMPLEX) 4538 if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported"); 4539 #endif 4540 4541 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4542 PetscFunctionReturn(0); 4543 } 4544 4545 /*@C 4546 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4547 4548 Not Collective 4549 4550 Input Parameters: 4551 + mat - the matrix 4552 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4553 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4554 4555 Output Parameter: 4556 . flg - PETSC_TRUE if the factorization is available 4557 4558 Notes: 4559 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4560 such as pastix, superlu, mumps etc. 4561 4562 PETSc must have been ./configure to use the external solver, using the option --download-package 4563 4564 Level: intermediate 4565 4566 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4567 @*/ 4568 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4569 { 4570 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4571 4572 PetscFunctionBegin; 4573 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4574 PetscValidType(mat,1); 4575 4576 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4577 MatCheckPreallocated(mat,1); 4578 4579 *flg = PETSC_FALSE; 4580 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4581 if (gconv) { 4582 *flg = PETSC_TRUE; 4583 } 4584 PetscFunctionReturn(0); 4585 } 4586 4587 #include <petscdmtypes.h> 4588 4589 /*@ 4590 MatDuplicate - Duplicates a matrix including the non-zero structure. 4591 4592 Collective on Mat 4593 4594 Input Parameters: 4595 + mat - the matrix 4596 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4597 See the manual page for MatDuplicateOption for an explanation of these options. 4598 4599 Output Parameter: 4600 . M - pointer to place new matrix 4601 4602 Level: intermediate 4603 4604 Concepts: matrices^duplicating 4605 4606 Notes: 4607 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4608 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation. 4609 4610 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4611 @*/ 4612 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4613 { 4614 PetscErrorCode ierr; 4615 Mat B; 4616 PetscInt i; 4617 DM dm; 4618 void (*viewf)(void); 4619 4620 PetscFunctionBegin; 4621 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4622 PetscValidType(mat,1); 4623 PetscValidPointer(M,3); 4624 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4625 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4626 MatCheckPreallocated(mat,1); 4627 4628 *M = 0; 4629 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4630 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4631 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4632 B = *M; 4633 4634 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4635 if (viewf) { 4636 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4637 } 4638 4639 B->stencil.dim = mat->stencil.dim; 4640 B->stencil.noc = mat->stencil.noc; 4641 for (i=0; i<=mat->stencil.dim; i++) { 4642 B->stencil.dims[i] = mat->stencil.dims[i]; 4643 B->stencil.starts[i] = mat->stencil.starts[i]; 4644 } 4645 4646 B->nooffproczerorows = mat->nooffproczerorows; 4647 B->nooffprocentries = mat->nooffprocentries; 4648 4649 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4650 if (dm) { 4651 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4652 } 4653 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4654 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4655 PetscFunctionReturn(0); 4656 } 4657 4658 /*@ 4659 MatGetDiagonal - Gets the diagonal of a matrix. 4660 4661 Logically Collective on Mat and Vec 4662 4663 Input Parameters: 4664 + mat - the matrix 4665 - v - the vector for storing the diagonal 4666 4667 Output Parameter: 4668 . v - the diagonal of the matrix 4669 4670 Level: intermediate 4671 4672 Note: 4673 Currently only correct in parallel for square matrices. 4674 4675 Concepts: matrices^accessing diagonals 4676 4677 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4678 @*/ 4679 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4680 { 4681 PetscErrorCode ierr; 4682 4683 PetscFunctionBegin; 4684 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4685 PetscValidType(mat,1); 4686 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4687 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4688 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4689 MatCheckPreallocated(mat,1); 4690 4691 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4692 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4693 PetscFunctionReturn(0); 4694 } 4695 4696 /*@C 4697 MatGetRowMin - Gets the minimum value (of the real part) of each 4698 row of the matrix 4699 4700 Logically Collective on Mat and Vec 4701 4702 Input Parameters: 4703 . mat - the matrix 4704 4705 Output Parameter: 4706 + v - the vector for storing the maximums 4707 - idx - the indices of the column found for each row (optional) 4708 4709 Level: intermediate 4710 4711 Notes: 4712 The result of this call are the same as if one converted the matrix to dense format 4713 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4714 4715 This code is only implemented for a couple of matrix formats. 4716 4717 Concepts: matrices^getting row maximums 4718 4719 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4720 MatGetRowMax() 4721 @*/ 4722 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4723 { 4724 PetscErrorCode ierr; 4725 4726 PetscFunctionBegin; 4727 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4728 PetscValidType(mat,1); 4729 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4730 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4731 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4732 MatCheckPreallocated(mat,1); 4733 4734 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4735 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4736 PetscFunctionReturn(0); 4737 } 4738 4739 /*@C 4740 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4741 row of the matrix 4742 4743 Logically Collective on Mat and Vec 4744 4745 Input Parameters: 4746 . mat - the matrix 4747 4748 Output Parameter: 4749 + v - the vector for storing the minimums 4750 - idx - the indices of the column found for each row (or NULL if not needed) 4751 4752 Level: intermediate 4753 4754 Notes: 4755 if a row is completely empty or has only 0.0 values then the idx[] value for that 4756 row is 0 (the first column). 4757 4758 This code is only implemented for a couple of matrix formats. 4759 4760 Concepts: matrices^getting row maximums 4761 4762 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4763 @*/ 4764 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4765 { 4766 PetscErrorCode ierr; 4767 4768 PetscFunctionBegin; 4769 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4770 PetscValidType(mat,1); 4771 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4772 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4773 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4774 MatCheckPreallocated(mat,1); 4775 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4776 4777 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4778 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4779 PetscFunctionReturn(0); 4780 } 4781 4782 /*@C 4783 MatGetRowMax - Gets the maximum value (of the real part) of each 4784 row of the matrix 4785 4786 Logically Collective on Mat and Vec 4787 4788 Input Parameters: 4789 . mat - the matrix 4790 4791 Output Parameter: 4792 + v - the vector for storing the maximums 4793 - idx - the indices of the column found for each row (optional) 4794 4795 Level: intermediate 4796 4797 Notes: 4798 The result of this call are the same as if one converted the matrix to dense format 4799 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4800 4801 This code is only implemented for a couple of matrix formats. 4802 4803 Concepts: matrices^getting row maximums 4804 4805 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4806 @*/ 4807 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4808 { 4809 PetscErrorCode ierr; 4810 4811 PetscFunctionBegin; 4812 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4813 PetscValidType(mat,1); 4814 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4815 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4816 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4817 MatCheckPreallocated(mat,1); 4818 4819 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4820 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4821 PetscFunctionReturn(0); 4822 } 4823 4824 /*@C 4825 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4826 row of the matrix 4827 4828 Logically Collective on Mat and Vec 4829 4830 Input Parameters: 4831 . mat - the matrix 4832 4833 Output Parameter: 4834 + v - the vector for storing the maximums 4835 - idx - the indices of the column found for each row (or NULL if not needed) 4836 4837 Level: intermediate 4838 4839 Notes: 4840 if a row is completely empty or has only 0.0 values then the idx[] value for that 4841 row is 0 (the first column). 4842 4843 This code is only implemented for a couple of matrix formats. 4844 4845 Concepts: matrices^getting row maximums 4846 4847 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4848 @*/ 4849 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4850 { 4851 PetscErrorCode ierr; 4852 4853 PetscFunctionBegin; 4854 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4855 PetscValidType(mat,1); 4856 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4857 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4858 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4859 MatCheckPreallocated(mat,1); 4860 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4861 4862 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4863 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4864 PetscFunctionReturn(0); 4865 } 4866 4867 /*@ 4868 MatGetRowSum - Gets the sum of each row of the matrix 4869 4870 Logically or Neighborhood Collective on Mat and Vec 4871 4872 Input Parameters: 4873 . mat - the matrix 4874 4875 Output Parameter: 4876 . v - the vector for storing the sum of rows 4877 4878 Level: intermediate 4879 4880 Notes: 4881 This code is slow since it is not currently specialized for different formats 4882 4883 Concepts: matrices^getting row sums 4884 4885 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4886 @*/ 4887 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4888 { 4889 Vec ones; 4890 PetscErrorCode ierr; 4891 4892 PetscFunctionBegin; 4893 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4894 PetscValidType(mat,1); 4895 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4896 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4897 MatCheckPreallocated(mat,1); 4898 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4899 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4900 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4901 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4902 PetscFunctionReturn(0); 4903 } 4904 4905 /*@ 4906 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4907 4908 Collective on Mat 4909 4910 Input Parameter: 4911 + mat - the matrix to transpose 4912 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4913 4914 Output Parameters: 4915 . B - the transpose 4916 4917 Notes: 4918 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4919 4920 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4921 4922 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4923 4924 Level: intermediate 4925 4926 Concepts: matrices^transposing 4927 4928 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4929 @*/ 4930 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4931 { 4932 PetscErrorCode ierr; 4933 4934 PetscFunctionBegin; 4935 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4936 PetscValidType(mat,1); 4937 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4938 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4939 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4940 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4941 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4942 MatCheckPreallocated(mat,1); 4943 4944 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4945 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4946 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4947 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4948 PetscFunctionReturn(0); 4949 } 4950 4951 /*@ 4952 MatIsTranspose - Test whether a matrix is another one's transpose, 4953 or its own, in which case it tests symmetry. 4954 4955 Collective on Mat 4956 4957 Input Parameter: 4958 + A - the matrix to test 4959 - B - the matrix to test against, this can equal the first parameter 4960 4961 Output Parameters: 4962 . flg - the result 4963 4964 Notes: 4965 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4966 has a running time of the order of the number of nonzeros; the parallel 4967 test involves parallel copies of the block-offdiagonal parts of the matrix. 4968 4969 Level: intermediate 4970 4971 Concepts: matrices^transposing, matrix^symmetry 4972 4973 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4974 @*/ 4975 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4976 { 4977 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4978 4979 PetscFunctionBegin; 4980 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4981 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4982 PetscValidPointer(flg,3); 4983 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4984 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4985 *flg = PETSC_FALSE; 4986 if (f && g) { 4987 if (f == g) { 4988 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4989 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4990 } else { 4991 MatType mattype; 4992 if (!f) { 4993 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4994 } else { 4995 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4996 } 4997 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4998 } 4999 PetscFunctionReturn(0); 5000 } 5001 5002 /*@ 5003 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5004 5005 Collective on Mat 5006 5007 Input Parameter: 5008 + mat - the matrix to transpose and complex conjugate 5009 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 5010 5011 Output Parameters: 5012 . B - the Hermitian 5013 5014 Level: intermediate 5015 5016 Concepts: matrices^transposing, complex conjugatex 5017 5018 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 5019 @*/ 5020 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5021 { 5022 PetscErrorCode ierr; 5023 5024 PetscFunctionBegin; 5025 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 5026 #if defined(PETSC_USE_COMPLEX) 5027 ierr = MatConjugate(*B);CHKERRQ(ierr); 5028 #endif 5029 PetscFunctionReturn(0); 5030 } 5031 5032 /*@ 5033 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5034 5035 Collective on Mat 5036 5037 Input Parameter: 5038 + A - the matrix to test 5039 - B - the matrix to test against, this can equal the first parameter 5040 5041 Output Parameters: 5042 . flg - the result 5043 5044 Notes: 5045 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5046 has a running time of the order of the number of nonzeros; the parallel 5047 test involves parallel copies of the block-offdiagonal parts of the matrix. 5048 5049 Level: intermediate 5050 5051 Concepts: matrices^transposing, matrix^symmetry 5052 5053 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 5054 @*/ 5055 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5056 { 5057 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5058 5059 PetscFunctionBegin; 5060 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5061 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5062 PetscValidPointer(flg,3); 5063 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 5064 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 5065 if (f && g) { 5066 if (f==g) { 5067 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5068 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5069 } 5070 PetscFunctionReturn(0); 5071 } 5072 5073 /*@ 5074 MatPermute - Creates a new matrix with rows and columns permuted from the 5075 original. 5076 5077 Collective on Mat 5078 5079 Input Parameters: 5080 + mat - the matrix to permute 5081 . row - row permutation, each processor supplies only the permutation for its rows 5082 - col - column permutation, each processor supplies only the permutation for its columns 5083 5084 Output Parameters: 5085 . B - the permuted matrix 5086 5087 Level: advanced 5088 5089 Note: 5090 The index sets map from row/col of permuted matrix to row/col of original matrix. 5091 The index sets should be on the same communicator as Mat and have the same local sizes. 5092 5093 Concepts: matrices^permuting 5094 5095 .seealso: MatGetOrdering(), ISAllGather() 5096 5097 @*/ 5098 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5099 { 5100 PetscErrorCode ierr; 5101 5102 PetscFunctionBegin; 5103 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5104 PetscValidType(mat,1); 5105 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5106 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5107 PetscValidPointer(B,4); 5108 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5109 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5110 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5111 MatCheckPreallocated(mat,1); 5112 5113 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5114 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5115 PetscFunctionReturn(0); 5116 } 5117 5118 /*@ 5119 MatEqual - Compares two matrices. 5120 5121 Collective on Mat 5122 5123 Input Parameters: 5124 + A - the first matrix 5125 - B - the second matrix 5126 5127 Output Parameter: 5128 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5129 5130 Level: intermediate 5131 5132 Concepts: matrices^equality between 5133 @*/ 5134 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5135 { 5136 PetscErrorCode ierr; 5137 5138 PetscFunctionBegin; 5139 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5140 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5141 PetscValidType(A,1); 5142 PetscValidType(B,2); 5143 PetscValidIntPointer(flg,3); 5144 PetscCheckSameComm(A,1,B,2); 5145 MatCheckPreallocated(B,2); 5146 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5147 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5148 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); 5149 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5150 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5151 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); 5152 MatCheckPreallocated(A,1); 5153 5154 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5155 PetscFunctionReturn(0); 5156 } 5157 5158 /*@ 5159 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5160 matrices that are stored as vectors. Either of the two scaling 5161 matrices can be NULL. 5162 5163 Collective on Mat 5164 5165 Input Parameters: 5166 + mat - the matrix to be scaled 5167 . l - the left scaling vector (or NULL) 5168 - r - the right scaling vector (or NULL) 5169 5170 Notes: 5171 MatDiagonalScale() computes A = LAR, where 5172 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5173 The L scales the rows of the matrix, the R scales the columns of the matrix. 5174 5175 Level: intermediate 5176 5177 Concepts: matrices^diagonal scaling 5178 Concepts: diagonal scaling of matrices 5179 5180 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5181 @*/ 5182 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5183 { 5184 PetscErrorCode ierr; 5185 5186 PetscFunctionBegin; 5187 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5188 PetscValidType(mat,1); 5189 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5190 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5191 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5192 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5193 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5194 MatCheckPreallocated(mat,1); 5195 5196 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5197 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5198 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5199 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5200 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5201 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5202 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5203 } 5204 #endif 5205 PetscFunctionReturn(0); 5206 } 5207 5208 /*@ 5209 MatScale - Scales all elements of a matrix by a given number. 5210 5211 Logically Collective on Mat 5212 5213 Input Parameters: 5214 + mat - the matrix to be scaled 5215 - a - the scaling value 5216 5217 Output Parameter: 5218 . mat - the scaled matrix 5219 5220 Level: intermediate 5221 5222 Concepts: matrices^scaling all entries 5223 5224 .seealso: MatDiagonalScale() 5225 @*/ 5226 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5227 { 5228 PetscErrorCode ierr; 5229 5230 PetscFunctionBegin; 5231 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5232 PetscValidType(mat,1); 5233 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5234 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5235 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5236 PetscValidLogicalCollectiveScalar(mat,a,2); 5237 MatCheckPreallocated(mat,1); 5238 5239 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5240 if (a != (PetscScalar)1.0) { 5241 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5242 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5243 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5244 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5245 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5246 } 5247 #endif 5248 } 5249 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5250 PetscFunctionReturn(0); 5251 } 5252 5253 /*@ 5254 MatNorm - Calculates various norms of a matrix. 5255 5256 Collective on Mat 5257 5258 Input Parameters: 5259 + mat - the matrix 5260 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5261 5262 Output Parameters: 5263 . nrm - the resulting norm 5264 5265 Level: intermediate 5266 5267 Concepts: matrices^norm 5268 Concepts: norm^of matrix 5269 @*/ 5270 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5271 { 5272 PetscErrorCode ierr; 5273 5274 PetscFunctionBegin; 5275 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5276 PetscValidType(mat,1); 5277 PetscValidScalarPointer(nrm,3); 5278 5279 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5280 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5281 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5282 MatCheckPreallocated(mat,1); 5283 5284 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5285 PetscFunctionReturn(0); 5286 } 5287 5288 /* 5289 This variable is used to prevent counting of MatAssemblyBegin() that 5290 are called from within a MatAssemblyEnd(). 5291 */ 5292 static PetscInt MatAssemblyEnd_InUse = 0; 5293 /*@ 5294 MatAssemblyBegin - Begins assembling the matrix. This routine should 5295 be called after completing all calls to MatSetValues(). 5296 5297 Collective on Mat 5298 5299 Input Parameters: 5300 + mat - the matrix 5301 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5302 5303 Notes: 5304 MatSetValues() generally caches the values. The matrix is ready to 5305 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5306 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5307 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5308 using the matrix. 5309 5310 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5311 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 5312 a global collective operation requring all processes that share the matrix. 5313 5314 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5315 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5316 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5317 5318 Level: beginner 5319 5320 Concepts: matrices^assembling 5321 5322 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5323 @*/ 5324 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5325 { 5326 PetscErrorCode ierr; 5327 5328 PetscFunctionBegin; 5329 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5330 PetscValidType(mat,1); 5331 MatCheckPreallocated(mat,1); 5332 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5333 if (mat->assembled) { 5334 mat->was_assembled = PETSC_TRUE; 5335 mat->assembled = PETSC_FALSE; 5336 } 5337 if (!MatAssemblyEnd_InUse) { 5338 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5339 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5340 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5341 } else if (mat->ops->assemblybegin) { 5342 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5343 } 5344 PetscFunctionReturn(0); 5345 } 5346 5347 /*@ 5348 MatAssembled - Indicates if a matrix has been assembled and is ready for 5349 use; for example, in matrix-vector product. 5350 5351 Not Collective 5352 5353 Input Parameter: 5354 . mat - the matrix 5355 5356 Output Parameter: 5357 . assembled - PETSC_TRUE or PETSC_FALSE 5358 5359 Level: advanced 5360 5361 Concepts: matrices^assembled? 5362 5363 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5364 @*/ 5365 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5366 { 5367 PetscFunctionBegin; 5368 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5369 PetscValidPointer(assembled,2); 5370 *assembled = mat->assembled; 5371 PetscFunctionReturn(0); 5372 } 5373 5374 /*@ 5375 MatAssemblyEnd - Completes assembling the matrix. This routine should 5376 be called after MatAssemblyBegin(). 5377 5378 Collective on Mat 5379 5380 Input Parameters: 5381 + mat - the matrix 5382 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5383 5384 Options Database Keys: 5385 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5386 . -mat_view ::ascii_info_detail - Prints more detailed info 5387 . -mat_view - Prints matrix in ASCII format 5388 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5389 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5390 . -display <name> - Sets display name (default is host) 5391 . -draw_pause <sec> - Sets number of seconds to pause after display 5392 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5393 . -viewer_socket_machine <machine> - Machine to use for socket 5394 . -viewer_socket_port <port> - Port number to use for socket 5395 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5396 5397 Notes: 5398 MatSetValues() generally caches the values. The matrix is ready to 5399 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5400 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5401 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5402 using the matrix. 5403 5404 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5405 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5406 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5407 5408 Level: beginner 5409 5410 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5411 @*/ 5412 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5413 { 5414 PetscErrorCode ierr; 5415 static PetscInt inassm = 0; 5416 PetscBool flg = PETSC_FALSE; 5417 5418 PetscFunctionBegin; 5419 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5420 PetscValidType(mat,1); 5421 5422 inassm++; 5423 MatAssemblyEnd_InUse++; 5424 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5425 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5426 if (mat->ops->assemblyend) { 5427 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5428 } 5429 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5430 } else if (mat->ops->assemblyend) { 5431 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5432 } 5433 5434 /* Flush assembly is not a true assembly */ 5435 if (type != MAT_FLUSH_ASSEMBLY) { 5436 mat->assembled = PETSC_TRUE; mat->num_ass++; 5437 } 5438 mat->insertmode = NOT_SET_VALUES; 5439 MatAssemblyEnd_InUse--; 5440 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5441 if (!mat->symmetric_eternal) { 5442 mat->symmetric_set = PETSC_FALSE; 5443 mat->hermitian_set = PETSC_FALSE; 5444 mat->structurally_symmetric_set = PETSC_FALSE; 5445 } 5446 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5447 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5448 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5449 } 5450 #endif 5451 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5452 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5453 5454 if (mat->checksymmetryonassembly) { 5455 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5456 if (flg) { 5457 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5458 } else { 5459 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5460 } 5461 } 5462 if (mat->nullsp && mat->checknullspaceonassembly) { 5463 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5464 } 5465 } 5466 inassm--; 5467 PetscFunctionReturn(0); 5468 } 5469 5470 /*@ 5471 MatSetOption - Sets a parameter option for a matrix. Some options 5472 may be specific to certain storage formats. Some options 5473 determine how values will be inserted (or added). Sorted, 5474 row-oriented input will generally assemble the fastest. The default 5475 is row-oriented. 5476 5477 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5478 5479 Input Parameters: 5480 + mat - the matrix 5481 . option - the option, one of those listed below (and possibly others), 5482 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5483 5484 Options Describing Matrix Structure: 5485 + MAT_SPD - symmetric positive definite 5486 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5487 . MAT_HERMITIAN - transpose is the complex conjugation 5488 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5489 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5490 you set to be kept with all future use of the matrix 5491 including after MatAssemblyBegin/End() which could 5492 potentially change the symmetry structure, i.e. you 5493 KNOW the matrix will ALWAYS have the property you set. 5494 5495 5496 Options For Use with MatSetValues(): 5497 Insert a logically dense subblock, which can be 5498 . MAT_ROW_ORIENTED - row-oriented (default) 5499 5500 Note these options reflect the data you pass in with MatSetValues(); it has 5501 nothing to do with how the data is stored internally in the matrix 5502 data structure. 5503 5504 When (re)assembling a matrix, we can restrict the input for 5505 efficiency/debugging purposes. These options include: 5506 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5507 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5508 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5509 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5510 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5511 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5512 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5513 performance for very large process counts. 5514 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5515 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5516 functions, instead sending only neighbor messages. 5517 5518 Notes: 5519 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5520 5521 Some options are relevant only for particular matrix types and 5522 are thus ignored by others. Other options are not supported by 5523 certain matrix types and will generate an error message if set. 5524 5525 If using a Fortran 77 module to compute a matrix, one may need to 5526 use the column-oriented option (or convert to the row-oriented 5527 format). 5528 5529 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5530 that would generate a new entry in the nonzero structure is instead 5531 ignored. Thus, if memory has not alredy been allocated for this particular 5532 data, then the insertion is ignored. For dense matrices, in which 5533 the entire array is allocated, no entries are ever ignored. 5534 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5535 5536 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5537 that would generate a new entry in the nonzero structure instead produces 5538 an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5539 5540 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5541 that would generate a new entry that has not been preallocated will 5542 instead produce an error. (Currently supported for AIJ and BAIJ formats 5543 only.) This is a useful flag when debugging matrix memory preallocation. 5544 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5545 5546 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5547 other processors should be dropped, rather than stashed. 5548 This is useful if you know that the "owning" processor is also 5549 always generating the correct matrix entries, so that PETSc need 5550 not transfer duplicate entries generated on another processor. 5551 5552 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5553 searches during matrix assembly. When this flag is set, the hash table 5554 is created during the first Matrix Assembly. This hash table is 5555 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5556 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5557 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5558 supported by MATMPIBAIJ format only. 5559 5560 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5561 are kept in the nonzero structure 5562 5563 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5564 a zero location in the matrix 5565 5566 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5567 5568 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5569 zero row routines and thus improves performance for very large process counts. 5570 5571 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5572 part of the matrix (since they should match the upper triangular part). 5573 5574 Notes: 5575 Can only be called after MatSetSizes() and MatSetType() have been set. 5576 5577 Level: intermediate 5578 5579 Concepts: matrices^setting options 5580 5581 .seealso: MatOption, Mat 5582 5583 @*/ 5584 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5585 { 5586 PetscErrorCode ierr; 5587 5588 PetscFunctionBegin; 5589 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5590 PetscValidType(mat,1); 5591 if (op > 0) { 5592 PetscValidLogicalCollectiveEnum(mat,op,2); 5593 PetscValidLogicalCollectiveBool(mat,flg,3); 5594 } 5595 5596 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); 5597 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()"); 5598 5599 switch (op) { 5600 case MAT_NO_OFF_PROC_ENTRIES: 5601 mat->nooffprocentries = flg; 5602 PetscFunctionReturn(0); 5603 break; 5604 case MAT_SUBSET_OFF_PROC_ENTRIES: 5605 mat->subsetoffprocentries = flg; 5606 PetscFunctionReturn(0); 5607 case MAT_NO_OFF_PROC_ZERO_ROWS: 5608 mat->nooffproczerorows = flg; 5609 PetscFunctionReturn(0); 5610 break; 5611 case MAT_SPD: 5612 mat->spd_set = PETSC_TRUE; 5613 mat->spd = flg; 5614 if (flg) { 5615 mat->symmetric = PETSC_TRUE; 5616 mat->structurally_symmetric = PETSC_TRUE; 5617 mat->symmetric_set = PETSC_TRUE; 5618 mat->structurally_symmetric_set = PETSC_TRUE; 5619 } 5620 break; 5621 case MAT_SYMMETRIC: 5622 mat->symmetric = flg; 5623 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5624 mat->symmetric_set = PETSC_TRUE; 5625 mat->structurally_symmetric_set = flg; 5626 #if !defined(PETSC_USE_COMPLEX) 5627 mat->hermitian = flg; 5628 mat->hermitian_set = PETSC_TRUE; 5629 #endif 5630 break; 5631 case MAT_HERMITIAN: 5632 mat->hermitian = flg; 5633 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5634 mat->hermitian_set = PETSC_TRUE; 5635 mat->structurally_symmetric_set = flg; 5636 #if !defined(PETSC_USE_COMPLEX) 5637 mat->symmetric = flg; 5638 mat->symmetric_set = PETSC_TRUE; 5639 #endif 5640 break; 5641 case MAT_STRUCTURALLY_SYMMETRIC: 5642 mat->structurally_symmetric = flg; 5643 mat->structurally_symmetric_set = PETSC_TRUE; 5644 break; 5645 case MAT_SYMMETRY_ETERNAL: 5646 mat->symmetric_eternal = flg; 5647 break; 5648 case MAT_STRUCTURE_ONLY: 5649 mat->structure_only = flg; 5650 break; 5651 default: 5652 break; 5653 } 5654 if (mat->ops->setoption) { 5655 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5656 } 5657 PetscFunctionReturn(0); 5658 } 5659 5660 /*@ 5661 MatGetOption - Gets a parameter option that has been set for a matrix. 5662 5663 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5664 5665 Input Parameters: 5666 + mat - the matrix 5667 - option - the option, this only responds to certain options, check the code for which ones 5668 5669 Output Parameter: 5670 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5671 5672 Notes: 5673 Can only be called after MatSetSizes() and MatSetType() have been set. 5674 5675 Level: intermediate 5676 5677 Concepts: matrices^setting options 5678 5679 .seealso: MatOption, MatSetOption() 5680 5681 @*/ 5682 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5683 { 5684 PetscFunctionBegin; 5685 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5686 PetscValidType(mat,1); 5687 5688 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); 5689 if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()"); 5690 5691 switch (op) { 5692 case MAT_NO_OFF_PROC_ENTRIES: 5693 *flg = mat->nooffprocentries; 5694 break; 5695 case MAT_NO_OFF_PROC_ZERO_ROWS: 5696 *flg = mat->nooffproczerorows; 5697 break; 5698 case MAT_SYMMETRIC: 5699 *flg = mat->symmetric; 5700 break; 5701 case MAT_HERMITIAN: 5702 *flg = mat->hermitian; 5703 break; 5704 case MAT_STRUCTURALLY_SYMMETRIC: 5705 *flg = mat->structurally_symmetric; 5706 break; 5707 case MAT_SYMMETRY_ETERNAL: 5708 *flg = mat->symmetric_eternal; 5709 break; 5710 case MAT_SPD: 5711 *flg = mat->spd; 5712 break; 5713 default: 5714 break; 5715 } 5716 PetscFunctionReturn(0); 5717 } 5718 5719 /*@ 5720 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5721 this routine retains the old nonzero structure. 5722 5723 Logically Collective on Mat 5724 5725 Input Parameters: 5726 . mat - the matrix 5727 5728 Level: intermediate 5729 5730 Notes: 5731 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. 5732 See the Performance chapter of the users manual for information on preallocating matrices. 5733 5734 Concepts: matrices^zeroing 5735 5736 .seealso: MatZeroRows() 5737 @*/ 5738 PetscErrorCode MatZeroEntries(Mat mat) 5739 { 5740 PetscErrorCode ierr; 5741 5742 PetscFunctionBegin; 5743 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5744 PetscValidType(mat,1); 5745 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5746 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"); 5747 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5748 MatCheckPreallocated(mat,1); 5749 5750 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5751 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5752 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5753 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5754 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5755 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5756 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5757 } 5758 #endif 5759 PetscFunctionReturn(0); 5760 } 5761 5762 /*@ 5763 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5764 of a set of rows and columns of a matrix. 5765 5766 Collective on Mat 5767 5768 Input Parameters: 5769 + mat - the matrix 5770 . numRows - the number of rows to remove 5771 . rows - the global row indices 5772 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5773 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5774 - b - optional vector of right hand side, that will be adjusted by provided solution 5775 5776 Notes: 5777 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5778 5779 The user can set a value in the diagonal entry (or for the AIJ and 5780 row formats can optionally remove the main diagonal entry from the 5781 nonzero structure as well, by passing 0.0 as the final argument). 5782 5783 For the parallel case, all processes that share the matrix (i.e., 5784 those in the communicator used for matrix creation) MUST call this 5785 routine, regardless of whether any rows being zeroed are owned by 5786 them. 5787 5788 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5789 list only rows local to itself). 5790 5791 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5792 5793 Level: intermediate 5794 5795 Concepts: matrices^zeroing rows 5796 5797 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5798 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5799 @*/ 5800 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5801 { 5802 PetscErrorCode ierr; 5803 5804 PetscFunctionBegin; 5805 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5806 PetscValidType(mat,1); 5807 if (numRows) PetscValidIntPointer(rows,3); 5808 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5809 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5810 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5811 MatCheckPreallocated(mat,1); 5812 5813 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5814 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5815 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5816 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5817 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5818 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5819 } 5820 #endif 5821 PetscFunctionReturn(0); 5822 } 5823 5824 /*@ 5825 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5826 of a set of rows and columns of a matrix. 5827 5828 Collective on Mat 5829 5830 Input Parameters: 5831 + mat - the matrix 5832 . is - the rows to zero 5833 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5834 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5835 - b - optional vector of right hand side, that will be adjusted by provided solution 5836 5837 Notes: 5838 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5839 5840 The user can set a value in the diagonal entry (or for the AIJ and 5841 row formats can optionally remove the main diagonal entry from the 5842 nonzero structure as well, by passing 0.0 as the final argument). 5843 5844 For the parallel case, all processes that share the matrix (i.e., 5845 those in the communicator used for matrix creation) MUST call this 5846 routine, regardless of whether any rows being zeroed are owned by 5847 them. 5848 5849 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5850 list only rows local to itself). 5851 5852 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5853 5854 Level: intermediate 5855 5856 Concepts: matrices^zeroing rows 5857 5858 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5859 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5860 @*/ 5861 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5862 { 5863 PetscErrorCode ierr; 5864 PetscInt numRows; 5865 const PetscInt *rows; 5866 5867 PetscFunctionBegin; 5868 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5869 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5870 PetscValidType(mat,1); 5871 PetscValidType(is,2); 5872 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5873 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5874 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5875 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5876 PetscFunctionReturn(0); 5877 } 5878 5879 /*@ 5880 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5881 of a set of rows of a matrix. 5882 5883 Collective on Mat 5884 5885 Input Parameters: 5886 + mat - the matrix 5887 . numRows - the number of rows to remove 5888 . rows - the global row indices 5889 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5890 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5891 - b - optional vector of right hand side, that will be adjusted by provided solution 5892 5893 Notes: 5894 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5895 but does not release memory. For the dense and block diagonal 5896 formats this does not alter the nonzero structure. 5897 5898 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5899 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5900 merely zeroed. 5901 5902 The user can set a value in the diagonal entry (or for the AIJ and 5903 row formats can optionally remove the main diagonal entry from the 5904 nonzero structure as well, by passing 0.0 as the final argument). 5905 5906 For the parallel case, all processes that share the matrix (i.e., 5907 those in the communicator used for matrix creation) MUST call this 5908 routine, regardless of whether any rows being zeroed are owned by 5909 them. 5910 5911 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5912 list only rows local to itself). 5913 5914 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5915 owns that are to be zeroed. This saves a global synchronization in the implementation. 5916 5917 Level: intermediate 5918 5919 Concepts: matrices^zeroing rows 5920 5921 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5922 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5923 @*/ 5924 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5925 { 5926 PetscErrorCode ierr; 5927 5928 PetscFunctionBegin; 5929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5930 PetscValidType(mat,1); 5931 if (numRows) PetscValidIntPointer(rows,3); 5932 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5933 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5934 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5935 MatCheckPreallocated(mat,1); 5936 5937 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5938 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5939 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5940 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5941 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5942 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5943 } 5944 #endif 5945 PetscFunctionReturn(0); 5946 } 5947 5948 /*@ 5949 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5950 of a set of rows of a matrix. 5951 5952 Collective on Mat 5953 5954 Input Parameters: 5955 + mat - the matrix 5956 . is - index set of rows to remove 5957 . diag - value put in all diagonals of eliminated rows 5958 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5959 - b - optional vector of right hand side, that will be adjusted by provided solution 5960 5961 Notes: 5962 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5963 but does not release memory. For the dense and block diagonal 5964 formats this does not alter the nonzero structure. 5965 5966 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5967 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5968 merely zeroed. 5969 5970 The user can set a value in the diagonal entry (or for the AIJ and 5971 row formats can optionally remove the main diagonal entry from the 5972 nonzero structure as well, by passing 0.0 as the final argument). 5973 5974 For the parallel case, all processes that share the matrix (i.e., 5975 those in the communicator used for matrix creation) MUST call this 5976 routine, regardless of whether any rows being zeroed are owned by 5977 them. 5978 5979 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5980 list only rows local to itself). 5981 5982 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5983 owns that are to be zeroed. This saves a global synchronization in the implementation. 5984 5985 Level: intermediate 5986 5987 Concepts: matrices^zeroing rows 5988 5989 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5990 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5991 @*/ 5992 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5993 { 5994 PetscInt numRows; 5995 const PetscInt *rows; 5996 PetscErrorCode ierr; 5997 5998 PetscFunctionBegin; 5999 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6000 PetscValidType(mat,1); 6001 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6002 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6003 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6004 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6005 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6006 PetscFunctionReturn(0); 6007 } 6008 6009 /*@ 6010 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6011 of a set of rows of a matrix. These rows must be local to the process. 6012 6013 Collective on Mat 6014 6015 Input Parameters: 6016 + mat - the matrix 6017 . numRows - the number of rows to remove 6018 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6019 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6020 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6021 - b - optional vector of right hand side, that will be adjusted by provided solution 6022 6023 Notes: 6024 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6025 but does not release memory. For the dense and block diagonal 6026 formats this does not alter the nonzero structure. 6027 6028 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6029 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6030 merely zeroed. 6031 6032 The user can set a value in the diagonal entry (or for the AIJ and 6033 row formats can optionally remove the main diagonal entry from the 6034 nonzero structure as well, by passing 0.0 as the final argument). 6035 6036 For the parallel case, all processes that share the matrix (i.e., 6037 those in the communicator used for matrix creation) MUST call this 6038 routine, regardless of whether any rows being zeroed are owned by 6039 them. 6040 6041 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6042 list only rows local to itself). 6043 6044 The grid coordinates are across the entire grid, not just the local portion 6045 6046 In Fortran idxm and idxn should be declared as 6047 $ MatStencil idxm(4,m) 6048 and the values inserted using 6049 $ idxm(MatStencil_i,1) = i 6050 $ idxm(MatStencil_j,1) = j 6051 $ idxm(MatStencil_k,1) = k 6052 $ idxm(MatStencil_c,1) = c 6053 etc 6054 6055 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6056 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6057 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6058 DM_BOUNDARY_PERIODIC boundary type. 6059 6060 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 6061 a single value per point) you can skip filling those indices. 6062 6063 Level: intermediate 6064 6065 Concepts: matrices^zeroing rows 6066 6067 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6068 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6069 @*/ 6070 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6071 { 6072 PetscInt dim = mat->stencil.dim; 6073 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6074 PetscInt *dims = mat->stencil.dims+1; 6075 PetscInt *starts = mat->stencil.starts; 6076 PetscInt *dxm = (PetscInt*) rows; 6077 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6078 PetscErrorCode ierr; 6079 6080 PetscFunctionBegin; 6081 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6082 PetscValidType(mat,1); 6083 if (numRows) PetscValidIntPointer(rows,3); 6084 6085 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6086 for (i = 0; i < numRows; ++i) { 6087 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6088 for (j = 0; j < 3-sdim; ++j) dxm++; 6089 /* Local index in X dir */ 6090 tmp = *dxm++ - starts[0]; 6091 /* Loop over remaining dimensions */ 6092 for (j = 0; j < dim-1; ++j) { 6093 /* If nonlocal, set index to be negative */ 6094 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6095 /* Update local index */ 6096 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6097 } 6098 /* Skip component slot if necessary */ 6099 if (mat->stencil.noc) dxm++; 6100 /* Local row number */ 6101 if (tmp >= 0) { 6102 jdxm[numNewRows++] = tmp; 6103 } 6104 } 6105 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6106 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6107 PetscFunctionReturn(0); 6108 } 6109 6110 /*@ 6111 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6112 of a set of rows and columns of a matrix. 6113 6114 Collective on Mat 6115 6116 Input Parameters: 6117 + mat - the matrix 6118 . numRows - the number of rows/columns to remove 6119 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6120 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6121 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6122 - b - optional vector of right hand side, that will be adjusted by provided solution 6123 6124 Notes: 6125 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6126 but does not release memory. For the dense and block diagonal 6127 formats this does not alter the nonzero structure. 6128 6129 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6130 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6131 merely zeroed. 6132 6133 The user can set a value in the diagonal entry (or for the AIJ and 6134 row formats can optionally remove the main diagonal entry from the 6135 nonzero structure as well, by passing 0.0 as the final argument). 6136 6137 For the parallel case, all processes that share the matrix (i.e., 6138 those in the communicator used for matrix creation) MUST call this 6139 routine, regardless of whether any rows being zeroed are owned by 6140 them. 6141 6142 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6143 list only rows local to itself, but the row/column numbers are given in local numbering). 6144 6145 The grid coordinates are across the entire grid, not just the local portion 6146 6147 In Fortran idxm and idxn should be declared as 6148 $ MatStencil idxm(4,m) 6149 and the values inserted using 6150 $ idxm(MatStencil_i,1) = i 6151 $ idxm(MatStencil_j,1) = j 6152 $ idxm(MatStencil_k,1) = k 6153 $ idxm(MatStencil_c,1) = c 6154 etc 6155 6156 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6157 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6158 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6159 DM_BOUNDARY_PERIODIC boundary type. 6160 6161 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 6162 a single value per point) you can skip filling those indices. 6163 6164 Level: intermediate 6165 6166 Concepts: matrices^zeroing rows 6167 6168 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6169 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6170 @*/ 6171 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6172 { 6173 PetscInt dim = mat->stencil.dim; 6174 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6175 PetscInt *dims = mat->stencil.dims+1; 6176 PetscInt *starts = mat->stencil.starts; 6177 PetscInt *dxm = (PetscInt*) rows; 6178 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6179 PetscErrorCode ierr; 6180 6181 PetscFunctionBegin; 6182 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6183 PetscValidType(mat,1); 6184 if (numRows) PetscValidIntPointer(rows,3); 6185 6186 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6187 for (i = 0; i < numRows; ++i) { 6188 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6189 for (j = 0; j < 3-sdim; ++j) dxm++; 6190 /* Local index in X dir */ 6191 tmp = *dxm++ - starts[0]; 6192 /* Loop over remaining dimensions */ 6193 for (j = 0; j < dim-1; ++j) { 6194 /* If nonlocal, set index to be negative */ 6195 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6196 /* Update local index */ 6197 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6198 } 6199 /* Skip component slot if necessary */ 6200 if (mat->stencil.noc) dxm++; 6201 /* Local row number */ 6202 if (tmp >= 0) { 6203 jdxm[numNewRows++] = tmp; 6204 } 6205 } 6206 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6207 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6208 PetscFunctionReturn(0); 6209 } 6210 6211 /*@C 6212 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6213 of a set of rows of a matrix; using local numbering of rows. 6214 6215 Collective on Mat 6216 6217 Input Parameters: 6218 + mat - the matrix 6219 . numRows - the number of rows to remove 6220 . rows - the global row indices 6221 . diag - value put in all diagonals of eliminated rows 6222 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6223 - b - optional vector of right hand side, that will be adjusted by provided solution 6224 6225 Notes: 6226 Before calling MatZeroRowsLocal(), the user must first set the 6227 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6228 6229 For the AIJ matrix formats this removes the old nonzero structure, 6230 but does not release memory. For the dense and block diagonal 6231 formats this does not alter the nonzero structure. 6232 6233 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6234 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6235 merely zeroed. 6236 6237 The user can set a value in the diagonal entry (or for the AIJ and 6238 row formats can optionally remove the main diagonal entry from the 6239 nonzero structure as well, by passing 0.0 as the final argument). 6240 6241 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6242 owns that are to be zeroed. This saves a global synchronization in the implementation. 6243 6244 Level: intermediate 6245 6246 Concepts: matrices^zeroing 6247 6248 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6249 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6250 @*/ 6251 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6252 { 6253 PetscErrorCode ierr; 6254 6255 PetscFunctionBegin; 6256 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6257 PetscValidType(mat,1); 6258 if (numRows) PetscValidIntPointer(rows,3); 6259 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6260 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6261 MatCheckPreallocated(mat,1); 6262 6263 if (mat->ops->zerorowslocal) { 6264 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6265 } else { 6266 IS is, newis; 6267 const PetscInt *newRows; 6268 6269 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6270 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6271 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6272 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6273 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6274 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6275 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6276 ierr = ISDestroy(&is);CHKERRQ(ierr); 6277 } 6278 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6279 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6280 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6281 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6282 } 6283 #endif 6284 PetscFunctionReturn(0); 6285 } 6286 6287 /*@ 6288 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6289 of a set of rows of a matrix; using local numbering of rows. 6290 6291 Collective on Mat 6292 6293 Input Parameters: 6294 + mat - the matrix 6295 . is - index set of rows to remove 6296 . diag - value put in all diagonals of eliminated rows 6297 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6298 - b - optional vector of right hand side, that will be adjusted by provided solution 6299 6300 Notes: 6301 Before calling MatZeroRowsLocalIS(), the user must first set the 6302 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6303 6304 For the AIJ matrix formats this removes the old nonzero structure, 6305 but does not release memory. For the dense and block diagonal 6306 formats this does not alter the nonzero structure. 6307 6308 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6309 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6310 merely zeroed. 6311 6312 The user can set a value in the diagonal entry (or for the AIJ and 6313 row formats can optionally remove the main diagonal entry from the 6314 nonzero structure as well, by passing 0.0 as the final argument). 6315 6316 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6317 owns that are to be zeroed. This saves a global synchronization in the implementation. 6318 6319 Level: intermediate 6320 6321 Concepts: matrices^zeroing 6322 6323 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6324 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6325 @*/ 6326 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6327 { 6328 PetscErrorCode ierr; 6329 PetscInt numRows; 6330 const PetscInt *rows; 6331 6332 PetscFunctionBegin; 6333 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6334 PetscValidType(mat,1); 6335 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6336 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6337 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6338 MatCheckPreallocated(mat,1); 6339 6340 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6341 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6342 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6343 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6344 PetscFunctionReturn(0); 6345 } 6346 6347 /*@ 6348 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6349 of a set of rows and columns of a matrix; using local numbering of rows. 6350 6351 Collective on Mat 6352 6353 Input Parameters: 6354 + mat - the matrix 6355 . numRows - the number of rows to remove 6356 . rows - the global row indices 6357 . diag - value put in all diagonals of eliminated rows 6358 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6359 - b - optional vector of right hand side, that will be adjusted by provided solution 6360 6361 Notes: 6362 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6363 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6364 6365 The user can set a value in the diagonal entry (or for the AIJ and 6366 row formats can optionally remove the main diagonal entry from the 6367 nonzero structure as well, by passing 0.0 as the final argument). 6368 6369 Level: intermediate 6370 6371 Concepts: matrices^zeroing 6372 6373 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6374 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6375 @*/ 6376 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6377 { 6378 PetscErrorCode ierr; 6379 IS is, newis; 6380 const PetscInt *newRows; 6381 6382 PetscFunctionBegin; 6383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6384 PetscValidType(mat,1); 6385 if (numRows) PetscValidIntPointer(rows,3); 6386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6388 MatCheckPreallocated(mat,1); 6389 6390 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6391 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6392 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6393 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6394 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6395 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6396 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6397 ierr = ISDestroy(&is);CHKERRQ(ierr); 6398 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6399 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6400 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6401 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6402 } 6403 #endif 6404 PetscFunctionReturn(0); 6405 } 6406 6407 /*@ 6408 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6409 of a set of rows and columns of a matrix; using local numbering of rows. 6410 6411 Collective on Mat 6412 6413 Input Parameters: 6414 + mat - the matrix 6415 . is - index set of rows to remove 6416 . diag - value put in all diagonals of eliminated rows 6417 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6418 - b - optional vector of right hand side, that will be adjusted by provided solution 6419 6420 Notes: 6421 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6422 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6423 6424 The user can set a value in the diagonal entry (or for the AIJ and 6425 row formats can optionally remove the main diagonal entry from the 6426 nonzero structure as well, by passing 0.0 as the final argument). 6427 6428 Level: intermediate 6429 6430 Concepts: matrices^zeroing 6431 6432 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6433 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6434 @*/ 6435 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6436 { 6437 PetscErrorCode ierr; 6438 PetscInt numRows; 6439 const PetscInt *rows; 6440 6441 PetscFunctionBegin; 6442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6443 PetscValidType(mat,1); 6444 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6445 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6446 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6447 MatCheckPreallocated(mat,1); 6448 6449 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6450 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6451 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6452 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6453 PetscFunctionReturn(0); 6454 } 6455 6456 /*@C 6457 MatGetSize - Returns the numbers of rows and columns in a matrix. 6458 6459 Not Collective 6460 6461 Input Parameter: 6462 . mat - the matrix 6463 6464 Output Parameters: 6465 + m - the number of global rows 6466 - n - the number of global columns 6467 6468 Note: both output parameters can be NULL on input. 6469 6470 Level: beginner 6471 6472 Concepts: matrices^size 6473 6474 .seealso: MatGetLocalSize() 6475 @*/ 6476 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6477 { 6478 PetscFunctionBegin; 6479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6480 if (m) *m = mat->rmap->N; 6481 if (n) *n = mat->cmap->N; 6482 PetscFunctionReturn(0); 6483 } 6484 6485 /*@C 6486 MatGetLocalSize - Returns the number of rows and columns in a matrix 6487 stored locally. This information may be implementation dependent, so 6488 use with care. 6489 6490 Not Collective 6491 6492 Input Parameters: 6493 . mat - the matrix 6494 6495 Output Parameters: 6496 + m - the number of local rows 6497 - n - the number of local columns 6498 6499 Note: both output parameters can be NULL on input. 6500 6501 Level: beginner 6502 6503 Concepts: matrices^local size 6504 6505 .seealso: MatGetSize() 6506 @*/ 6507 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6508 { 6509 PetscFunctionBegin; 6510 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6511 if (m) PetscValidIntPointer(m,2); 6512 if (n) PetscValidIntPointer(n,3); 6513 if (m) *m = mat->rmap->n; 6514 if (n) *n = mat->cmap->n; 6515 PetscFunctionReturn(0); 6516 } 6517 6518 /*@C 6519 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6520 this processor. (The columns of the "diagonal block") 6521 6522 Not Collective, unless matrix has not been allocated, then collective on Mat 6523 6524 Input Parameters: 6525 . mat - the matrix 6526 6527 Output Parameters: 6528 + m - the global index of the first local column 6529 - n - one more than the global index of the last local column 6530 6531 Notes: 6532 both output parameters can be NULL on input. 6533 6534 Level: developer 6535 6536 Concepts: matrices^column ownership 6537 6538 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6539 6540 @*/ 6541 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6542 { 6543 PetscFunctionBegin; 6544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6545 PetscValidType(mat,1); 6546 if (m) PetscValidIntPointer(m,2); 6547 if (n) PetscValidIntPointer(n,3); 6548 MatCheckPreallocated(mat,1); 6549 if (m) *m = mat->cmap->rstart; 6550 if (n) *n = mat->cmap->rend; 6551 PetscFunctionReturn(0); 6552 } 6553 6554 /*@C 6555 MatGetOwnershipRange - Returns the range of matrix rows owned by 6556 this processor, assuming that the matrix is laid out with the first 6557 n1 rows on the first processor, the next n2 rows on the second, etc. 6558 For certain parallel layouts this range may not be well defined. 6559 6560 Not Collective 6561 6562 Input Parameters: 6563 . mat - the matrix 6564 6565 Output Parameters: 6566 + m - the global index of the first local row 6567 - n - one more than the global index of the last local row 6568 6569 Note: Both output parameters can be NULL on input. 6570 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6571 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6572 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6573 6574 Level: beginner 6575 6576 Concepts: matrices^row ownership 6577 6578 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6579 6580 @*/ 6581 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6582 { 6583 PetscFunctionBegin; 6584 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6585 PetscValidType(mat,1); 6586 if (m) PetscValidIntPointer(m,2); 6587 if (n) PetscValidIntPointer(n,3); 6588 MatCheckPreallocated(mat,1); 6589 if (m) *m = mat->rmap->rstart; 6590 if (n) *n = mat->rmap->rend; 6591 PetscFunctionReturn(0); 6592 } 6593 6594 /*@C 6595 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6596 each process 6597 6598 Not Collective, unless matrix has not been allocated, then collective on Mat 6599 6600 Input Parameters: 6601 . mat - the matrix 6602 6603 Output Parameters: 6604 . ranges - start of each processors portion plus one more than the total length at the end 6605 6606 Level: beginner 6607 6608 Concepts: matrices^row ownership 6609 6610 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6611 6612 @*/ 6613 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6614 { 6615 PetscErrorCode ierr; 6616 6617 PetscFunctionBegin; 6618 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6619 PetscValidType(mat,1); 6620 MatCheckPreallocated(mat,1); 6621 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6622 PetscFunctionReturn(0); 6623 } 6624 6625 /*@C 6626 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6627 this processor. (The columns of the "diagonal blocks" for each process) 6628 6629 Not Collective, unless matrix has not been allocated, then collective on Mat 6630 6631 Input Parameters: 6632 . mat - the matrix 6633 6634 Output Parameters: 6635 . ranges - start of each processors portion plus one more then the total length at the end 6636 6637 Level: beginner 6638 6639 Concepts: matrices^column ownership 6640 6641 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6642 6643 @*/ 6644 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6645 { 6646 PetscErrorCode ierr; 6647 6648 PetscFunctionBegin; 6649 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6650 PetscValidType(mat,1); 6651 MatCheckPreallocated(mat,1); 6652 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6653 PetscFunctionReturn(0); 6654 } 6655 6656 /*@C 6657 MatGetOwnershipIS - Get row and column ownership as index sets 6658 6659 Not Collective 6660 6661 Input Arguments: 6662 . A - matrix of type Elemental 6663 6664 Output Arguments: 6665 + rows - rows in which this process owns elements 6666 . cols - columns in which this process owns elements 6667 6668 Level: intermediate 6669 6670 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6671 @*/ 6672 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6673 { 6674 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6675 6676 PetscFunctionBegin; 6677 MatCheckPreallocated(A,1); 6678 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6679 if (f) { 6680 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6681 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6682 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6683 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6684 } 6685 PetscFunctionReturn(0); 6686 } 6687 6688 /*@C 6689 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6690 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6691 to complete the factorization. 6692 6693 Collective on Mat 6694 6695 Input Parameters: 6696 + mat - the matrix 6697 . row - row permutation 6698 . column - column permutation 6699 - info - structure containing 6700 $ levels - number of levels of fill. 6701 $ expected fill - as ratio of original fill. 6702 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6703 missing diagonal entries) 6704 6705 Output Parameters: 6706 . fact - new matrix that has been symbolically factored 6707 6708 Notes: 6709 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6710 6711 Most users should employ the simplified KSP interface for linear solvers 6712 instead of working directly with matrix algebra routines such as this. 6713 See, e.g., KSPCreate(). 6714 6715 Level: developer 6716 6717 Concepts: matrices^symbolic LU factorization 6718 Concepts: matrices^factorization 6719 Concepts: LU^symbolic factorization 6720 6721 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6722 MatGetOrdering(), MatFactorInfo 6723 6724 Note: this uses the definition of level of fill as in Y. Saad, 2003 6725 6726 Developer Note: fortran interface is not autogenerated as the f90 6727 interface defintion cannot be generated correctly [due to MatFactorInfo] 6728 6729 References: 6730 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6731 @*/ 6732 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6733 { 6734 PetscErrorCode ierr; 6735 6736 PetscFunctionBegin; 6737 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6738 PetscValidType(mat,1); 6739 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6740 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6741 PetscValidPointer(info,4); 6742 PetscValidPointer(fact,5); 6743 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6744 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6745 if (!(fact)->ops->ilufactorsymbolic) { 6746 MatSolverType spackage; 6747 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6748 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6749 } 6750 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6751 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6752 MatCheckPreallocated(mat,2); 6753 6754 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6755 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6756 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6757 PetscFunctionReturn(0); 6758 } 6759 6760 /*@C 6761 MatICCFactorSymbolic - Performs symbolic incomplete 6762 Cholesky factorization for a symmetric matrix. Use 6763 MatCholeskyFactorNumeric() to complete the factorization. 6764 6765 Collective on Mat 6766 6767 Input Parameters: 6768 + mat - the matrix 6769 . perm - row and column permutation 6770 - info - structure containing 6771 $ levels - number of levels of fill. 6772 $ expected fill - as ratio of original fill. 6773 6774 Output Parameter: 6775 . fact - the factored matrix 6776 6777 Notes: 6778 Most users should employ the KSP interface for linear solvers 6779 instead of working directly with matrix algebra routines such as this. 6780 See, e.g., KSPCreate(). 6781 6782 Level: developer 6783 6784 Concepts: matrices^symbolic incomplete Cholesky factorization 6785 Concepts: matrices^factorization 6786 Concepts: Cholsky^symbolic factorization 6787 6788 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6789 6790 Note: this uses the definition of level of fill as in Y. Saad, 2003 6791 6792 Developer Note: fortran interface is not autogenerated as the f90 6793 interface defintion cannot be generated correctly [due to MatFactorInfo] 6794 6795 References: 6796 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6797 @*/ 6798 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6799 { 6800 PetscErrorCode ierr; 6801 6802 PetscFunctionBegin; 6803 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6804 PetscValidType(mat,1); 6805 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6806 PetscValidPointer(info,3); 6807 PetscValidPointer(fact,4); 6808 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6809 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6810 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6811 if (!(fact)->ops->iccfactorsymbolic) { 6812 MatSolverType spackage; 6813 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6814 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6815 } 6816 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6817 MatCheckPreallocated(mat,2); 6818 6819 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6820 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6821 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6822 PetscFunctionReturn(0); 6823 } 6824 6825 /*@C 6826 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6827 points to an array of valid matrices, they may be reused to store the new 6828 submatrices. 6829 6830 Collective on Mat 6831 6832 Input Parameters: 6833 + mat - the matrix 6834 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6835 . irow, icol - index sets of rows and columns to extract 6836 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6837 6838 Output Parameter: 6839 . submat - the array of submatrices 6840 6841 Notes: 6842 MatCreateSubMatrices() can extract ONLY sequential submatrices 6843 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6844 to extract a parallel submatrix. 6845 6846 Some matrix types place restrictions on the row and column 6847 indices, such as that they be sorted or that they be equal to each other. 6848 6849 The index sets may not have duplicate entries. 6850 6851 When extracting submatrices from a parallel matrix, each processor can 6852 form a different submatrix by setting the rows and columns of its 6853 individual index sets according to the local submatrix desired. 6854 6855 When finished using the submatrices, the user should destroy 6856 them with MatDestroySubMatrices(). 6857 6858 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6859 original matrix has not changed from that last call to MatCreateSubMatrices(). 6860 6861 This routine creates the matrices in submat; you should NOT create them before 6862 calling it. It also allocates the array of matrix pointers submat. 6863 6864 For BAIJ matrices the index sets must respect the block structure, that is if they 6865 request one row/column in a block, they must request all rows/columns that are in 6866 that block. For example, if the block size is 2 you cannot request just row 0 and 6867 column 0. 6868 6869 Fortran Note: 6870 The Fortran interface is slightly different from that given below; it 6871 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6872 6873 Level: advanced 6874 6875 Concepts: matrices^accessing submatrices 6876 Concepts: submatrices 6877 6878 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6879 @*/ 6880 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6881 { 6882 PetscErrorCode ierr; 6883 PetscInt i; 6884 PetscBool eq; 6885 6886 PetscFunctionBegin; 6887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6888 PetscValidType(mat,1); 6889 if (n) { 6890 PetscValidPointer(irow,3); 6891 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6892 PetscValidPointer(icol,4); 6893 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6894 } 6895 PetscValidPointer(submat,6); 6896 if (n && scall == MAT_REUSE_MATRIX) { 6897 PetscValidPointer(*submat,6); 6898 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6899 } 6900 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6901 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6902 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6903 MatCheckPreallocated(mat,1); 6904 6905 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6906 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6907 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6908 for (i=0; i<n; i++) { 6909 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6910 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6911 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6912 if (eq) { 6913 if (mat->symmetric) { 6914 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6915 } else if (mat->hermitian) { 6916 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6917 } else if (mat->structurally_symmetric) { 6918 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6919 } 6920 } 6921 } 6922 } 6923 PetscFunctionReturn(0); 6924 } 6925 6926 /*@C 6927 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6928 6929 Collective on Mat 6930 6931 Input Parameters: 6932 + mat - the matrix 6933 . n - the number of submatrixes to be extracted 6934 . irow, icol - index sets of rows and columns to extract 6935 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6936 6937 Output Parameter: 6938 . submat - the array of submatrices 6939 6940 Level: advanced 6941 6942 Concepts: matrices^accessing submatrices 6943 Concepts: submatrices 6944 6945 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6946 @*/ 6947 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6948 { 6949 PetscErrorCode ierr; 6950 PetscInt i; 6951 PetscBool eq; 6952 6953 PetscFunctionBegin; 6954 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6955 PetscValidType(mat,1); 6956 if (n) { 6957 PetscValidPointer(irow,3); 6958 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6959 PetscValidPointer(icol,4); 6960 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6961 } 6962 PetscValidPointer(submat,6); 6963 if (n && scall == MAT_REUSE_MATRIX) { 6964 PetscValidPointer(*submat,6); 6965 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6966 } 6967 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6968 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6969 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6970 MatCheckPreallocated(mat,1); 6971 6972 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6973 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6974 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6975 for (i=0; i<n; i++) { 6976 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6977 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6978 if (eq) { 6979 if (mat->symmetric) { 6980 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6981 } else if (mat->hermitian) { 6982 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6983 } else if (mat->structurally_symmetric) { 6984 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6985 } 6986 } 6987 } 6988 } 6989 PetscFunctionReturn(0); 6990 } 6991 6992 /*@C 6993 MatDestroyMatrices - Destroys an array of matrices. 6994 6995 Collective on Mat 6996 6997 Input Parameters: 6998 + n - the number of local matrices 6999 - mat - the matrices (note that this is a pointer to the array of matrices) 7000 7001 Level: advanced 7002 7003 Notes: 7004 Frees not only the matrices, but also the array that contains the matrices 7005 In Fortran will not free the array. 7006 7007 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 7008 @*/ 7009 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7010 { 7011 PetscErrorCode ierr; 7012 PetscInt i; 7013 7014 PetscFunctionBegin; 7015 if (!*mat) PetscFunctionReturn(0); 7016 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7017 PetscValidPointer(mat,2); 7018 7019 for (i=0; i<n; i++) { 7020 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 7021 } 7022 7023 /* memory is allocated even if n = 0 */ 7024 ierr = PetscFree(*mat);CHKERRQ(ierr); 7025 PetscFunctionReturn(0); 7026 } 7027 7028 /*@C 7029 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7030 7031 Collective on Mat 7032 7033 Input Parameters: 7034 + n - the number of local matrices 7035 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7036 sequence of MatCreateSubMatrices()) 7037 7038 Level: advanced 7039 7040 Notes: 7041 Frees not only the matrices, but also the array that contains the matrices 7042 In Fortran will not free the array. 7043 7044 .seealso: MatCreateSubMatrices() 7045 @*/ 7046 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7047 { 7048 PetscErrorCode ierr; 7049 Mat mat0; 7050 7051 PetscFunctionBegin; 7052 if (!*mat) PetscFunctionReturn(0); 7053 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7054 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 7055 PetscValidPointer(mat,2); 7056 7057 mat0 = (*mat)[0]; 7058 if (mat0 && mat0->ops->destroysubmatrices) { 7059 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 7060 } else { 7061 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 7062 } 7063 PetscFunctionReturn(0); 7064 } 7065 7066 /*@C 7067 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 7068 7069 Collective on Mat 7070 7071 Input Parameters: 7072 . mat - the matrix 7073 7074 Output Parameter: 7075 . matstruct - the sequential matrix with the nonzero structure of mat 7076 7077 Level: intermediate 7078 7079 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 7080 @*/ 7081 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7082 { 7083 PetscErrorCode ierr; 7084 7085 PetscFunctionBegin; 7086 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7087 PetscValidPointer(matstruct,2); 7088 7089 PetscValidType(mat,1); 7090 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7091 MatCheckPreallocated(mat,1); 7092 7093 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 7094 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7095 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7096 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7097 PetscFunctionReturn(0); 7098 } 7099 7100 /*@C 7101 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7102 7103 Collective on Mat 7104 7105 Input Parameters: 7106 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7107 sequence of MatGetSequentialNonzeroStructure()) 7108 7109 Level: advanced 7110 7111 Notes: 7112 Frees not only the matrices, but also the array that contains the matrices 7113 7114 .seealso: MatGetSeqNonzeroStructure() 7115 @*/ 7116 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7117 { 7118 PetscErrorCode ierr; 7119 7120 PetscFunctionBegin; 7121 PetscValidPointer(mat,1); 7122 ierr = MatDestroy(mat);CHKERRQ(ierr); 7123 PetscFunctionReturn(0); 7124 } 7125 7126 /*@ 7127 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7128 replaces the index sets by larger ones that represent submatrices with 7129 additional overlap. 7130 7131 Collective on Mat 7132 7133 Input Parameters: 7134 + mat - the matrix 7135 . n - the number of index sets 7136 . is - the array of index sets (these index sets will changed during the call) 7137 - ov - the additional overlap requested 7138 7139 Options Database: 7140 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7141 7142 Level: developer 7143 7144 Concepts: overlap 7145 Concepts: ASM^computing overlap 7146 7147 .seealso: MatCreateSubMatrices() 7148 @*/ 7149 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7150 { 7151 PetscErrorCode ierr; 7152 7153 PetscFunctionBegin; 7154 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7155 PetscValidType(mat,1); 7156 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7157 if (n) { 7158 PetscValidPointer(is,3); 7159 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7160 } 7161 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7162 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7163 MatCheckPreallocated(mat,1); 7164 7165 if (!ov) PetscFunctionReturn(0); 7166 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7167 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7168 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7169 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7170 PetscFunctionReturn(0); 7171 } 7172 7173 7174 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7175 7176 /*@ 7177 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7178 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7179 additional overlap. 7180 7181 Collective on Mat 7182 7183 Input Parameters: 7184 + mat - the matrix 7185 . n - the number of index sets 7186 . is - the array of index sets (these index sets will changed during the call) 7187 - ov - the additional overlap requested 7188 7189 Options Database: 7190 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7191 7192 Level: developer 7193 7194 Concepts: overlap 7195 Concepts: ASM^computing overlap 7196 7197 .seealso: MatCreateSubMatrices() 7198 @*/ 7199 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7200 { 7201 PetscInt i; 7202 PetscErrorCode ierr; 7203 7204 PetscFunctionBegin; 7205 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7206 PetscValidType(mat,1); 7207 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7208 if (n) { 7209 PetscValidPointer(is,3); 7210 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7211 } 7212 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7213 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7214 MatCheckPreallocated(mat,1); 7215 if (!ov) PetscFunctionReturn(0); 7216 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7217 for(i=0; i<n; i++){ 7218 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7219 } 7220 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7221 PetscFunctionReturn(0); 7222 } 7223 7224 7225 7226 7227 /*@ 7228 MatGetBlockSize - Returns the matrix block size. 7229 7230 Not Collective 7231 7232 Input Parameter: 7233 . mat - the matrix 7234 7235 Output Parameter: 7236 . bs - block size 7237 7238 Notes: 7239 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7240 7241 If the block size has not been set yet this routine returns 1. 7242 7243 Level: intermediate 7244 7245 Concepts: matrices^block size 7246 7247 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7248 @*/ 7249 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7250 { 7251 PetscFunctionBegin; 7252 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7253 PetscValidIntPointer(bs,2); 7254 *bs = PetscAbs(mat->rmap->bs); 7255 PetscFunctionReturn(0); 7256 } 7257 7258 /*@ 7259 MatGetBlockSizes - Returns the matrix block row and column sizes. 7260 7261 Not Collective 7262 7263 Input Parameter: 7264 . mat - the matrix 7265 7266 Output Parameter: 7267 . rbs - row block size 7268 . cbs - column block size 7269 7270 Notes: 7271 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7272 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7273 7274 If a block size has not been set yet this routine returns 1. 7275 7276 Level: intermediate 7277 7278 Concepts: matrices^block size 7279 7280 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7281 @*/ 7282 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7283 { 7284 PetscFunctionBegin; 7285 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7286 if (rbs) PetscValidIntPointer(rbs,2); 7287 if (cbs) PetscValidIntPointer(cbs,3); 7288 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7289 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7290 PetscFunctionReturn(0); 7291 } 7292 7293 /*@ 7294 MatSetBlockSize - Sets the matrix block size. 7295 7296 Logically Collective on Mat 7297 7298 Input Parameters: 7299 + mat - the matrix 7300 - bs - block size 7301 7302 Notes: 7303 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7304 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7305 7306 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7307 is compatible with the matrix local sizes. 7308 7309 Level: intermediate 7310 7311 Concepts: matrices^block size 7312 7313 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7314 @*/ 7315 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7316 { 7317 PetscErrorCode ierr; 7318 7319 PetscFunctionBegin; 7320 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7321 PetscValidLogicalCollectiveInt(mat,bs,2); 7322 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7323 PetscFunctionReturn(0); 7324 } 7325 7326 /*@ 7327 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7328 7329 Logically Collective on Mat 7330 7331 Input Parameters: 7332 + mat - the matrix 7333 . nblocks - the number of blocks on this process 7334 - bsizes - the block sizes 7335 7336 Notes: 7337 Currently used by PCVPBJACOBI for SeqAIJ matrices 7338 7339 Level: intermediate 7340 7341 Concepts: matrices^block size 7342 7343 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7344 @*/ 7345 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7346 { 7347 PetscErrorCode ierr; 7348 PetscInt i,ncnt = 0, nlocal; 7349 7350 PetscFunctionBegin; 7351 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7352 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7353 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7354 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7355 if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal); 7356 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7357 mat->nblocks = nblocks; 7358 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7359 ierr = PetscMemcpy(mat->bsizes,bsizes,nblocks*sizeof(PetscInt));CHKERRQ(ierr); 7360 PetscFunctionReturn(0); 7361 } 7362 7363 /*@C 7364 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7365 7366 Logically Collective on Mat 7367 7368 Input Parameters: 7369 . mat - the matrix 7370 7371 Output Parameters: 7372 + nblocks - the number of blocks on this process 7373 - bsizes - the block sizes 7374 7375 Notes: Currently not supported from Fortran 7376 7377 Level: intermediate 7378 7379 Concepts: matrices^block size 7380 7381 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7382 @*/ 7383 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7384 { 7385 PetscFunctionBegin; 7386 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7387 *nblocks = mat->nblocks; 7388 *bsizes = mat->bsizes; 7389 PetscFunctionReturn(0); 7390 } 7391 7392 /*@ 7393 MatSetBlockSizes - Sets the matrix block row and column sizes. 7394 7395 Logically Collective on Mat 7396 7397 Input Parameters: 7398 + mat - the matrix 7399 - rbs - row block size 7400 - cbs - column block size 7401 7402 Notes: 7403 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7404 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7405 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7406 7407 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7408 are compatible with the matrix local sizes. 7409 7410 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7411 7412 Level: intermediate 7413 7414 Concepts: matrices^block size 7415 7416 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7417 @*/ 7418 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7419 { 7420 PetscErrorCode ierr; 7421 7422 PetscFunctionBegin; 7423 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7424 PetscValidLogicalCollectiveInt(mat,rbs,2); 7425 PetscValidLogicalCollectiveInt(mat,cbs,3); 7426 if (mat->ops->setblocksizes) { 7427 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7428 } 7429 if (mat->rmap->refcnt) { 7430 ISLocalToGlobalMapping l2g = NULL; 7431 PetscLayout nmap = NULL; 7432 7433 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7434 if (mat->rmap->mapping) { 7435 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7436 } 7437 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7438 mat->rmap = nmap; 7439 mat->rmap->mapping = l2g; 7440 } 7441 if (mat->cmap->refcnt) { 7442 ISLocalToGlobalMapping l2g = NULL; 7443 PetscLayout nmap = NULL; 7444 7445 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7446 if (mat->cmap->mapping) { 7447 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7448 } 7449 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7450 mat->cmap = nmap; 7451 mat->cmap->mapping = l2g; 7452 } 7453 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7454 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7455 PetscFunctionReturn(0); 7456 } 7457 7458 /*@ 7459 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7460 7461 Logically Collective on Mat 7462 7463 Input Parameters: 7464 + mat - the matrix 7465 . fromRow - matrix from which to copy row block size 7466 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7467 7468 Level: developer 7469 7470 Concepts: matrices^block size 7471 7472 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7473 @*/ 7474 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7475 { 7476 PetscErrorCode ierr; 7477 7478 PetscFunctionBegin; 7479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7480 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7481 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7482 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7483 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7484 PetscFunctionReturn(0); 7485 } 7486 7487 /*@ 7488 MatResidual - Default routine to calculate the residual. 7489 7490 Collective on Mat and Vec 7491 7492 Input Parameters: 7493 + mat - the matrix 7494 . b - the right-hand-side 7495 - x - the approximate solution 7496 7497 Output Parameter: 7498 . r - location to store the residual 7499 7500 Level: developer 7501 7502 .keywords: MG, default, multigrid, residual 7503 7504 .seealso: PCMGSetResidual() 7505 @*/ 7506 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7507 { 7508 PetscErrorCode ierr; 7509 7510 PetscFunctionBegin; 7511 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7512 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7513 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7514 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7515 PetscValidType(mat,1); 7516 MatCheckPreallocated(mat,1); 7517 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7518 if (!mat->ops->residual) { 7519 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7520 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7521 } else { 7522 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7523 } 7524 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7525 PetscFunctionReturn(0); 7526 } 7527 7528 /*@C 7529 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7530 7531 Collective on Mat 7532 7533 Input Parameters: 7534 + mat - the matrix 7535 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7536 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7537 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7538 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7539 always used. 7540 7541 Output Parameters: 7542 + n - number of rows in the (possibly compressed) matrix 7543 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7544 . ja - the column indices 7545 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7546 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7547 7548 Level: developer 7549 7550 Notes: 7551 You CANNOT change any of the ia[] or ja[] values. 7552 7553 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7554 7555 Fortran Notes: 7556 In Fortran use 7557 $ 7558 $ PetscInt ia(1), ja(1) 7559 $ PetscOffset iia, jja 7560 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7561 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7562 7563 or 7564 $ 7565 $ PetscInt, pointer :: ia(:),ja(:) 7566 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7567 $ ! Access the ith and jth entries via ia(i) and ja(j) 7568 7569 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7570 @*/ 7571 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7572 { 7573 PetscErrorCode ierr; 7574 7575 PetscFunctionBegin; 7576 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7577 PetscValidType(mat,1); 7578 PetscValidIntPointer(n,5); 7579 if (ia) PetscValidIntPointer(ia,6); 7580 if (ja) PetscValidIntPointer(ja,7); 7581 PetscValidIntPointer(done,8); 7582 MatCheckPreallocated(mat,1); 7583 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7584 else { 7585 *done = PETSC_TRUE; 7586 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7587 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7588 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7589 } 7590 PetscFunctionReturn(0); 7591 } 7592 7593 /*@C 7594 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7595 7596 Collective on Mat 7597 7598 Input Parameters: 7599 + mat - the matrix 7600 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7601 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7602 symmetrized 7603 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7604 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7605 always used. 7606 . n - number of columns in the (possibly compressed) matrix 7607 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7608 - ja - the row indices 7609 7610 Output Parameters: 7611 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7612 7613 Level: developer 7614 7615 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7616 @*/ 7617 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7618 { 7619 PetscErrorCode ierr; 7620 7621 PetscFunctionBegin; 7622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7623 PetscValidType(mat,1); 7624 PetscValidIntPointer(n,4); 7625 if (ia) PetscValidIntPointer(ia,5); 7626 if (ja) PetscValidIntPointer(ja,6); 7627 PetscValidIntPointer(done,7); 7628 MatCheckPreallocated(mat,1); 7629 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7630 else { 7631 *done = PETSC_TRUE; 7632 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7633 } 7634 PetscFunctionReturn(0); 7635 } 7636 7637 /*@C 7638 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7639 MatGetRowIJ(). 7640 7641 Collective on Mat 7642 7643 Input Parameters: 7644 + mat - the matrix 7645 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7646 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7647 symmetrized 7648 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7649 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7650 always used. 7651 . n - size of (possibly compressed) matrix 7652 . ia - the row pointers 7653 - ja - the column indices 7654 7655 Output Parameters: 7656 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7657 7658 Note: 7659 This routine zeros out n, ia, and ja. This is to prevent accidental 7660 us of the array after it has been restored. If you pass NULL, it will 7661 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7662 7663 Level: developer 7664 7665 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7666 @*/ 7667 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7668 { 7669 PetscErrorCode ierr; 7670 7671 PetscFunctionBegin; 7672 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7673 PetscValidType(mat,1); 7674 if (ia) PetscValidIntPointer(ia,6); 7675 if (ja) PetscValidIntPointer(ja,7); 7676 PetscValidIntPointer(done,8); 7677 MatCheckPreallocated(mat,1); 7678 7679 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7680 else { 7681 *done = PETSC_TRUE; 7682 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7683 if (n) *n = 0; 7684 if (ia) *ia = NULL; 7685 if (ja) *ja = NULL; 7686 } 7687 PetscFunctionReturn(0); 7688 } 7689 7690 /*@C 7691 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7692 MatGetColumnIJ(). 7693 7694 Collective on Mat 7695 7696 Input Parameters: 7697 + mat - the matrix 7698 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7699 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7700 symmetrized 7701 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7702 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7703 always used. 7704 7705 Output Parameters: 7706 + n - size of (possibly compressed) matrix 7707 . ia - the column pointers 7708 . ja - the row indices 7709 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7710 7711 Level: developer 7712 7713 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7714 @*/ 7715 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7716 { 7717 PetscErrorCode ierr; 7718 7719 PetscFunctionBegin; 7720 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7721 PetscValidType(mat,1); 7722 if (ia) PetscValidIntPointer(ia,5); 7723 if (ja) PetscValidIntPointer(ja,6); 7724 PetscValidIntPointer(done,7); 7725 MatCheckPreallocated(mat,1); 7726 7727 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7728 else { 7729 *done = PETSC_TRUE; 7730 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7731 if (n) *n = 0; 7732 if (ia) *ia = NULL; 7733 if (ja) *ja = NULL; 7734 } 7735 PetscFunctionReturn(0); 7736 } 7737 7738 /*@C 7739 MatColoringPatch -Used inside matrix coloring routines that 7740 use MatGetRowIJ() and/or MatGetColumnIJ(). 7741 7742 Collective on Mat 7743 7744 Input Parameters: 7745 + mat - the matrix 7746 . ncolors - max color value 7747 . n - number of entries in colorarray 7748 - colorarray - array indicating color for each column 7749 7750 Output Parameters: 7751 . iscoloring - coloring generated using colorarray information 7752 7753 Level: developer 7754 7755 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7756 7757 @*/ 7758 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7759 { 7760 PetscErrorCode ierr; 7761 7762 PetscFunctionBegin; 7763 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7764 PetscValidType(mat,1); 7765 PetscValidIntPointer(colorarray,4); 7766 PetscValidPointer(iscoloring,5); 7767 MatCheckPreallocated(mat,1); 7768 7769 if (!mat->ops->coloringpatch) { 7770 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7771 } else { 7772 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7773 } 7774 PetscFunctionReturn(0); 7775 } 7776 7777 7778 /*@ 7779 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7780 7781 Logically Collective on Mat 7782 7783 Input Parameter: 7784 . mat - the factored matrix to be reset 7785 7786 Notes: 7787 This routine should be used only with factored matrices formed by in-place 7788 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7789 format). This option can save memory, for example, when solving nonlinear 7790 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7791 ILU(0) preconditioner. 7792 7793 Note that one can specify in-place ILU(0) factorization by calling 7794 .vb 7795 PCType(pc,PCILU); 7796 PCFactorSeUseInPlace(pc); 7797 .ve 7798 or by using the options -pc_type ilu -pc_factor_in_place 7799 7800 In-place factorization ILU(0) can also be used as a local 7801 solver for the blocks within the block Jacobi or additive Schwarz 7802 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7803 for details on setting local solver options. 7804 7805 Most users should employ the simplified KSP interface for linear solvers 7806 instead of working directly with matrix algebra routines such as this. 7807 See, e.g., KSPCreate(). 7808 7809 Level: developer 7810 7811 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7812 7813 Concepts: matrices^unfactored 7814 7815 @*/ 7816 PetscErrorCode MatSetUnfactored(Mat mat) 7817 { 7818 PetscErrorCode ierr; 7819 7820 PetscFunctionBegin; 7821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7822 PetscValidType(mat,1); 7823 MatCheckPreallocated(mat,1); 7824 mat->factortype = MAT_FACTOR_NONE; 7825 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7826 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7827 PetscFunctionReturn(0); 7828 } 7829 7830 /*MC 7831 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7832 7833 Synopsis: 7834 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7835 7836 Not collective 7837 7838 Input Parameter: 7839 . x - matrix 7840 7841 Output Parameters: 7842 + xx_v - the Fortran90 pointer to the array 7843 - ierr - error code 7844 7845 Example of Usage: 7846 .vb 7847 PetscScalar, pointer xx_v(:,:) 7848 .... 7849 call MatDenseGetArrayF90(x,xx_v,ierr) 7850 a = xx_v(3) 7851 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7852 .ve 7853 7854 Level: advanced 7855 7856 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7857 7858 Concepts: matrices^accessing array 7859 7860 M*/ 7861 7862 /*MC 7863 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7864 accessed with MatDenseGetArrayF90(). 7865 7866 Synopsis: 7867 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7868 7869 Not collective 7870 7871 Input Parameters: 7872 + x - matrix 7873 - xx_v - the Fortran90 pointer to the array 7874 7875 Output Parameter: 7876 . ierr - error code 7877 7878 Example of Usage: 7879 .vb 7880 PetscScalar, pointer xx_v(:,:) 7881 .... 7882 call MatDenseGetArrayF90(x,xx_v,ierr) 7883 a = xx_v(3) 7884 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7885 .ve 7886 7887 Level: advanced 7888 7889 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7890 7891 M*/ 7892 7893 7894 /*MC 7895 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7896 7897 Synopsis: 7898 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7899 7900 Not collective 7901 7902 Input Parameter: 7903 . x - matrix 7904 7905 Output Parameters: 7906 + xx_v - the Fortran90 pointer to the array 7907 - ierr - error code 7908 7909 Example of Usage: 7910 .vb 7911 PetscScalar, pointer xx_v(:) 7912 .... 7913 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7914 a = xx_v(3) 7915 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7916 .ve 7917 7918 Level: advanced 7919 7920 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7921 7922 Concepts: matrices^accessing array 7923 7924 M*/ 7925 7926 /*MC 7927 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7928 accessed with MatSeqAIJGetArrayF90(). 7929 7930 Synopsis: 7931 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7932 7933 Not collective 7934 7935 Input Parameters: 7936 + x - matrix 7937 - xx_v - the Fortran90 pointer to the array 7938 7939 Output Parameter: 7940 . ierr - error code 7941 7942 Example of Usage: 7943 .vb 7944 PetscScalar, pointer xx_v(:) 7945 .... 7946 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7947 a = xx_v(3) 7948 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7949 .ve 7950 7951 Level: advanced 7952 7953 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7954 7955 M*/ 7956 7957 7958 /*@ 7959 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7960 as the original matrix. 7961 7962 Collective on Mat 7963 7964 Input Parameters: 7965 + mat - the original matrix 7966 . isrow - parallel IS containing the rows this processor should obtain 7967 . 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. 7968 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7969 7970 Output Parameter: 7971 . newmat - the new submatrix, of the same type as the old 7972 7973 Level: advanced 7974 7975 Notes: 7976 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7977 7978 Some matrix types place restrictions on the row and column indices, such 7979 as that they be sorted or that they be equal to each other. 7980 7981 The index sets may not have duplicate entries. 7982 7983 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7984 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7985 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7986 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7987 you are finished using it. 7988 7989 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7990 the input matrix. 7991 7992 If iscol is NULL then all columns are obtained (not supported in Fortran). 7993 7994 Example usage: 7995 Consider the following 8x8 matrix with 34 non-zero values, that is 7996 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7997 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7998 as follows: 7999 8000 .vb 8001 1 2 0 | 0 3 0 | 0 4 8002 Proc0 0 5 6 | 7 0 0 | 8 0 8003 9 0 10 | 11 0 0 | 12 0 8004 ------------------------------------- 8005 13 0 14 | 15 16 17 | 0 0 8006 Proc1 0 18 0 | 19 20 21 | 0 0 8007 0 0 0 | 22 23 0 | 24 0 8008 ------------------------------------- 8009 Proc2 25 26 27 | 0 0 28 | 29 0 8010 30 0 0 | 31 32 33 | 0 34 8011 .ve 8012 8013 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8014 8015 .vb 8016 2 0 | 0 3 0 | 0 8017 Proc0 5 6 | 7 0 0 | 8 8018 ------------------------------- 8019 Proc1 18 0 | 19 20 21 | 0 8020 ------------------------------- 8021 Proc2 26 27 | 0 0 28 | 29 8022 0 0 | 31 32 33 | 0 8023 .ve 8024 8025 8026 Concepts: matrices^submatrices 8027 8028 .seealso: MatCreateSubMatrices() 8029 @*/ 8030 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8031 { 8032 PetscErrorCode ierr; 8033 PetscMPIInt size; 8034 Mat *local; 8035 IS iscoltmp; 8036 8037 PetscFunctionBegin; 8038 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8039 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8040 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8041 PetscValidPointer(newmat,5); 8042 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8043 PetscValidType(mat,1); 8044 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8045 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8046 8047 MatCheckPreallocated(mat,1); 8048 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8049 8050 if (!iscol || isrow == iscol) { 8051 PetscBool stride; 8052 PetscMPIInt grabentirematrix = 0,grab; 8053 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 8054 if (stride) { 8055 PetscInt first,step,n,rstart,rend; 8056 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 8057 if (step == 1) { 8058 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 8059 if (rstart == first) { 8060 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 8061 if (n == rend-rstart) { 8062 grabentirematrix = 1; 8063 } 8064 } 8065 } 8066 } 8067 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 8068 if (grab) { 8069 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 8070 if (cll == MAT_INITIAL_MATRIX) { 8071 *newmat = mat; 8072 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 8073 } 8074 PetscFunctionReturn(0); 8075 } 8076 } 8077 8078 if (!iscol) { 8079 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 8080 } else { 8081 iscoltmp = iscol; 8082 } 8083 8084 /* if original matrix is on just one processor then use submatrix generated */ 8085 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8086 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8087 goto setproperties; 8088 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8089 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8090 *newmat = *local; 8091 ierr = PetscFree(local);CHKERRQ(ierr); 8092 goto setproperties; 8093 } else if (!mat->ops->createsubmatrix) { 8094 /* Create a new matrix type that implements the operation using the full matrix */ 8095 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8096 switch (cll) { 8097 case MAT_INITIAL_MATRIX: 8098 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8099 break; 8100 case MAT_REUSE_MATRIX: 8101 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8102 break; 8103 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8104 } 8105 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8106 goto setproperties; 8107 } 8108 8109 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8110 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8111 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8112 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8113 8114 /* Propagate symmetry information for diagonal blocks */ 8115 setproperties: 8116 if (isrow == iscoltmp) { 8117 if (mat->symmetric_set && mat->symmetric) { 8118 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8119 } 8120 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 8121 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 8122 } 8123 if (mat->hermitian_set && mat->hermitian) { 8124 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 8125 } 8126 if (mat->spd_set && mat->spd) { 8127 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 8128 } 8129 } 8130 8131 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8132 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8133 PetscFunctionReturn(0); 8134 } 8135 8136 /*@ 8137 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8138 used during the assembly process to store values that belong to 8139 other processors. 8140 8141 Not Collective 8142 8143 Input Parameters: 8144 + mat - the matrix 8145 . size - the initial size of the stash. 8146 - bsize - the initial size of the block-stash(if used). 8147 8148 Options Database Keys: 8149 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8150 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8151 8152 Level: intermediate 8153 8154 Notes: 8155 The block-stash is used for values set with MatSetValuesBlocked() while 8156 the stash is used for values set with MatSetValues() 8157 8158 Run with the option -info and look for output of the form 8159 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8160 to determine the appropriate value, MM, to use for size and 8161 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8162 to determine the value, BMM to use for bsize 8163 8164 Concepts: stash^setting matrix size 8165 Concepts: matrices^stash 8166 8167 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8168 8169 @*/ 8170 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8171 { 8172 PetscErrorCode ierr; 8173 8174 PetscFunctionBegin; 8175 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8176 PetscValidType(mat,1); 8177 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8178 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8179 PetscFunctionReturn(0); 8180 } 8181 8182 /*@ 8183 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8184 the matrix 8185 8186 Neighbor-wise Collective on Mat 8187 8188 Input Parameters: 8189 + mat - the matrix 8190 . x,y - the vectors 8191 - w - where the result is stored 8192 8193 Level: intermediate 8194 8195 Notes: 8196 w may be the same vector as y. 8197 8198 This allows one to use either the restriction or interpolation (its transpose) 8199 matrix to do the interpolation 8200 8201 Concepts: interpolation 8202 8203 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8204 8205 @*/ 8206 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8207 { 8208 PetscErrorCode ierr; 8209 PetscInt M,N,Ny; 8210 8211 PetscFunctionBegin; 8212 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8213 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8214 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8215 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8216 PetscValidType(A,1); 8217 MatCheckPreallocated(A,1); 8218 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8219 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8220 if (M == Ny) { 8221 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8222 } else { 8223 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8224 } 8225 PetscFunctionReturn(0); 8226 } 8227 8228 /*@ 8229 MatInterpolate - y = A*x or A'*x depending on the shape of 8230 the matrix 8231 8232 Neighbor-wise Collective on Mat 8233 8234 Input Parameters: 8235 + mat - the matrix 8236 - x,y - the vectors 8237 8238 Level: intermediate 8239 8240 Notes: 8241 This allows one to use either the restriction or interpolation (its transpose) 8242 matrix to do the interpolation 8243 8244 Concepts: matrices^interpolation 8245 8246 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8247 8248 @*/ 8249 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8250 { 8251 PetscErrorCode ierr; 8252 PetscInt M,N,Ny; 8253 8254 PetscFunctionBegin; 8255 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8256 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8257 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8258 PetscValidType(A,1); 8259 MatCheckPreallocated(A,1); 8260 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8261 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8262 if (M == Ny) { 8263 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8264 } else { 8265 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8266 } 8267 PetscFunctionReturn(0); 8268 } 8269 8270 /*@ 8271 MatRestrict - y = A*x or A'*x 8272 8273 Neighbor-wise Collective on Mat 8274 8275 Input Parameters: 8276 + mat - the matrix 8277 - x,y - the vectors 8278 8279 Level: intermediate 8280 8281 Notes: 8282 This allows one to use either the restriction or interpolation (its transpose) 8283 matrix to do the restriction 8284 8285 Concepts: matrices^restriction 8286 8287 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8288 8289 @*/ 8290 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8291 { 8292 PetscErrorCode ierr; 8293 PetscInt M,N,Ny; 8294 8295 PetscFunctionBegin; 8296 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8297 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8298 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8299 PetscValidType(A,1); 8300 MatCheckPreallocated(A,1); 8301 8302 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8303 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8304 if (M == Ny) { 8305 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8306 } else { 8307 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8308 } 8309 PetscFunctionReturn(0); 8310 } 8311 8312 /*@ 8313 MatGetNullSpace - retrieves the null space of a matrix. 8314 8315 Logically Collective on Mat and MatNullSpace 8316 8317 Input Parameters: 8318 + mat - the matrix 8319 - nullsp - the null space object 8320 8321 Level: developer 8322 8323 Concepts: null space^attaching to matrix 8324 8325 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8326 @*/ 8327 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8328 { 8329 PetscFunctionBegin; 8330 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8331 PetscValidPointer(nullsp,2); 8332 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8333 PetscFunctionReturn(0); 8334 } 8335 8336 /*@ 8337 MatSetNullSpace - attaches a null space to a matrix. 8338 8339 Logically Collective on Mat and MatNullSpace 8340 8341 Input Parameters: 8342 + mat - the matrix 8343 - nullsp - the null space object 8344 8345 Level: advanced 8346 8347 Notes: 8348 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8349 8350 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8351 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8352 8353 You can remove the null space by calling this routine with an nullsp of NULL 8354 8355 8356 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8357 the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T). 8358 Similarly R^m = direct sum n(A^T) + R(A). Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to 8359 n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution 8360 the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T). 8361 8362 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8363 8364 If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this 8365 routine also automatically calls MatSetTransposeNullSpace(). 8366 8367 Concepts: null space^attaching to matrix 8368 8369 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8370 @*/ 8371 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8372 { 8373 PetscErrorCode ierr; 8374 8375 PetscFunctionBegin; 8376 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8377 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8378 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8379 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8380 mat->nullsp = nullsp; 8381 if (mat->symmetric_set && mat->symmetric) { 8382 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8383 } 8384 PetscFunctionReturn(0); 8385 } 8386 8387 /*@ 8388 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8389 8390 Logically Collective on Mat and MatNullSpace 8391 8392 Input Parameters: 8393 + mat - the matrix 8394 - nullsp - the null space object 8395 8396 Level: developer 8397 8398 Concepts: null space^attaching to matrix 8399 8400 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8401 @*/ 8402 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8403 { 8404 PetscFunctionBegin; 8405 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8406 PetscValidType(mat,1); 8407 PetscValidPointer(nullsp,2); 8408 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8409 PetscFunctionReturn(0); 8410 } 8411 8412 /*@ 8413 MatSetTransposeNullSpace - attaches a null space to a matrix. 8414 8415 Logically Collective on Mat and MatNullSpace 8416 8417 Input Parameters: 8418 + mat - the matrix 8419 - nullsp - the null space object 8420 8421 Level: advanced 8422 8423 Notes: 8424 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense. 8425 You must also call MatSetNullSpace() 8426 8427 8428 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8429 the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T). 8430 Similarly R^m = direct sum n(A^T) + R(A). Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to 8431 n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution 8432 the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T). 8433 8434 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8435 8436 Concepts: null space^attaching to matrix 8437 8438 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8439 @*/ 8440 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8441 { 8442 PetscErrorCode ierr; 8443 8444 PetscFunctionBegin; 8445 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8446 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8447 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8448 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8449 mat->transnullsp = nullsp; 8450 PetscFunctionReturn(0); 8451 } 8452 8453 /*@ 8454 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8455 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8456 8457 Logically Collective on Mat and MatNullSpace 8458 8459 Input Parameters: 8460 + mat - the matrix 8461 - nullsp - the null space object 8462 8463 Level: advanced 8464 8465 Notes: 8466 Overwrites any previous near null space that may have been attached 8467 8468 You can remove the null space by calling this routine with an nullsp of NULL 8469 8470 Concepts: null space^attaching to matrix 8471 8472 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8473 @*/ 8474 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8475 { 8476 PetscErrorCode ierr; 8477 8478 PetscFunctionBegin; 8479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8480 PetscValidType(mat,1); 8481 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8482 MatCheckPreallocated(mat,1); 8483 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8484 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8485 mat->nearnullsp = nullsp; 8486 PetscFunctionReturn(0); 8487 } 8488 8489 /*@ 8490 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8491 8492 Not Collective 8493 8494 Input Parameters: 8495 . mat - the matrix 8496 8497 Output Parameters: 8498 . nullsp - the null space object, NULL if not set 8499 8500 Level: developer 8501 8502 Concepts: null space^attaching to matrix 8503 8504 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8505 @*/ 8506 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8507 { 8508 PetscFunctionBegin; 8509 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8510 PetscValidType(mat,1); 8511 PetscValidPointer(nullsp,2); 8512 MatCheckPreallocated(mat,1); 8513 *nullsp = mat->nearnullsp; 8514 PetscFunctionReturn(0); 8515 } 8516 8517 /*@C 8518 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8519 8520 Collective on Mat 8521 8522 Input Parameters: 8523 + mat - the matrix 8524 . row - row/column permutation 8525 . fill - expected fill factor >= 1.0 8526 - level - level of fill, for ICC(k) 8527 8528 Notes: 8529 Probably really in-place only when level of fill is zero, otherwise allocates 8530 new space to store factored matrix and deletes previous memory. 8531 8532 Most users should employ the simplified KSP interface for linear solvers 8533 instead of working directly with matrix algebra routines such as this. 8534 See, e.g., KSPCreate(). 8535 8536 Level: developer 8537 8538 Concepts: matrices^incomplete Cholesky factorization 8539 Concepts: Cholesky factorization 8540 8541 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8542 8543 Developer Note: fortran interface is not autogenerated as the f90 8544 interface defintion cannot be generated correctly [due to MatFactorInfo] 8545 8546 @*/ 8547 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8548 { 8549 PetscErrorCode ierr; 8550 8551 PetscFunctionBegin; 8552 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8553 PetscValidType(mat,1); 8554 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8555 PetscValidPointer(info,3); 8556 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8557 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8558 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8559 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8560 MatCheckPreallocated(mat,1); 8561 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8562 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8563 PetscFunctionReturn(0); 8564 } 8565 8566 /*@ 8567 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8568 ghosted ones. 8569 8570 Not Collective 8571 8572 Input Parameters: 8573 + mat - the matrix 8574 - diag = the diagonal values, including ghost ones 8575 8576 Level: developer 8577 8578 Notes: 8579 Works only for MPIAIJ and MPIBAIJ matrices 8580 8581 .seealso: MatDiagonalScale() 8582 @*/ 8583 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8584 { 8585 PetscErrorCode ierr; 8586 PetscMPIInt size; 8587 8588 PetscFunctionBegin; 8589 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8590 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8591 PetscValidType(mat,1); 8592 8593 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8594 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8595 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8596 if (size == 1) { 8597 PetscInt n,m; 8598 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8599 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8600 if (m == n) { 8601 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8602 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8603 } else { 8604 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8605 } 8606 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8607 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8608 PetscFunctionReturn(0); 8609 } 8610 8611 /*@ 8612 MatGetInertia - Gets the inertia from a factored matrix 8613 8614 Collective on Mat 8615 8616 Input Parameter: 8617 . mat - the matrix 8618 8619 Output Parameters: 8620 + nneg - number of negative eigenvalues 8621 . nzero - number of zero eigenvalues 8622 - npos - number of positive eigenvalues 8623 8624 Level: advanced 8625 8626 Notes: 8627 Matrix must have been factored by MatCholeskyFactor() 8628 8629 8630 @*/ 8631 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8632 { 8633 PetscErrorCode ierr; 8634 8635 PetscFunctionBegin; 8636 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8637 PetscValidType(mat,1); 8638 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8639 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8640 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8641 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8642 PetscFunctionReturn(0); 8643 } 8644 8645 /* ----------------------------------------------------------------*/ 8646 /*@C 8647 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8648 8649 Neighbor-wise Collective on Mat and Vecs 8650 8651 Input Parameters: 8652 + mat - the factored matrix 8653 - b - the right-hand-side vectors 8654 8655 Output Parameter: 8656 . x - the result vectors 8657 8658 Notes: 8659 The vectors b and x cannot be the same. I.e., one cannot 8660 call MatSolves(A,x,x). 8661 8662 Notes: 8663 Most users should employ the simplified KSP interface for linear solvers 8664 instead of working directly with matrix algebra routines such as this. 8665 See, e.g., KSPCreate(). 8666 8667 Level: developer 8668 8669 Concepts: matrices^triangular solves 8670 8671 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8672 @*/ 8673 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8674 { 8675 PetscErrorCode ierr; 8676 8677 PetscFunctionBegin; 8678 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8679 PetscValidType(mat,1); 8680 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8681 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8682 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8683 8684 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8685 MatCheckPreallocated(mat,1); 8686 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8687 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8688 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8689 PetscFunctionReturn(0); 8690 } 8691 8692 /*@ 8693 MatIsSymmetric - Test whether a matrix is symmetric 8694 8695 Collective on Mat 8696 8697 Input Parameter: 8698 + A - the matrix to test 8699 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8700 8701 Output Parameters: 8702 . flg - the result 8703 8704 Notes: 8705 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8706 8707 Level: intermediate 8708 8709 Concepts: matrix^symmetry 8710 8711 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8712 @*/ 8713 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8714 { 8715 PetscErrorCode ierr; 8716 8717 PetscFunctionBegin; 8718 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8719 PetscValidPointer(flg,2); 8720 8721 if (!A->symmetric_set) { 8722 if (!A->ops->issymmetric) { 8723 MatType mattype; 8724 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8725 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8726 } 8727 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8728 if (!tol) { 8729 A->symmetric_set = PETSC_TRUE; 8730 A->symmetric = *flg; 8731 if (A->symmetric) { 8732 A->structurally_symmetric_set = PETSC_TRUE; 8733 A->structurally_symmetric = PETSC_TRUE; 8734 } 8735 } 8736 } else if (A->symmetric) { 8737 *flg = PETSC_TRUE; 8738 } else if (!tol) { 8739 *flg = PETSC_FALSE; 8740 } else { 8741 if (!A->ops->issymmetric) { 8742 MatType mattype; 8743 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8744 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8745 } 8746 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8747 } 8748 PetscFunctionReturn(0); 8749 } 8750 8751 /*@ 8752 MatIsHermitian - Test whether a matrix is Hermitian 8753 8754 Collective on Mat 8755 8756 Input Parameter: 8757 + A - the matrix to test 8758 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8759 8760 Output Parameters: 8761 . flg - the result 8762 8763 Level: intermediate 8764 8765 Concepts: matrix^symmetry 8766 8767 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8768 MatIsSymmetricKnown(), MatIsSymmetric() 8769 @*/ 8770 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8771 { 8772 PetscErrorCode ierr; 8773 8774 PetscFunctionBegin; 8775 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8776 PetscValidPointer(flg,2); 8777 8778 if (!A->hermitian_set) { 8779 if (!A->ops->ishermitian) { 8780 MatType mattype; 8781 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8782 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8783 } 8784 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8785 if (!tol) { 8786 A->hermitian_set = PETSC_TRUE; 8787 A->hermitian = *flg; 8788 if (A->hermitian) { 8789 A->structurally_symmetric_set = PETSC_TRUE; 8790 A->structurally_symmetric = PETSC_TRUE; 8791 } 8792 } 8793 } else if (A->hermitian) { 8794 *flg = PETSC_TRUE; 8795 } else if (!tol) { 8796 *flg = PETSC_FALSE; 8797 } else { 8798 if (!A->ops->ishermitian) { 8799 MatType mattype; 8800 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8801 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8802 } 8803 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8804 } 8805 PetscFunctionReturn(0); 8806 } 8807 8808 /*@ 8809 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8810 8811 Not Collective 8812 8813 Input Parameter: 8814 . A - the matrix to check 8815 8816 Output Parameters: 8817 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8818 - flg - the result 8819 8820 Level: advanced 8821 8822 Concepts: matrix^symmetry 8823 8824 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8825 if you want it explicitly checked 8826 8827 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8828 @*/ 8829 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8830 { 8831 PetscFunctionBegin; 8832 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8833 PetscValidPointer(set,2); 8834 PetscValidPointer(flg,3); 8835 if (A->symmetric_set) { 8836 *set = PETSC_TRUE; 8837 *flg = A->symmetric; 8838 } else { 8839 *set = PETSC_FALSE; 8840 } 8841 PetscFunctionReturn(0); 8842 } 8843 8844 /*@ 8845 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8846 8847 Not Collective 8848 8849 Input Parameter: 8850 . A - the matrix to check 8851 8852 Output Parameters: 8853 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8854 - flg - the result 8855 8856 Level: advanced 8857 8858 Concepts: matrix^symmetry 8859 8860 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8861 if you want it explicitly checked 8862 8863 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8864 @*/ 8865 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8866 { 8867 PetscFunctionBegin; 8868 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8869 PetscValidPointer(set,2); 8870 PetscValidPointer(flg,3); 8871 if (A->hermitian_set) { 8872 *set = PETSC_TRUE; 8873 *flg = A->hermitian; 8874 } else { 8875 *set = PETSC_FALSE; 8876 } 8877 PetscFunctionReturn(0); 8878 } 8879 8880 /*@ 8881 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8882 8883 Collective on Mat 8884 8885 Input Parameter: 8886 . A - the matrix to test 8887 8888 Output Parameters: 8889 . flg - the result 8890 8891 Level: intermediate 8892 8893 Concepts: matrix^symmetry 8894 8895 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8896 @*/ 8897 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8898 { 8899 PetscErrorCode ierr; 8900 8901 PetscFunctionBegin; 8902 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8903 PetscValidPointer(flg,2); 8904 if (!A->structurally_symmetric_set) { 8905 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8906 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8907 8908 A->structurally_symmetric_set = PETSC_TRUE; 8909 } 8910 *flg = A->structurally_symmetric; 8911 PetscFunctionReturn(0); 8912 } 8913 8914 /*@ 8915 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8916 to be communicated to other processors during the MatAssemblyBegin/End() process 8917 8918 Not collective 8919 8920 Input Parameter: 8921 . vec - the vector 8922 8923 Output Parameters: 8924 + nstash - the size of the stash 8925 . reallocs - the number of additional mallocs incurred. 8926 . bnstash - the size of the block stash 8927 - breallocs - the number of additional mallocs incurred.in the block stash 8928 8929 Level: advanced 8930 8931 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8932 8933 @*/ 8934 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8935 { 8936 PetscErrorCode ierr; 8937 8938 PetscFunctionBegin; 8939 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8940 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8941 PetscFunctionReturn(0); 8942 } 8943 8944 /*@C 8945 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8946 parallel layout 8947 8948 Collective on Mat 8949 8950 Input Parameter: 8951 . mat - the matrix 8952 8953 Output Parameter: 8954 + right - (optional) vector that the matrix can be multiplied against 8955 - left - (optional) vector that the matrix vector product can be stored in 8956 8957 Notes: 8958 The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize(). 8959 8960 Notes: 8961 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8962 8963 Level: advanced 8964 8965 .seealso: MatCreate(), VecDestroy() 8966 @*/ 8967 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8968 { 8969 PetscErrorCode ierr; 8970 8971 PetscFunctionBegin; 8972 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8973 PetscValidType(mat,1); 8974 if (mat->ops->getvecs) { 8975 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8976 } else { 8977 PetscInt rbs,cbs; 8978 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8979 if (right) { 8980 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8981 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8982 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8983 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8984 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8985 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8986 } 8987 if (left) { 8988 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8989 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8990 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8991 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8992 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8993 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8994 } 8995 } 8996 PetscFunctionReturn(0); 8997 } 8998 8999 /*@C 9000 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9001 with default values. 9002 9003 Not Collective 9004 9005 Input Parameters: 9006 . info - the MatFactorInfo data structure 9007 9008 9009 Notes: 9010 The solvers are generally used through the KSP and PC objects, for example 9011 PCLU, PCILU, PCCHOLESKY, PCICC 9012 9013 Level: developer 9014 9015 .seealso: MatFactorInfo 9016 9017 Developer Note: fortran interface is not autogenerated as the f90 9018 interface defintion cannot be generated correctly [due to MatFactorInfo] 9019 9020 @*/ 9021 9022 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9023 { 9024 PetscErrorCode ierr; 9025 9026 PetscFunctionBegin; 9027 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 9028 PetscFunctionReturn(0); 9029 } 9030 9031 /*@ 9032 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9033 9034 Collective on Mat 9035 9036 Input Parameters: 9037 + mat - the factored matrix 9038 - is - the index set defining the Schur indices (0-based) 9039 9040 Notes: 9041 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9042 9043 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9044 9045 Level: developer 9046 9047 Concepts: 9048 9049 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 9050 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 9051 9052 @*/ 9053 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9054 { 9055 PetscErrorCode ierr,(*f)(Mat,IS); 9056 9057 PetscFunctionBegin; 9058 PetscValidType(mat,1); 9059 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9060 PetscValidType(is,2); 9061 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9062 PetscCheckSameComm(mat,1,is,2); 9063 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9064 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 9065 if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9066 if (mat->schur) { 9067 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 9068 } 9069 ierr = (*f)(mat,is);CHKERRQ(ierr); 9070 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9071 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 9072 PetscFunctionReturn(0); 9073 } 9074 9075 /*@ 9076 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9077 9078 Logically Collective on Mat 9079 9080 Input Parameters: 9081 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9082 . S - location where to return the Schur complement, can be NULL 9083 - status - the status of the Schur complement matrix, can be NULL 9084 9085 Notes: 9086 You must call MatFactorSetSchurIS() before calling this routine. 9087 9088 The routine provides a copy of the Schur matrix stored within the solver data structures. 9089 The caller must destroy the object when it is no longer needed. 9090 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9091 9092 Use MatFactorGetSchurComplement() to get access to the Schur complement matrix inside the factored matrix instead of making a copy of it (which this function does) 9093 9094 Developer Notes: 9095 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9096 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9097 9098 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9099 9100 Level: advanced 9101 9102 References: 9103 9104 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9105 @*/ 9106 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9107 { 9108 PetscErrorCode ierr; 9109 9110 PetscFunctionBegin; 9111 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9112 if (S) PetscValidPointer(S,2); 9113 if (status) PetscValidPointer(status,3); 9114 if (S) { 9115 PetscErrorCode (*f)(Mat,Mat*); 9116 9117 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9118 if (f) { 9119 ierr = (*f)(F,S);CHKERRQ(ierr); 9120 } else { 9121 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9122 } 9123 } 9124 if (status) *status = F->schur_status; 9125 PetscFunctionReturn(0); 9126 } 9127 9128 /*@ 9129 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9130 9131 Logically Collective on Mat 9132 9133 Input Parameters: 9134 + F - the factored matrix obtained by calling MatGetFactor() 9135 . *S - location where to return the Schur complement, can be NULL 9136 - status - the status of the Schur complement matrix, can be NULL 9137 9138 Notes: 9139 You must call MatFactorSetSchurIS() before calling this routine. 9140 9141 Schur complement mode is currently implemented for sequential matrices. 9142 The routine returns a the Schur Complement stored within the data strutures of the solver. 9143 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9144 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9145 9146 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9147 9148 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9149 9150 Level: advanced 9151 9152 References: 9153 9154 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9155 @*/ 9156 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9157 { 9158 PetscFunctionBegin; 9159 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9160 if (S) PetscValidPointer(S,2); 9161 if (status) PetscValidPointer(status,3); 9162 if (S) *S = F->schur; 9163 if (status) *status = F->schur_status; 9164 PetscFunctionReturn(0); 9165 } 9166 9167 /*@ 9168 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9169 9170 Logically Collective on Mat 9171 9172 Input Parameters: 9173 + F - the factored matrix obtained by calling MatGetFactor() 9174 . *S - location where the Schur complement is stored 9175 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9176 9177 Notes: 9178 9179 Level: advanced 9180 9181 References: 9182 9183 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9184 @*/ 9185 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9186 { 9187 PetscErrorCode ierr; 9188 9189 PetscFunctionBegin; 9190 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9191 if (S) { 9192 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9193 *S = NULL; 9194 } 9195 F->schur_status = status; 9196 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9197 PetscFunctionReturn(0); 9198 } 9199 9200 /*@ 9201 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9202 9203 Logically Collective on Mat 9204 9205 Input Parameters: 9206 + F - the factored matrix obtained by calling MatGetFactor() 9207 . rhs - location where the right hand side of the Schur complement system is stored 9208 - sol - location where the solution of the Schur complement system has to be returned 9209 9210 Notes: 9211 The sizes of the vectors should match the size of the Schur complement 9212 9213 Must be called after MatFactorSetSchurIS() 9214 9215 Level: advanced 9216 9217 References: 9218 9219 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9220 @*/ 9221 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9222 { 9223 PetscErrorCode ierr; 9224 9225 PetscFunctionBegin; 9226 PetscValidType(F,1); 9227 PetscValidType(rhs,2); 9228 PetscValidType(sol,3); 9229 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9230 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9231 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9232 PetscCheckSameComm(F,1,rhs,2); 9233 PetscCheckSameComm(F,1,sol,3); 9234 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9235 switch (F->schur_status) { 9236 case MAT_FACTOR_SCHUR_FACTORED: 9237 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9238 break; 9239 case MAT_FACTOR_SCHUR_INVERTED: 9240 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9241 break; 9242 default: 9243 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9244 break; 9245 } 9246 PetscFunctionReturn(0); 9247 } 9248 9249 /*@ 9250 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9251 9252 Logically Collective on Mat 9253 9254 Input Parameters: 9255 + F - the factored matrix obtained by calling MatGetFactor() 9256 . rhs - location where the right hand side of the Schur complement system is stored 9257 - sol - location where the solution of the Schur complement system has to be returned 9258 9259 Notes: 9260 The sizes of the vectors should match the size of the Schur complement 9261 9262 Must be called after MatFactorSetSchurIS() 9263 9264 Level: advanced 9265 9266 References: 9267 9268 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9269 @*/ 9270 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9271 { 9272 PetscErrorCode ierr; 9273 9274 PetscFunctionBegin; 9275 PetscValidType(F,1); 9276 PetscValidType(rhs,2); 9277 PetscValidType(sol,3); 9278 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9279 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9280 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9281 PetscCheckSameComm(F,1,rhs,2); 9282 PetscCheckSameComm(F,1,sol,3); 9283 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9284 switch (F->schur_status) { 9285 case MAT_FACTOR_SCHUR_FACTORED: 9286 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9287 break; 9288 case MAT_FACTOR_SCHUR_INVERTED: 9289 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9290 break; 9291 default: 9292 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9293 break; 9294 } 9295 PetscFunctionReturn(0); 9296 } 9297 9298 /*@ 9299 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9300 9301 Logically Collective on Mat 9302 9303 Input Parameters: 9304 + F - the factored matrix obtained by calling MatGetFactor() 9305 9306 Notes: 9307 Must be called after MatFactorSetSchurIS(). 9308 9309 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9310 9311 Level: advanced 9312 9313 References: 9314 9315 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9316 @*/ 9317 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9318 { 9319 PetscErrorCode ierr; 9320 9321 PetscFunctionBegin; 9322 PetscValidType(F,1); 9323 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9324 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9325 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9326 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9327 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9328 PetscFunctionReturn(0); 9329 } 9330 9331 /*@ 9332 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9333 9334 Logically Collective on Mat 9335 9336 Input Parameters: 9337 + F - the factored matrix obtained by calling MatGetFactor() 9338 9339 Notes: 9340 Must be called after MatFactorSetSchurIS(). 9341 9342 Level: advanced 9343 9344 References: 9345 9346 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9347 @*/ 9348 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9349 { 9350 PetscErrorCode ierr; 9351 9352 PetscFunctionBegin; 9353 PetscValidType(F,1); 9354 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9355 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9356 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9357 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9358 PetscFunctionReturn(0); 9359 } 9360 9361 /*@ 9362 MatPtAP - Creates the matrix product C = P^T * A * P 9363 9364 Neighbor-wise Collective on Mat 9365 9366 Input Parameters: 9367 + A - the matrix 9368 . P - the projection matrix 9369 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9370 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9371 if the result is a dense matrix this is irrelevent 9372 9373 Output Parameters: 9374 . C - the product matrix 9375 9376 Notes: 9377 C will be created and must be destroyed by the user with MatDestroy(). 9378 9379 This routine is currently only implemented for pairs of sequential dense matrices, AIJ matrices and classes 9380 which inherit from AIJ. 9381 9382 Level: intermediate 9383 9384 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9385 @*/ 9386 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9387 { 9388 PetscErrorCode ierr; 9389 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9390 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9391 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9392 PetscBool sametype; 9393 9394 PetscFunctionBegin; 9395 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9396 PetscValidType(A,1); 9397 MatCheckPreallocated(A,1); 9398 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9399 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9400 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9401 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9402 PetscValidType(P,2); 9403 MatCheckPreallocated(P,2); 9404 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9405 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9406 9407 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); 9408 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); 9409 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9410 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9411 9412 if (scall == MAT_REUSE_MATRIX) { 9413 PetscValidPointer(*C,5); 9414 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9415 9416 if (!(*C)->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You cannot use MAT_REUSE_MATRIX"); 9417 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9418 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9419 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9420 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9421 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9422 PetscFunctionReturn(0); 9423 } 9424 9425 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9426 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9427 9428 fA = A->ops->ptap; 9429 fP = P->ops->ptap; 9430 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9431 if (fP == fA && sametype) { 9432 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9433 ptap = fA; 9434 } else { 9435 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9436 char ptapname[256]; 9437 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9438 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9439 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9440 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9441 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9442 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9443 if (!ptap) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatPtAP requires A, %s, to be compatible with P, %s (Misses composed function %s)",((PetscObject)A)->type_name,((PetscObject)P)->type_name,ptapname); 9444 } 9445 9446 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9447 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9448 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9449 if (A->symmetric_set && A->symmetric) { 9450 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9451 } 9452 PetscFunctionReturn(0); 9453 } 9454 9455 /*@ 9456 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9457 9458 Neighbor-wise Collective on Mat 9459 9460 Input Parameters: 9461 + A - the matrix 9462 - P - the projection matrix 9463 9464 Output Parameters: 9465 . C - the product matrix 9466 9467 Notes: 9468 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9469 the user using MatDeatroy(). 9470 9471 This routine is currently only implemented for pairs of AIJ matrices and classes 9472 which inherit from AIJ. C will be of type MATAIJ. 9473 9474 Level: intermediate 9475 9476 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9477 @*/ 9478 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9479 { 9480 PetscErrorCode ierr; 9481 9482 PetscFunctionBegin; 9483 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9484 PetscValidType(A,1); 9485 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9486 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9487 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9488 PetscValidType(P,2); 9489 MatCheckPreallocated(P,2); 9490 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9491 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9492 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9493 PetscValidType(C,3); 9494 MatCheckPreallocated(C,3); 9495 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9496 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); 9497 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); 9498 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); 9499 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); 9500 MatCheckPreallocated(A,1); 9501 9502 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9503 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9504 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9505 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9506 PetscFunctionReturn(0); 9507 } 9508 9509 /*@ 9510 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9511 9512 Neighbor-wise Collective on Mat 9513 9514 Input Parameters: 9515 + A - the matrix 9516 - P - the projection matrix 9517 9518 Output Parameters: 9519 . C - the (i,j) structure of the product matrix 9520 9521 Notes: 9522 C will be created and must be destroyed by the user with MatDestroy(). 9523 9524 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9525 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9526 this (i,j) structure by calling MatPtAPNumeric(). 9527 9528 Level: intermediate 9529 9530 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9531 @*/ 9532 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9533 { 9534 PetscErrorCode ierr; 9535 9536 PetscFunctionBegin; 9537 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9538 PetscValidType(A,1); 9539 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9540 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9541 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9542 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9543 PetscValidType(P,2); 9544 MatCheckPreallocated(P,2); 9545 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9546 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9547 PetscValidPointer(C,3); 9548 9549 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); 9550 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); 9551 MatCheckPreallocated(A,1); 9552 9553 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9554 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9555 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9556 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9557 9558 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9559 PetscFunctionReturn(0); 9560 } 9561 9562 /*@ 9563 MatRARt - Creates the matrix product C = R * A * R^T 9564 9565 Neighbor-wise Collective on Mat 9566 9567 Input Parameters: 9568 + A - the matrix 9569 . R - the projection matrix 9570 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9571 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9572 if the result is a dense matrix this is irrelevent 9573 9574 Output Parameters: 9575 . C - the product matrix 9576 9577 Notes: 9578 C will be created and must be destroyed by the user with MatDestroy(). 9579 9580 This routine is currently only implemented for pairs of AIJ matrices and classes 9581 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9582 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9583 We recommend using MatPtAP(). 9584 9585 Level: intermediate 9586 9587 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9588 @*/ 9589 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9590 { 9591 PetscErrorCode ierr; 9592 9593 PetscFunctionBegin; 9594 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9595 PetscValidType(A,1); 9596 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9597 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9598 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9599 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9600 PetscValidType(R,2); 9601 MatCheckPreallocated(R,2); 9602 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9603 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9604 PetscValidPointer(C,3); 9605 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); 9606 9607 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9608 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9609 MatCheckPreallocated(A,1); 9610 9611 if (!A->ops->rart) { 9612 Mat Rt; 9613 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9614 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9615 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9616 PetscFunctionReturn(0); 9617 } 9618 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9619 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9620 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9621 PetscFunctionReturn(0); 9622 } 9623 9624 /*@ 9625 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9626 9627 Neighbor-wise Collective on Mat 9628 9629 Input Parameters: 9630 + A - the matrix 9631 - R - the projection matrix 9632 9633 Output Parameters: 9634 . C - the product matrix 9635 9636 Notes: 9637 C must have been created by calling MatRARtSymbolic and must be destroyed by 9638 the user using MatDestroy(). 9639 9640 This routine is currently only implemented for pairs of AIJ matrices and classes 9641 which inherit from AIJ. C will be of type MATAIJ. 9642 9643 Level: intermediate 9644 9645 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9646 @*/ 9647 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9648 { 9649 PetscErrorCode ierr; 9650 9651 PetscFunctionBegin; 9652 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9653 PetscValidType(A,1); 9654 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9655 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9656 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9657 PetscValidType(R,2); 9658 MatCheckPreallocated(R,2); 9659 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9660 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9661 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9662 PetscValidType(C,3); 9663 MatCheckPreallocated(C,3); 9664 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9665 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); 9666 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); 9667 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); 9668 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); 9669 MatCheckPreallocated(A,1); 9670 9671 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9672 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9673 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9674 PetscFunctionReturn(0); 9675 } 9676 9677 /*@ 9678 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9679 9680 Neighbor-wise Collective on Mat 9681 9682 Input Parameters: 9683 + A - the matrix 9684 - R - the projection matrix 9685 9686 Output Parameters: 9687 . C - the (i,j) structure of the product matrix 9688 9689 Notes: 9690 C will be created and must be destroyed by the user with MatDestroy(). 9691 9692 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9693 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9694 this (i,j) structure by calling MatRARtNumeric(). 9695 9696 Level: intermediate 9697 9698 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9699 @*/ 9700 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9701 { 9702 PetscErrorCode ierr; 9703 9704 PetscFunctionBegin; 9705 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9706 PetscValidType(A,1); 9707 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9708 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9709 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9710 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9711 PetscValidType(R,2); 9712 MatCheckPreallocated(R,2); 9713 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9714 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9715 PetscValidPointer(C,3); 9716 9717 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); 9718 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); 9719 MatCheckPreallocated(A,1); 9720 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9721 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9722 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9723 9724 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9725 PetscFunctionReturn(0); 9726 } 9727 9728 /*@ 9729 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9730 9731 Neighbor-wise Collective on Mat 9732 9733 Input Parameters: 9734 + A - the left matrix 9735 . B - the right matrix 9736 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9737 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9738 if the result is a dense matrix this is irrelevent 9739 9740 Output Parameters: 9741 . C - the product matrix 9742 9743 Notes: 9744 Unless scall is MAT_REUSE_MATRIX C will be created. 9745 9746 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call and C was obtained from a previous 9747 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9748 9749 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9750 actually needed. 9751 9752 If you have many matrices with the same non-zero structure to multiply, you 9753 should either 9754 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9755 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9756 In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine 9757 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9758 9759 Level: intermediate 9760 9761 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9762 @*/ 9763 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9764 { 9765 PetscErrorCode ierr; 9766 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9767 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9768 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9769 9770 PetscFunctionBegin; 9771 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9772 PetscValidType(A,1); 9773 MatCheckPreallocated(A,1); 9774 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9775 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9776 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9777 PetscValidType(B,2); 9778 MatCheckPreallocated(B,2); 9779 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9780 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9781 PetscValidPointer(C,3); 9782 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9783 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); 9784 if (scall == MAT_REUSE_MATRIX) { 9785 PetscValidPointer(*C,5); 9786 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9787 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9788 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9789 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9790 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9791 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9792 PetscFunctionReturn(0); 9793 } 9794 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9795 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9796 9797 fA = A->ops->matmult; 9798 fB = B->ops->matmult; 9799 if (fB == fA) { 9800 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9801 mult = fB; 9802 } else { 9803 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9804 char multname[256]; 9805 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9806 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9807 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9808 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9809 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9810 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9811 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); 9812 } 9813 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9814 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9815 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9816 PetscFunctionReturn(0); 9817 } 9818 9819 /*@ 9820 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9821 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9822 9823 Neighbor-wise Collective on Mat 9824 9825 Input Parameters: 9826 + A - the left matrix 9827 . B - the right matrix 9828 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9829 if C is a dense matrix this is irrelevent 9830 9831 Output Parameters: 9832 . C - the product matrix 9833 9834 Notes: 9835 Unless scall is MAT_REUSE_MATRIX C will be created. 9836 9837 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9838 actually needed. 9839 9840 This routine is currently implemented for 9841 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9842 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9843 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9844 9845 Level: intermediate 9846 9847 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9848 We should incorporate them into PETSc. 9849 9850 .seealso: MatMatMult(), MatMatMultNumeric() 9851 @*/ 9852 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9853 { 9854 PetscErrorCode ierr; 9855 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9856 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9857 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9858 9859 PetscFunctionBegin; 9860 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9861 PetscValidType(A,1); 9862 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9863 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9864 9865 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9866 PetscValidType(B,2); 9867 MatCheckPreallocated(B,2); 9868 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9869 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9870 PetscValidPointer(C,3); 9871 9872 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); 9873 if (fill == PETSC_DEFAULT) fill = 2.0; 9874 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9875 MatCheckPreallocated(A,1); 9876 9877 Asymbolic = A->ops->matmultsymbolic; 9878 Bsymbolic = B->ops->matmultsymbolic; 9879 if (Asymbolic == Bsymbolic) { 9880 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9881 symbolic = Bsymbolic; 9882 } else { /* dispatch based on the type of A and B */ 9883 char symbolicname[256]; 9884 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9885 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9886 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9887 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9888 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9889 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9890 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); 9891 } 9892 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9893 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9894 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9895 PetscFunctionReturn(0); 9896 } 9897 9898 /*@ 9899 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9900 Call this routine after first calling MatMatMultSymbolic(). 9901 9902 Neighbor-wise Collective on Mat 9903 9904 Input Parameters: 9905 + A - the left matrix 9906 - B - the right matrix 9907 9908 Output Parameters: 9909 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9910 9911 Notes: 9912 C must have been created with MatMatMultSymbolic(). 9913 9914 This routine is currently implemented for 9915 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9916 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9917 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9918 9919 Level: intermediate 9920 9921 .seealso: MatMatMult(), MatMatMultSymbolic() 9922 @*/ 9923 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9924 { 9925 PetscErrorCode ierr; 9926 9927 PetscFunctionBegin; 9928 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9929 PetscFunctionReturn(0); 9930 } 9931 9932 /*@ 9933 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9934 9935 Neighbor-wise Collective on Mat 9936 9937 Input Parameters: 9938 + A - the left matrix 9939 . B - the right matrix 9940 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9941 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9942 9943 Output Parameters: 9944 . C - the product matrix 9945 9946 Notes: 9947 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9948 9949 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9950 9951 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9952 actually needed. 9953 9954 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9955 and for pairs of MPIDense matrices. 9956 9957 Options Database Keys: 9958 + -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9959 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9960 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9961 9962 Level: intermediate 9963 9964 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9965 @*/ 9966 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9967 { 9968 PetscErrorCode ierr; 9969 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9970 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9971 9972 PetscFunctionBegin; 9973 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9974 PetscValidType(A,1); 9975 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9976 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9977 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9978 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9979 PetscValidType(B,2); 9980 MatCheckPreallocated(B,2); 9981 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9982 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9983 PetscValidPointer(C,3); 9984 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); 9985 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9986 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9987 MatCheckPreallocated(A,1); 9988 9989 fA = A->ops->mattransposemult; 9990 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9991 fB = B->ops->mattransposemult; 9992 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9993 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); 9994 9995 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9996 if (scall == MAT_INITIAL_MATRIX) { 9997 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9998 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9999 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 10000 } 10001 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 10002 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 10003 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 10004 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 10005 PetscFunctionReturn(0); 10006 } 10007 10008 /*@ 10009 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 10010 10011 Neighbor-wise Collective on Mat 10012 10013 Input Parameters: 10014 + A - the left matrix 10015 . B - the right matrix 10016 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10017 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 10018 10019 Output Parameters: 10020 . C - the product matrix 10021 10022 Notes: 10023 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 10024 10025 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 10026 10027 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10028 actually needed. 10029 10030 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 10031 which inherit from SeqAIJ. C will be of same type as the input matrices. 10032 10033 Level: intermediate 10034 10035 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 10036 @*/ 10037 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 10038 { 10039 PetscErrorCode ierr; 10040 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 10041 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 10042 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 10043 10044 PetscFunctionBegin; 10045 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10046 PetscValidType(A,1); 10047 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10048 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10049 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10050 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10051 PetscValidType(B,2); 10052 MatCheckPreallocated(B,2); 10053 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10054 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10055 PetscValidPointer(C,3); 10056 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); 10057 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10058 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 10059 MatCheckPreallocated(A,1); 10060 10061 fA = A->ops->transposematmult; 10062 fB = B->ops->transposematmult; 10063 if (fB==fA) { 10064 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10065 transposematmult = fA; 10066 } else { 10067 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 10068 char multname[256]; 10069 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 10070 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10071 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10072 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10073 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 10074 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 10075 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); 10076 } 10077 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10078 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 10079 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 10080 PetscFunctionReturn(0); 10081 } 10082 10083 /*@ 10084 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 10085 10086 Neighbor-wise Collective on Mat 10087 10088 Input Parameters: 10089 + A - the left matrix 10090 . B - the middle matrix 10091 . C - the right matrix 10092 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10093 - 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 10094 if the result is a dense matrix this is irrelevent 10095 10096 Output Parameters: 10097 . D - the product matrix 10098 10099 Notes: 10100 Unless scall is MAT_REUSE_MATRIX D will be created. 10101 10102 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 10103 10104 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 10105 actually needed. 10106 10107 If you have many matrices with the same non-zero structure to multiply, you 10108 should use MAT_REUSE_MATRIX in all calls but the first or 10109 10110 Level: intermediate 10111 10112 .seealso: MatMatMult, MatPtAP() 10113 @*/ 10114 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 10115 { 10116 PetscErrorCode ierr; 10117 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10118 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10119 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 10120 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 10121 10122 PetscFunctionBegin; 10123 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10124 PetscValidType(A,1); 10125 MatCheckPreallocated(A,1); 10126 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10127 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10128 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10129 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10130 PetscValidType(B,2); 10131 MatCheckPreallocated(B,2); 10132 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10133 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10134 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10135 PetscValidPointer(C,3); 10136 MatCheckPreallocated(C,3); 10137 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10138 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10139 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); 10140 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); 10141 if (scall == MAT_REUSE_MATRIX) { 10142 PetscValidPointer(*D,6); 10143 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 10144 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10145 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10146 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10147 PetscFunctionReturn(0); 10148 } 10149 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 10150 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 10151 10152 fA = A->ops->matmatmult; 10153 fB = B->ops->matmatmult; 10154 fC = C->ops->matmatmult; 10155 if (fA == fB && fA == fC) { 10156 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 10157 mult = fA; 10158 } else { 10159 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 10160 char multname[256]; 10161 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 10162 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 10163 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10164 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 10165 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 10166 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 10167 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 10168 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 10169 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); 10170 } 10171 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10172 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 10173 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 10174 PetscFunctionReturn(0); 10175 } 10176 10177 /*@ 10178 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10179 10180 Collective on Mat 10181 10182 Input Parameters: 10183 + mat - the matrix 10184 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10185 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10186 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10187 10188 Output Parameter: 10189 . matredundant - redundant matrix 10190 10191 Notes: 10192 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10193 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10194 10195 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10196 calling it. 10197 10198 Level: advanced 10199 10200 Concepts: subcommunicator 10201 Concepts: duplicate matrix 10202 10203 .seealso: MatDestroy() 10204 @*/ 10205 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10206 { 10207 PetscErrorCode ierr; 10208 MPI_Comm comm; 10209 PetscMPIInt size; 10210 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10211 Mat_Redundant *redund=NULL; 10212 PetscSubcomm psubcomm=NULL; 10213 MPI_Comm subcomm_in=subcomm; 10214 Mat *matseq; 10215 IS isrow,iscol; 10216 PetscBool newsubcomm=PETSC_FALSE; 10217 10218 PetscFunctionBegin; 10219 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10220 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10221 PetscValidPointer(*matredundant,5); 10222 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10223 } 10224 10225 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10226 if (size == 1 || nsubcomm == 1) { 10227 if (reuse == MAT_INITIAL_MATRIX) { 10228 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10229 } else { 10230 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10231 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10232 } 10233 PetscFunctionReturn(0); 10234 } 10235 10236 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10237 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10238 MatCheckPreallocated(mat,1); 10239 10240 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10241 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10242 /* create psubcomm, then get subcomm */ 10243 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10244 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10245 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10246 10247 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10248 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10249 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10250 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10251 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10252 newsubcomm = PETSC_TRUE; 10253 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10254 } 10255 10256 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10257 if (reuse == MAT_INITIAL_MATRIX) { 10258 mloc_sub = PETSC_DECIDE; 10259 nloc_sub = PETSC_DECIDE; 10260 if (bs < 1) { 10261 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10262 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10263 } else { 10264 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10265 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10266 } 10267 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10268 rstart = rend - mloc_sub; 10269 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10270 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10271 } else { /* reuse == MAT_REUSE_MATRIX */ 10272 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10273 /* retrieve subcomm */ 10274 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10275 redund = (*matredundant)->redundant; 10276 isrow = redund->isrow; 10277 iscol = redund->iscol; 10278 matseq = redund->matseq; 10279 } 10280 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10281 10282 /* get matredundant over subcomm */ 10283 if (reuse == MAT_INITIAL_MATRIX) { 10284 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10285 10286 /* create a supporting struct and attach it to C for reuse */ 10287 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10288 (*matredundant)->redundant = redund; 10289 redund->isrow = isrow; 10290 redund->iscol = iscol; 10291 redund->matseq = matseq; 10292 if (newsubcomm) { 10293 redund->subcomm = subcomm; 10294 } else { 10295 redund->subcomm = MPI_COMM_NULL; 10296 } 10297 } else { 10298 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10299 } 10300 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10301 PetscFunctionReturn(0); 10302 } 10303 10304 /*@C 10305 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10306 a given 'mat' object. Each submatrix can span multiple procs. 10307 10308 Collective on Mat 10309 10310 Input Parameters: 10311 + mat - the matrix 10312 . subcomm - the subcommunicator obtained by com_split(comm) 10313 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10314 10315 Output Parameter: 10316 . subMat - 'parallel submatrices each spans a given subcomm 10317 10318 Notes: 10319 The submatrix partition across processors is dictated by 'subComm' a 10320 communicator obtained by com_split(comm). The comm_split 10321 is not restriced to be grouped with consecutive original ranks. 10322 10323 Due the comm_split() usage, the parallel layout of the submatrices 10324 map directly to the layout of the original matrix [wrt the local 10325 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10326 into the 'DiagonalMat' of the subMat, hence it is used directly from 10327 the subMat. However the offDiagMat looses some columns - and this is 10328 reconstructed with MatSetValues() 10329 10330 Level: advanced 10331 10332 Concepts: subcommunicator 10333 Concepts: submatrices 10334 10335 .seealso: MatCreateSubMatrices() 10336 @*/ 10337 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10338 { 10339 PetscErrorCode ierr; 10340 PetscMPIInt commsize,subCommSize; 10341 10342 PetscFunctionBegin; 10343 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10344 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10345 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10346 10347 if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10348 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10349 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10350 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10351 PetscFunctionReturn(0); 10352 } 10353 10354 /*@ 10355 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10356 10357 Not Collective 10358 10359 Input Arguments: 10360 mat - matrix to extract local submatrix from 10361 isrow - local row indices for submatrix 10362 iscol - local column indices for submatrix 10363 10364 Output Arguments: 10365 submat - the submatrix 10366 10367 Level: intermediate 10368 10369 Notes: 10370 The submat should be returned with MatRestoreLocalSubMatrix(). 10371 10372 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10373 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10374 10375 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10376 MatSetValuesBlockedLocal() will also be implemented. 10377 10378 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10379 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10380 10381 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10382 @*/ 10383 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10384 { 10385 PetscErrorCode ierr; 10386 10387 PetscFunctionBegin; 10388 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10389 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10390 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10391 PetscCheckSameComm(isrow,2,iscol,3); 10392 PetscValidPointer(submat,4); 10393 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10394 10395 if (mat->ops->getlocalsubmatrix) { 10396 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10397 } else { 10398 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10399 } 10400 PetscFunctionReturn(0); 10401 } 10402 10403 /*@ 10404 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10405 10406 Not Collective 10407 10408 Input Arguments: 10409 mat - matrix to extract local submatrix from 10410 isrow - local row indices for submatrix 10411 iscol - local column indices for submatrix 10412 submat - the submatrix 10413 10414 Level: intermediate 10415 10416 .seealso: MatGetLocalSubMatrix() 10417 @*/ 10418 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10419 { 10420 PetscErrorCode ierr; 10421 10422 PetscFunctionBegin; 10423 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10424 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10425 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10426 PetscCheckSameComm(isrow,2,iscol,3); 10427 PetscValidPointer(submat,4); 10428 if (*submat) { 10429 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10430 } 10431 10432 if (mat->ops->restorelocalsubmatrix) { 10433 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10434 } else { 10435 ierr = MatDestroy(submat);CHKERRQ(ierr); 10436 } 10437 *submat = NULL; 10438 PetscFunctionReturn(0); 10439 } 10440 10441 /* --------------------------------------------------------*/ 10442 /*@ 10443 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10444 10445 Collective on Mat 10446 10447 Input Parameter: 10448 . mat - the matrix 10449 10450 Output Parameter: 10451 . is - if any rows have zero diagonals this contains the list of them 10452 10453 Level: developer 10454 10455 Concepts: matrix-vector product 10456 10457 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10458 @*/ 10459 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10460 { 10461 PetscErrorCode ierr; 10462 10463 PetscFunctionBegin; 10464 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10465 PetscValidType(mat,1); 10466 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10467 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10468 10469 if (!mat->ops->findzerodiagonals) { 10470 Vec diag; 10471 const PetscScalar *a; 10472 PetscInt *rows; 10473 PetscInt rStart, rEnd, r, nrow = 0; 10474 10475 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10476 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10477 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10478 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10479 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10480 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10481 nrow = 0; 10482 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10483 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10484 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10485 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10486 } else { 10487 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10488 } 10489 PetscFunctionReturn(0); 10490 } 10491 10492 /*@ 10493 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10494 10495 Collective on Mat 10496 10497 Input Parameter: 10498 . mat - the matrix 10499 10500 Output Parameter: 10501 . is - contains the list of rows with off block diagonal entries 10502 10503 Level: developer 10504 10505 Concepts: matrix-vector product 10506 10507 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10508 @*/ 10509 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10510 { 10511 PetscErrorCode ierr; 10512 10513 PetscFunctionBegin; 10514 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10515 PetscValidType(mat,1); 10516 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10517 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10518 10519 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10520 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10521 PetscFunctionReturn(0); 10522 } 10523 10524 /*@C 10525 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10526 10527 Collective on Mat 10528 10529 Input Parameters: 10530 . mat - the matrix 10531 10532 Output Parameters: 10533 . values - the block inverses in column major order (FORTRAN-like) 10534 10535 Note: 10536 This routine is not available from Fortran. 10537 10538 Level: advanced 10539 10540 .seealso: MatInvertBockDiagonalMat 10541 @*/ 10542 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10543 { 10544 PetscErrorCode ierr; 10545 10546 PetscFunctionBegin; 10547 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10548 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10549 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10550 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10551 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10552 PetscFunctionReturn(0); 10553 } 10554 10555 /*@C 10556 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10557 10558 Collective on Mat 10559 10560 Input Parameters: 10561 + mat - the matrix 10562 . nblocks - the number of blocks 10563 - bsizes - the size of each block 10564 10565 Output Parameters: 10566 . values - the block inverses in column major order (FORTRAN-like) 10567 10568 Note: 10569 This routine is not available from Fortran. 10570 10571 Level: advanced 10572 10573 .seealso: MatInvertBockDiagonal() 10574 @*/ 10575 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10576 { 10577 PetscErrorCode ierr; 10578 10579 PetscFunctionBegin; 10580 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10581 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10582 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10583 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10584 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10585 PetscFunctionReturn(0); 10586 } 10587 10588 /*@ 10589 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10590 10591 Collective on Mat 10592 10593 Input Parameters: 10594 . A - the matrix 10595 10596 Output Parameters: 10597 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10598 10599 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10600 10601 Level: advanced 10602 10603 .seealso: MatInvertBockDiagonal() 10604 @*/ 10605 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10606 { 10607 PetscErrorCode ierr; 10608 const PetscScalar *vals; 10609 PetscInt *dnnz; 10610 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10611 10612 PetscFunctionBegin; 10613 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10614 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10615 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10616 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10617 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10618 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10619 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10620 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10621 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10622 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10623 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10624 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10625 for (i = rstart/bs; i < rend/bs; i++) { 10626 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10627 } 10628 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10629 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10630 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10631 PetscFunctionReturn(0); 10632 } 10633 10634 /*@C 10635 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10636 via MatTransposeColoringCreate(). 10637 10638 Collective on MatTransposeColoring 10639 10640 Input Parameter: 10641 . c - coloring context 10642 10643 Level: intermediate 10644 10645 .seealso: MatTransposeColoringCreate() 10646 @*/ 10647 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10648 { 10649 PetscErrorCode ierr; 10650 MatTransposeColoring matcolor=*c; 10651 10652 PetscFunctionBegin; 10653 if (!matcolor) PetscFunctionReturn(0); 10654 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10655 10656 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10657 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10658 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10659 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10660 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10661 if (matcolor->brows>0) { 10662 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10663 } 10664 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10665 PetscFunctionReturn(0); 10666 } 10667 10668 /*@C 10669 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10670 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10671 MatTransposeColoring to sparse B. 10672 10673 Collective on MatTransposeColoring 10674 10675 Input Parameters: 10676 + B - sparse matrix B 10677 . Btdense - symbolic dense matrix B^T 10678 - coloring - coloring context created with MatTransposeColoringCreate() 10679 10680 Output Parameter: 10681 . Btdense - dense matrix B^T 10682 10683 Level: advanced 10684 10685 Notes: 10686 These are used internally for some implementations of MatRARt() 10687 10688 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10689 10690 .keywords: coloring 10691 @*/ 10692 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10693 { 10694 PetscErrorCode ierr; 10695 10696 PetscFunctionBegin; 10697 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10698 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10699 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10700 10701 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10702 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10703 PetscFunctionReturn(0); 10704 } 10705 10706 /*@C 10707 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10708 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10709 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10710 Csp from Cden. 10711 10712 Collective on MatTransposeColoring 10713 10714 Input Parameters: 10715 + coloring - coloring context created with MatTransposeColoringCreate() 10716 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10717 10718 Output Parameter: 10719 . Csp - sparse matrix 10720 10721 Level: advanced 10722 10723 Notes: 10724 These are used internally for some implementations of MatRARt() 10725 10726 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10727 10728 .keywords: coloring 10729 @*/ 10730 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10731 { 10732 PetscErrorCode ierr; 10733 10734 PetscFunctionBegin; 10735 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10736 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10737 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10738 10739 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10740 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10741 PetscFunctionReturn(0); 10742 } 10743 10744 /*@C 10745 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10746 10747 Collective on Mat 10748 10749 Input Parameters: 10750 + mat - the matrix product C 10751 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10752 10753 Output Parameter: 10754 . color - the new coloring context 10755 10756 Level: intermediate 10757 10758 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10759 MatTransColoringApplyDenToSp() 10760 @*/ 10761 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10762 { 10763 MatTransposeColoring c; 10764 MPI_Comm comm; 10765 PetscErrorCode ierr; 10766 10767 PetscFunctionBegin; 10768 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10769 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10770 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10771 10772 c->ctype = iscoloring->ctype; 10773 if (mat->ops->transposecoloringcreate) { 10774 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10775 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10776 10777 *color = c; 10778 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10779 PetscFunctionReturn(0); 10780 } 10781 10782 /*@ 10783 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10784 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10785 same, otherwise it will be larger 10786 10787 Not Collective 10788 10789 Input Parameter: 10790 . A - the matrix 10791 10792 Output Parameter: 10793 . state - the current state 10794 10795 Notes: 10796 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10797 different matrices 10798 10799 Level: intermediate 10800 10801 @*/ 10802 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10803 { 10804 PetscFunctionBegin; 10805 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10806 *state = mat->nonzerostate; 10807 PetscFunctionReturn(0); 10808 } 10809 10810 /*@ 10811 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10812 matrices from each processor 10813 10814 Collective on MPI_Comm 10815 10816 Input Parameters: 10817 + comm - the communicators the parallel matrix will live on 10818 . seqmat - the input sequential matrices 10819 . n - number of local columns (or PETSC_DECIDE) 10820 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10821 10822 Output Parameter: 10823 . mpimat - the parallel matrix generated 10824 10825 Level: advanced 10826 10827 Notes: 10828 The number of columns of the matrix in EACH processor MUST be the same. 10829 10830 @*/ 10831 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10832 { 10833 PetscErrorCode ierr; 10834 10835 PetscFunctionBegin; 10836 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10837 if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10838 10839 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10840 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10841 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10842 PetscFunctionReturn(0); 10843 } 10844 10845 /*@ 10846 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10847 ranks' ownership ranges. 10848 10849 Collective on A 10850 10851 Input Parameters: 10852 + A - the matrix to create subdomains from 10853 - N - requested number of subdomains 10854 10855 10856 Output Parameters: 10857 + n - number of subdomains resulting on this rank 10858 - iss - IS list with indices of subdomains on this rank 10859 10860 Level: advanced 10861 10862 Notes: 10863 number of subdomains must be smaller than the communicator size 10864 @*/ 10865 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10866 { 10867 MPI_Comm comm,subcomm; 10868 PetscMPIInt size,rank,color; 10869 PetscInt rstart,rend,k; 10870 PetscErrorCode ierr; 10871 10872 PetscFunctionBegin; 10873 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10874 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10875 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10876 if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N); 10877 *n = 1; 10878 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10879 color = rank/k; 10880 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10881 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10882 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10883 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10884 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10885 PetscFunctionReturn(0); 10886 } 10887 10888 /*@ 10889 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10890 10891 If the interpolation and restriction operators are the same, uses MatPtAP. 10892 If they are not the same, use MatMatMatMult. 10893 10894 Once the coarse grid problem is constructed, correct for interpolation operators 10895 that are not of full rank, which can legitimately happen in the case of non-nested 10896 geometric multigrid. 10897 10898 Input Parameters: 10899 + restrct - restriction operator 10900 . dA - fine grid matrix 10901 . interpolate - interpolation operator 10902 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10903 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10904 10905 Output Parameters: 10906 . A - the Galerkin coarse matrix 10907 10908 Options Database Key: 10909 . -pc_mg_galerkin <both,pmat,mat,none> 10910 10911 Level: developer 10912 10913 .keywords: MG, multigrid, Galerkin 10914 10915 .seealso: MatPtAP(), MatMatMatMult() 10916 @*/ 10917 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10918 { 10919 PetscErrorCode ierr; 10920 IS zerorows; 10921 Vec diag; 10922 10923 PetscFunctionBegin; 10924 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10925 /* Construct the coarse grid matrix */ 10926 if (interpolate == restrct) { 10927 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10928 } else { 10929 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10930 } 10931 10932 /* If the interpolation matrix is not of full rank, A will have zero rows. 10933 This can legitimately happen in the case of non-nested geometric multigrid. 10934 In that event, we set the rows of the matrix to the rows of the identity, 10935 ignoring the equations (as the RHS will also be zero). */ 10936 10937 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10938 10939 if (zerorows != NULL) { /* if there are any zero rows */ 10940 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10941 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10942 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10943 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10944 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10945 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10946 } 10947 PetscFunctionReturn(0); 10948 } 10949 10950 /*@C 10951 MatSetOperation - Allows user to set a matrix operation for any matrix type 10952 10953 Logically Collective on Mat 10954 10955 Input Parameters: 10956 + mat - the matrix 10957 . op - the name of the operation 10958 - f - the function that provides the operation 10959 10960 Level: developer 10961 10962 Usage: 10963 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10964 $ ierr = MatCreateXXX(comm,...&A); 10965 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10966 10967 Notes: 10968 See the file include/petscmat.h for a complete list of matrix 10969 operations, which all have the form MATOP_<OPERATION>, where 10970 <OPERATION> is the name (in all capital letters) of the 10971 user interface routine (e.g., MatMult() -> MATOP_MULT). 10972 10973 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10974 sequence as the usual matrix interface routines, since they 10975 are intended to be accessed via the usual matrix interface 10976 routines, e.g., 10977 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10978 10979 In particular each function MUST return an error code of 0 on success and 10980 nonzero on failure. 10981 10982 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10983 10984 .keywords: matrix, set, operation 10985 10986 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10987 @*/ 10988 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10989 { 10990 PetscFunctionBegin; 10991 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10992 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10993 mat->ops->viewnative = mat->ops->view; 10994 } 10995 (((void(**)(void))mat->ops)[op]) = f; 10996 PetscFunctionReturn(0); 10997 } 10998 10999 /*@C 11000 MatGetOperation - Gets a matrix operation for any matrix type. 11001 11002 Not Collective 11003 11004 Input Parameters: 11005 + mat - the matrix 11006 - op - the name of the operation 11007 11008 Output Parameter: 11009 . f - the function that provides the operation 11010 11011 Level: developer 11012 11013 Usage: 11014 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 11015 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 11016 11017 Notes: 11018 See the file include/petscmat.h for a complete list of matrix 11019 operations, which all have the form MATOP_<OPERATION>, where 11020 <OPERATION> is the name (in all capital letters) of the 11021 user interface routine (e.g., MatMult() -> MATOP_MULT). 11022 11023 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 11024 11025 .keywords: matrix, get, operation 11026 11027 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 11028 @*/ 11029 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 11030 { 11031 PetscFunctionBegin; 11032 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11033 *f = (((void (**)(void))mat->ops)[op]); 11034 PetscFunctionReturn(0); 11035 } 11036 11037 /*@ 11038 MatHasOperation - Determines whether the given matrix supports the particular 11039 operation. 11040 11041 Not Collective 11042 11043 Input Parameters: 11044 + mat - the matrix 11045 - op - the operation, for example, MATOP_GET_DIAGONAL 11046 11047 Output Parameter: 11048 . has - either PETSC_TRUE or PETSC_FALSE 11049 11050 Level: advanced 11051 11052 Notes: 11053 See the file include/petscmat.h for a complete list of matrix 11054 operations, which all have the form MATOP_<OPERATION>, where 11055 <OPERATION> is the name (in all capital letters) of the 11056 user-level routine. E.g., MatNorm() -> MATOP_NORM. 11057 11058 .keywords: matrix, has, operation 11059 11060 .seealso: MatCreateShell() 11061 @*/ 11062 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 11063 { 11064 PetscErrorCode ierr; 11065 11066 PetscFunctionBegin; 11067 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11068 PetscValidType(mat,1); 11069 PetscValidPointer(has,3); 11070 if (mat->ops->hasoperation) { 11071 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 11072 } else { 11073 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 11074 else { 11075 *has = PETSC_FALSE; 11076 if (op == MATOP_CREATE_SUBMATRIX) { 11077 PetscMPIInt size; 11078 11079 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 11080 if (size == 1) { 11081 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 11082 } 11083 } 11084 } 11085 } 11086 PetscFunctionReturn(0); 11087 } 11088 11089 /*@ 11090 MatHasCongruentLayouts - Determines whether the rows and columns layouts 11091 of the matrix are congruent 11092 11093 Collective on mat 11094 11095 Input Parameters: 11096 . mat - the matrix 11097 11098 Output Parameter: 11099 . cong - either PETSC_TRUE or PETSC_FALSE 11100 11101 Level: beginner 11102 11103 Notes: 11104 11105 .keywords: matrix, has 11106 11107 .seealso: MatCreate(), MatSetSizes() 11108 @*/ 11109 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 11110 { 11111 PetscErrorCode ierr; 11112 11113 PetscFunctionBegin; 11114 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11115 PetscValidType(mat,1); 11116 PetscValidPointer(cong,2); 11117 if (!mat->rmap || !mat->cmap) { 11118 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 11119 PetscFunctionReturn(0); 11120 } 11121 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 11122 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 11123 if (*cong) mat->congruentlayouts = 1; 11124 else mat->congruentlayouts = 0; 11125 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 11126 PetscFunctionReturn(0); 11127 } 11128 11129 /*@ 11130 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 11131 e.g., matrx product of MatPtAP. 11132 11133 Collective on mat 11134 11135 Input Parameters: 11136 . mat - the matrix 11137 11138 Output Parameter: 11139 . mat - the matrix with intermediate data structures released 11140 11141 Level: advanced 11142 11143 Notes: 11144 11145 .keywords: matrix 11146 11147 .seealso: MatPtAP(), MatMatMult() 11148 @*/ 11149 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 11150 { 11151 PetscErrorCode ierr; 11152 11153 PetscFunctionBegin; 11154 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11155 PetscValidType(mat,1); 11156 if (mat->ops->freeintermediatedatastructures) { 11157 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 11158 } 11159 PetscFunctionReturn(0); 11160 } 11161