1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor; 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_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_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis; 36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO; 37 PetscLogEvent MAT_SetValuesBatch; 38 PetscLogEvent MAT_ViennaCLCopyToGPU; 39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 40 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 41 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 42 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 43 PetscLogEvent MAT_H2Opus_Build,MAT_H2Opus_Compress,MAT_H2Opus_Orthog,MAT_H2Opus_LR; 44 45 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL}; 46 47 /*@ 48 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 49 for sparse matrices that already have locations it fills the locations with random numbers 50 51 Logically Collective on Mat 52 53 Input Parameters: 54 + x - the matrix 55 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 56 it will create one internally. 57 58 Output Parameter: 59 . x - the matrix 60 61 Example of Usage: 62 .vb 63 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 64 MatSetRandom(x,rctx); 65 PetscRandomDestroy(rctx); 66 .ve 67 68 Level: intermediate 69 70 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 73 { 74 PetscErrorCode ierr; 75 PetscRandom randObj = NULL; 76 77 PetscFunctionBegin; 78 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 79 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 80 PetscValidType(x,1); 81 MatCheckPreallocated(x,1); 82 83 PetscCheckFalse(!x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 84 85 if (!rctx) { 86 MPI_Comm comm; 87 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 88 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 89 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 90 rctx = randObj; 91 } 92 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 93 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 94 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 95 96 ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 97 ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 98 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 /*@ 103 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 104 105 Logically Collective on Mat 106 107 Input Parameter: 108 . mat - the factored matrix 109 110 Output Parameters: 111 + pivot - the pivot value computed 112 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 113 the share the matrix 114 115 Level: advanced 116 117 Notes: 118 This routine does not work for factorizations done with external packages. 119 120 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 121 122 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 123 124 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 125 @*/ 126 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 127 { 128 PetscFunctionBegin; 129 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 130 *pivot = mat->factorerror_zeropivot_value; 131 *row = mat->factorerror_zeropivot_row; 132 PetscFunctionReturn(0); 133 } 134 135 /*@ 136 MatFactorGetError - gets the error code from a factorization 137 138 Logically Collective on Mat 139 140 Input Parameters: 141 . mat - the factored matrix 142 143 Output Parameter: 144 . err - the error code 145 146 Level: advanced 147 148 Notes: 149 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 150 151 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 152 @*/ 153 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 154 { 155 PetscFunctionBegin; 156 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 157 *err = mat->factorerrortype; 158 PetscFunctionReturn(0); 159 } 160 161 /*@ 162 MatFactorClearError - clears the error code in a factorization 163 164 Logically Collective on Mat 165 166 Input Parameter: 167 . mat - the factored matrix 168 169 Level: developer 170 171 Notes: 172 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 173 174 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 175 @*/ 176 PetscErrorCode MatFactorClearError(Mat mat) 177 { 178 PetscFunctionBegin; 179 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 180 mat->factorerrortype = MAT_FACTOR_NOERROR; 181 mat->factorerror_zeropivot_value = 0.0; 182 mat->factorerror_zeropivot_row = 0; 183 PetscFunctionReturn(0); 184 } 185 186 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 187 { 188 PetscErrorCode ierr; 189 Vec r,l; 190 const PetscScalar *al; 191 PetscInt i,nz,gnz,N,n; 192 193 PetscFunctionBegin; 194 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 195 if (!cols) { /* nonzero rows */ 196 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 197 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 198 ierr = VecSet(l,0.0);CHKERRQ(ierr); 199 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 200 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 201 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 202 } else { /* nonzero columns */ 203 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 204 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 205 ierr = VecSet(r,0.0);CHKERRQ(ierr); 206 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 207 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 208 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 209 } 210 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 211 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 212 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRMPI(ierr); 213 if (gnz != N) { 214 PetscInt *nzr; 215 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 216 if (nz) { 217 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 218 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 219 } 220 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 221 } else *nonzero = NULL; 222 if (!cols) { /* nonzero rows */ 223 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 224 } else { 225 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 226 } 227 ierr = VecDestroy(&l);CHKERRQ(ierr); 228 ierr = VecDestroy(&r);CHKERRQ(ierr); 229 PetscFunctionReturn(0); 230 } 231 232 /*@ 233 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 234 235 Input Parameter: 236 . A - the matrix 237 238 Output Parameter: 239 . keptrows - the rows that are not completely zero 240 241 Notes: 242 keptrows is set to NULL if all rows are nonzero. 243 244 Level: intermediate 245 246 @*/ 247 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 248 { 249 PetscErrorCode ierr; 250 251 PetscFunctionBegin; 252 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 253 PetscValidType(mat,1); 254 PetscValidPointer(keptrows,2); 255 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 256 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 257 if (!mat->ops->findnonzerorows) { 258 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 259 } else { 260 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 261 } 262 PetscFunctionReturn(0); 263 } 264 265 /*@ 266 MatFindZeroRows - Locate all rows that are completely zero in the matrix 267 268 Input Parameter: 269 . A - the matrix 270 271 Output Parameter: 272 . zerorows - the rows that are completely zero 273 274 Notes: 275 zerorows is set to NULL if no rows are zero. 276 277 Level: intermediate 278 279 @*/ 280 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 281 { 282 PetscErrorCode ierr; 283 IS keptrows; 284 PetscInt m, n; 285 286 PetscFunctionBegin; 287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 288 PetscValidType(mat,1); 289 PetscValidPointer(zerorows,2); 290 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 291 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 292 In keeping with this convention, we set zerorows to NULL if there are no zero 293 rows. */ 294 if (keptrows == NULL) { 295 *zerorows = NULL; 296 } else { 297 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 298 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 299 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 300 } 301 PetscFunctionReturn(0); 302 } 303 304 /*@ 305 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 306 307 Not Collective 308 309 Input Parameters: 310 . A - the matrix 311 312 Output Parameters: 313 . a - the diagonal part (which is a SEQUENTIAL matrix) 314 315 Notes: 316 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 317 Use caution, as the reference count on the returned matrix is not incremented and it is used as 318 part of the containing MPI Mat's normal operation. 319 320 Level: advanced 321 322 @*/ 323 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 324 { 325 PetscErrorCode ierr; 326 327 PetscFunctionBegin; 328 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 329 PetscValidType(A,1); 330 PetscValidPointer(a,2); 331 PetscCheckFalse(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 332 if (!A->ops->getdiagonalblock) { 333 PetscMPIInt size; 334 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRMPI(ierr); 335 if (size == 1) { 336 *a = A; 337 PetscFunctionReturn(0); 338 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for matrix type %s",((PetscObject)A)->type_name); 339 } 340 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 341 PetscFunctionReturn(0); 342 } 343 344 /*@ 345 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 346 347 Collective on Mat 348 349 Input Parameters: 350 . mat - the matrix 351 352 Output Parameter: 353 . trace - the sum of the diagonal entries 354 355 Level: advanced 356 357 @*/ 358 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 359 { 360 PetscErrorCode ierr; 361 Vec diag; 362 363 PetscFunctionBegin; 364 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 365 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 366 ierr = VecSum(diag,trace);CHKERRQ(ierr); 367 ierr = VecDestroy(&diag);CHKERRQ(ierr); 368 PetscFunctionReturn(0); 369 } 370 371 /*@ 372 MatRealPart - Zeros out the imaginary part of the matrix 373 374 Logically Collective on Mat 375 376 Input Parameters: 377 . mat - the matrix 378 379 Level: advanced 380 381 .seealso: MatImaginaryPart() 382 @*/ 383 PetscErrorCode MatRealPart(Mat mat) 384 { 385 PetscErrorCode ierr; 386 387 PetscFunctionBegin; 388 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 389 PetscValidType(mat,1); 390 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 391 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 392 PetscCheckFalse(!mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 393 MatCheckPreallocated(mat,1); 394 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 395 PetscFunctionReturn(0); 396 } 397 398 /*@C 399 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 400 401 Collective on Mat 402 403 Input Parameter: 404 . mat - the matrix 405 406 Output Parameters: 407 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 408 - ghosts - the global indices of the ghost points 409 410 Notes: 411 the nghosts and ghosts are suitable to pass into VecCreateGhost() 412 413 Level: advanced 414 415 @*/ 416 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 417 { 418 PetscErrorCode ierr; 419 420 PetscFunctionBegin; 421 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 422 PetscValidType(mat,1); 423 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 424 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 425 if (!mat->ops->getghosts) { 426 if (nghosts) *nghosts = 0; 427 if (ghosts) *ghosts = NULL; 428 } else { 429 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 430 } 431 PetscFunctionReturn(0); 432 } 433 434 /*@ 435 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 436 437 Logically Collective on Mat 438 439 Input Parameters: 440 . mat - the matrix 441 442 Level: advanced 443 444 .seealso: MatRealPart() 445 @*/ 446 PetscErrorCode MatImaginaryPart(Mat mat) 447 { 448 PetscErrorCode ierr; 449 450 PetscFunctionBegin; 451 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 452 PetscValidType(mat,1); 453 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 454 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 455 PetscCheckFalse(!mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 456 MatCheckPreallocated(mat,1); 457 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 458 PetscFunctionReturn(0); 459 } 460 461 /*@ 462 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 463 464 Not Collective 465 466 Input Parameter: 467 . mat - the matrix 468 469 Output Parameters: 470 + missing - is any diagonal missing 471 - dd - first diagonal entry that is missing (optional) on this process 472 473 Level: advanced 474 475 .seealso: MatRealPart() 476 @*/ 477 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 478 { 479 PetscErrorCode ierr; 480 481 PetscFunctionBegin; 482 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 483 PetscValidType(mat,1); 484 PetscValidPointer(missing,2); 485 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 486 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 487 PetscCheckFalse(!mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 488 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 489 PetscFunctionReturn(0); 490 } 491 492 /*@C 493 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 494 for each row that you get to ensure that your application does 495 not bleed memory. 496 497 Not Collective 498 499 Input Parameters: 500 + mat - the matrix 501 - row - the row to get 502 503 Output Parameters: 504 + ncols - if not NULL, the number of nonzeros in the row 505 . cols - if not NULL, the column numbers 506 - vals - if not NULL, the values 507 508 Notes: 509 This routine is provided for people who need to have direct access 510 to the structure of a matrix. We hope that we provide enough 511 high-level matrix routines that few users will need it. 512 513 MatGetRow() always returns 0-based column indices, regardless of 514 whether the internal representation is 0-based (default) or 1-based. 515 516 For better efficiency, set cols and/or vals to NULL if you do 517 not wish to extract these quantities. 518 519 The user can only examine the values extracted with MatGetRow(); 520 the values cannot be altered. To change the matrix entries, one 521 must use MatSetValues(). 522 523 You can only have one call to MatGetRow() outstanding for a particular 524 matrix at a time, per processor. MatGetRow() can only obtain rows 525 associated with the given processor, it cannot get rows from the 526 other processors; for that we suggest using MatCreateSubMatrices(), then 527 MatGetRow() on the submatrix. The row index passed to MatGetRow() 528 is in the global number of rows. 529 530 Fortran Notes: 531 The calling sequence from Fortran is 532 .vb 533 MatGetRow(matrix,row,ncols,cols,values,ierr) 534 Mat matrix (input) 535 integer row (input) 536 integer ncols (output) 537 integer cols(maxcols) (output) 538 double precision (or double complex) values(maxcols) output 539 .ve 540 where maxcols >= maximum nonzeros in any row of the matrix. 541 542 Caution: 543 Do not try to change the contents of the output arrays (cols and vals). 544 In some cases, this may corrupt the matrix. 545 546 Level: advanced 547 548 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 549 @*/ 550 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 551 { 552 PetscErrorCode ierr; 553 PetscInt incols; 554 555 PetscFunctionBegin; 556 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 557 PetscValidType(mat,1); 558 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 559 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 560 PetscCheckFalse(!mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 561 MatCheckPreallocated(mat,1); 562 PetscCheckFalse(row < mat->rmap->rstart || row >= mat->rmap->rend,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ")",row,mat->rmap->rstart,mat->rmap->rend); 563 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 564 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 565 if (ncols) *ncols = incols; 566 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 567 PetscFunctionReturn(0); 568 } 569 570 /*@ 571 MatConjugate - replaces the matrix values with their complex conjugates 572 573 Logically Collective on Mat 574 575 Input Parameters: 576 . mat - the matrix 577 578 Level: advanced 579 580 .seealso: VecConjugate() 581 @*/ 582 PetscErrorCode MatConjugate(Mat mat) 583 { 584 #if defined(PETSC_USE_COMPLEX) 585 PetscErrorCode ierr; 586 587 PetscFunctionBegin; 588 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 589 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 590 PetscCheckFalse(!mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 591 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 592 #else 593 PetscFunctionBegin; 594 #endif 595 PetscFunctionReturn(0); 596 } 597 598 /*@C 599 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 600 601 Not Collective 602 603 Input Parameters: 604 + mat - the matrix 605 . row - the row to get 606 . ncols, cols - the number of nonzeros and their columns 607 - vals - if nonzero the column values 608 609 Notes: 610 This routine should be called after you have finished examining the entries. 611 612 This routine zeros out ncols, cols, and vals. This is to prevent accidental 613 us of the array after it has been restored. If you pass NULL, it will 614 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 615 616 Fortran Notes: 617 The calling sequence from Fortran is 618 .vb 619 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 620 Mat matrix (input) 621 integer row (input) 622 integer ncols (output) 623 integer cols(maxcols) (output) 624 double precision (or double complex) values(maxcols) output 625 .ve 626 Where maxcols >= maximum nonzeros in any row of the matrix. 627 628 In Fortran MatRestoreRow() MUST be called after MatGetRow() 629 before another call to MatGetRow() can be made. 630 631 Level: advanced 632 633 .seealso: MatGetRow() 634 @*/ 635 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 636 { 637 PetscErrorCode ierr; 638 639 PetscFunctionBegin; 640 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 641 if (ncols) PetscValidIntPointer(ncols,3); 642 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 643 if (!mat->ops->restorerow) PetscFunctionReturn(0); 644 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 645 if (ncols) *ncols = 0; 646 if (cols) *cols = NULL; 647 if (vals) *vals = NULL; 648 PetscFunctionReturn(0); 649 } 650 651 /*@ 652 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 653 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 654 655 Not Collective 656 657 Input Parameters: 658 . mat - the matrix 659 660 Notes: 661 The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format. 662 663 Level: advanced 664 665 .seealso: MatRestoreRowUpperTriangular() 666 @*/ 667 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 668 { 669 PetscErrorCode ierr; 670 671 PetscFunctionBegin; 672 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 673 PetscValidType(mat,1); 674 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 675 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 676 MatCheckPreallocated(mat,1); 677 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 678 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 679 PetscFunctionReturn(0); 680 } 681 682 /*@ 683 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 684 685 Not Collective 686 687 Input Parameters: 688 . mat - the matrix 689 690 Notes: 691 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 692 693 Level: advanced 694 695 .seealso: MatGetRowUpperTriangular() 696 @*/ 697 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 698 { 699 PetscErrorCode ierr; 700 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 703 PetscValidType(mat,1); 704 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 705 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 706 MatCheckPreallocated(mat,1); 707 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 708 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 709 PetscFunctionReturn(0); 710 } 711 712 /*@C 713 MatSetOptionsPrefix - Sets the prefix used for searching for all 714 Mat options in the database. 715 716 Logically Collective on Mat 717 718 Input Parameters: 719 + A - the Mat context 720 - prefix - the prefix to prepend to all option names 721 722 Notes: 723 A hyphen (-) must NOT be given at the beginning of the prefix name. 724 The first character of all runtime options is AUTOMATICALLY the hyphen. 725 726 Level: advanced 727 728 .seealso: MatSetFromOptions() 729 @*/ 730 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 731 { 732 PetscErrorCode ierr; 733 734 PetscFunctionBegin; 735 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 736 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 737 PetscFunctionReturn(0); 738 } 739 740 /*@C 741 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 742 Mat options in the database. 743 744 Logically Collective on Mat 745 746 Input Parameters: 747 + A - the Mat context 748 - prefix - the prefix to prepend to all option names 749 750 Notes: 751 A hyphen (-) must NOT be given at the beginning of the prefix name. 752 The first character of all runtime options is AUTOMATICALLY the hyphen. 753 754 Level: advanced 755 756 .seealso: MatGetOptionsPrefix() 757 @*/ 758 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 759 { 760 PetscErrorCode ierr; 761 762 PetscFunctionBegin; 763 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 764 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 765 PetscFunctionReturn(0); 766 } 767 768 /*@C 769 MatGetOptionsPrefix - Gets the prefix used for searching for all 770 Mat options in the database. 771 772 Not Collective 773 774 Input Parameter: 775 . A - the Mat context 776 777 Output Parameter: 778 . prefix - pointer to the prefix string used 779 780 Notes: 781 On the fortran side, the user should pass in a string 'prefix' of 782 sufficient length to hold the prefix. 783 784 Level: advanced 785 786 .seealso: MatAppendOptionsPrefix() 787 @*/ 788 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 789 { 790 PetscErrorCode ierr; 791 792 PetscFunctionBegin; 793 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 794 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 795 PetscFunctionReturn(0); 796 } 797 798 /*@ 799 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 800 801 Collective on Mat 802 803 Input Parameters: 804 . A - the Mat context 805 806 Notes: 807 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 808 Currently support MPIAIJ and SEQAIJ. 809 810 Level: beginner 811 812 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 813 @*/ 814 PetscErrorCode MatResetPreallocation(Mat A) 815 { 816 PetscErrorCode ierr; 817 818 PetscFunctionBegin; 819 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 820 PetscValidType(A,1); 821 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 822 PetscFunctionReturn(0); 823 } 824 825 /*@ 826 MatSetUp - Sets up the internal matrix data structures for later use. 827 828 Collective on Mat 829 830 Input Parameters: 831 . A - the Mat context 832 833 Notes: 834 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 835 836 If a suitable preallocation routine is used, this function does not need to be called. 837 838 See the Performance chapter of the PETSc users manual for how to preallocate matrices 839 840 Level: beginner 841 842 .seealso: MatCreate(), MatDestroy() 843 @*/ 844 PetscErrorCode MatSetUp(Mat A) 845 { 846 PetscMPIInt size; 847 PetscErrorCode ierr; 848 849 PetscFunctionBegin; 850 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 851 if (!((PetscObject)A)->type_name) { 852 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRMPI(ierr); 853 if (size == 1) { 854 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 855 } else { 856 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 857 } 858 } 859 if (!A->preallocated && A->ops->setup) { 860 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 861 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 862 } 863 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 864 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 865 A->preallocated = PETSC_TRUE; 866 PetscFunctionReturn(0); 867 } 868 869 #if defined(PETSC_HAVE_SAWS) 870 #include <petscviewersaws.h> 871 #endif 872 873 /*@C 874 MatViewFromOptions - View from Options 875 876 Collective on Mat 877 878 Input Parameters: 879 + A - the Mat context 880 . obj - Optional object 881 - name - command line option 882 883 Level: intermediate 884 .seealso: Mat, MatView, PetscObjectViewFromOptions(), MatCreate() 885 @*/ 886 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 887 { 888 PetscErrorCode ierr; 889 890 PetscFunctionBegin; 891 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 892 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 893 PetscFunctionReturn(0); 894 } 895 896 /*@C 897 MatView - Visualizes a matrix object. 898 899 Collective on Mat 900 901 Input Parameters: 902 + mat - the matrix 903 - viewer - visualization context 904 905 Notes: 906 The available visualization contexts include 907 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 908 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 909 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 910 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 911 912 The user can open alternative visualization contexts with 913 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 914 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 915 specified file; corresponding input uses MatLoad() 916 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 917 an X window display 918 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 919 Currently only the sequential dense and AIJ 920 matrix types support the Socket viewer. 921 922 The user can call PetscViewerPushFormat() to specify the output 923 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 924 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 925 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 926 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 927 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 928 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 929 format common among all matrix types 930 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 931 format (which is in many cases the same as the default) 932 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 933 size and structure (not the matrix entries) 934 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 935 the matrix structure 936 937 Options Database Keys: 938 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 939 . -mat_view ::ascii_info_detail - Prints more detailed info 940 . -mat_view - Prints matrix in ASCII format 941 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 942 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 943 . -display <name> - Sets display name (default is host) 944 . -draw_pause <sec> - Sets number of seconds to pause after display 945 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 946 . -viewer_socket_machine <machine> - 947 . -viewer_socket_port <port> - 948 . -mat_view binary - save matrix to file in binary format 949 - -viewer_binary_filename <name> - 950 951 Level: beginner 952 953 Notes: 954 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 955 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 956 957 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 958 959 See the manual page for MatLoad() for the exact format of the binary file when the binary 960 viewer is used. 961 962 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 963 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 964 965 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 966 and then use the following mouse functions. 967 .vb 968 left mouse: zoom in 969 middle mouse: zoom out 970 right mouse: continue with the simulation 971 .ve 972 973 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 974 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 975 @*/ 976 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 977 { 978 PetscErrorCode ierr; 979 PetscInt rows,cols,rbs,cbs; 980 PetscBool isascii,isstring,issaws; 981 PetscViewerFormat format; 982 PetscMPIInt size; 983 984 PetscFunctionBegin; 985 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 986 PetscValidType(mat,1); 987 if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);} 988 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 989 PetscCheckSameComm(mat,1,viewer,2); 990 MatCheckPreallocated(mat,1); 991 992 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 993 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 994 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 995 996 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 997 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 998 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 999 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1000 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1001 } 1002 1003 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1004 if (isascii) { 1005 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1006 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1007 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1008 MatNullSpace nullsp,transnullsp; 1009 1010 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1011 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1012 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1013 if (rbs != 1 || cbs != 1) { 1014 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1015 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs);CHKERRQ(ierr);} 1016 } else { 1017 ierr = PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols);CHKERRQ(ierr); 1018 } 1019 if (mat->factortype) { 1020 MatSolverType solver; 1021 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1022 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1023 } 1024 if (mat->ops->getinfo) { 1025 MatInfo info; 1026 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1027 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1028 if (!mat->factortype) { 1029 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1030 } 1031 } 1032 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1033 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1034 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1035 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1036 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1037 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1038 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1039 ierr = MatProductView(mat,viewer);CHKERRQ(ierr); 1040 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1041 } 1042 } else if (issaws) { 1043 #if defined(PETSC_HAVE_SAWS) 1044 PetscMPIInt rank; 1045 1046 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1047 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr); 1048 if (!((PetscObject)mat)->amsmem && rank == 0) { 1049 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1050 } 1051 #endif 1052 } else if (isstring) { 1053 const char *type; 1054 ierr = MatGetType(mat,&type);CHKERRQ(ierr); 1055 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr); 1056 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);} 1057 } 1058 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1059 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1060 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1061 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1062 } else if (mat->ops->view) { 1063 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1064 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1065 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1066 } 1067 if (isascii) { 1068 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1069 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1070 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1071 } 1072 } 1073 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1074 PetscFunctionReturn(0); 1075 } 1076 1077 #if defined(PETSC_USE_DEBUG) 1078 #include <../src/sys/totalview/tv_data_display.h> 1079 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1080 { 1081 TV_add_row("Local rows", "int", &mat->rmap->n); 1082 TV_add_row("Local columns", "int", &mat->cmap->n); 1083 TV_add_row("Global rows", "int", &mat->rmap->N); 1084 TV_add_row("Global columns", "int", &mat->cmap->N); 1085 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1086 return TV_format_OK; 1087 } 1088 #endif 1089 1090 /*@C 1091 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1092 with MatView(). The matrix format is determined from the options database. 1093 Generates a parallel MPI matrix if the communicator has more than one 1094 processor. The default matrix type is AIJ. 1095 1096 Collective on PetscViewer 1097 1098 Input Parameters: 1099 + mat - the newly loaded matrix, this needs to have been created with MatCreate() 1100 or some related function before a call to MatLoad() 1101 - viewer - binary/HDF5 file viewer 1102 1103 Options Database Keys: 1104 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1105 block size 1106 . -matload_block_size <bs> 1107 1108 Level: beginner 1109 1110 Notes: 1111 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1112 Mat before calling this routine if you wish to set it from the options database. 1113 1114 MatLoad() automatically loads into the options database any options 1115 given in the file filename.info where filename is the name of the file 1116 that was passed to the PetscViewerBinaryOpen(). The options in the info 1117 file will be ignored if you use the -viewer_binary_skip_info option. 1118 1119 If the type or size of mat is not set before a call to MatLoad, PETSc 1120 sets the default matrix type AIJ and sets the local and global sizes. 1121 If type and/or size is already set, then the same are used. 1122 1123 In parallel, each processor can load a subset of rows (or the 1124 entire matrix). This routine is especially useful when a large 1125 matrix is stored on disk and only part of it is desired on each 1126 processor. For example, a parallel solver may access only some of 1127 the rows from each processor. The algorithm used here reads 1128 relatively small blocks of data rather than reading the entire 1129 matrix and then subsetting it. 1130 1131 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1132 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1133 or the sequence like 1134 $ PetscViewer v; 1135 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1136 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1137 $ PetscViewerSetFromOptions(v); 1138 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1139 $ PetscViewerFileSetName(v,"datafile"); 1140 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1141 $ -viewer_type {binary,hdf5} 1142 1143 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1144 and src/mat/tutorials/ex10.c with the second approach. 1145 1146 Notes about the PETSc binary format: 1147 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1148 is read onto rank 0 and then shipped to its destination rank, one after another. 1149 Multiple objects, both matrices and vectors, can be stored within the same file. 1150 Their PetscObject name is ignored; they are loaded in the order of their storage. 1151 1152 Most users should not need to know the details of the binary storage 1153 format, since MatLoad() and MatView() completely hide these details. 1154 But for anyone who's interested, the standard binary matrix storage 1155 format is 1156 1157 $ PetscInt MAT_FILE_CLASSID 1158 $ PetscInt number of rows 1159 $ PetscInt number of columns 1160 $ PetscInt total number of nonzeros 1161 $ PetscInt *number nonzeros in each row 1162 $ PetscInt *column indices of all nonzeros (starting index is zero) 1163 $ PetscScalar *values of all nonzeros 1164 1165 PETSc automatically does the byte swapping for 1166 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1167 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1168 read/write routines you have to swap the bytes; see PetscBinaryRead() 1169 and PetscBinaryWrite() to see how this may be done. 1170 1171 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1172 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1173 Each processor's chunk is loaded independently by its owning rank. 1174 Multiple objects, both matrices and vectors, can be stored within the same file. 1175 They are looked up by their PetscObject name. 1176 1177 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1178 by default the same structure and naming of the AIJ arrays and column count 1179 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1180 $ save example.mat A b -v7.3 1181 can be directly read by this routine (see Reference 1 for details). 1182 Note that depending on your MATLAB version, this format might be a default, 1183 otherwise you can set it as default in Preferences. 1184 1185 Unless -nocompression flag is used to save the file in MATLAB, 1186 PETSc must be configured with ZLIB package. 1187 1188 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1189 1190 Current HDF5 (MAT-File) limitations: 1191 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1192 1193 Corresponding MatView() is not yet implemented. 1194 1195 The loaded matrix is actually a transpose of the original one in MATLAB, 1196 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1197 With this format, matrix is automatically transposed by PETSc, 1198 unless the matrix is marked as SPD or symmetric 1199 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1200 1201 References: 1202 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1203 1204 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1205 1206 @*/ 1207 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1208 { 1209 PetscErrorCode ierr; 1210 PetscBool flg; 1211 1212 PetscFunctionBegin; 1213 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1214 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1215 1216 if (!((PetscObject)mat)->type_name) { 1217 ierr = MatSetType(mat,MATAIJ);CHKERRQ(ierr); 1218 } 1219 1220 flg = PETSC_FALSE; 1221 ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1222 if (flg) { 1223 ierr = MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1224 ierr = MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1225 } 1226 flg = PETSC_FALSE; 1227 ierr = PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1228 if (flg) { 1229 ierr = MatSetOption(mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1230 } 1231 1232 PetscCheckFalse(!mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1233 ierr = PetscLogEventBegin(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr); 1234 ierr = (*mat->ops->load)(mat,viewer);CHKERRQ(ierr); 1235 ierr = PetscLogEventEnd(MAT_Load,mat,viewer,0,0);CHKERRQ(ierr); 1236 PetscFunctionReturn(0); 1237 } 1238 1239 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1240 { 1241 PetscErrorCode ierr; 1242 Mat_Redundant *redund = *redundant; 1243 PetscInt i; 1244 1245 PetscFunctionBegin; 1246 if (redund) { 1247 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1248 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1249 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1250 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1251 } else { 1252 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1253 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1254 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1255 for (i=0; i<redund->nrecvs; i++) { 1256 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1257 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1258 } 1259 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1260 } 1261 1262 if (redund->subcomm) { 1263 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1264 } 1265 ierr = PetscFree(redund);CHKERRQ(ierr); 1266 } 1267 PetscFunctionReturn(0); 1268 } 1269 1270 /*@C 1271 MatDestroy - Frees space taken by a matrix. 1272 1273 Collective on Mat 1274 1275 Input Parameter: 1276 . A - the matrix 1277 1278 Level: beginner 1279 1280 @*/ 1281 PetscErrorCode MatDestroy(Mat *A) 1282 { 1283 PetscErrorCode ierr; 1284 1285 PetscFunctionBegin; 1286 if (!*A) PetscFunctionReturn(0); 1287 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1288 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1289 1290 /* if memory was published with SAWs then destroy it */ 1291 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1292 if ((*A)->ops->destroy) { 1293 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1294 } 1295 1296 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1297 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1298 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1299 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) { 1300 ierr = PetscFree((*A)->preferredordering[i]);CHKERRQ(ierr); 1301 } 1302 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1303 ierr = MatProductClear(*A);CHKERRQ(ierr); 1304 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1305 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1306 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1307 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1308 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1309 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1310 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1311 PetscFunctionReturn(0); 1312 } 1313 1314 /*@C 1315 MatSetValues - Inserts or adds a block of values into a matrix. 1316 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1317 MUST be called after all calls to MatSetValues() have been completed. 1318 1319 Not Collective 1320 1321 Input Parameters: 1322 + mat - the matrix 1323 . v - a logically two-dimensional array of values 1324 . m, idxm - the number of rows and their global indices 1325 . n, idxn - the number of columns and their global indices 1326 - addv - either ADD_VALUES or INSERT_VALUES, where 1327 ADD_VALUES adds values to any existing entries, and 1328 INSERT_VALUES replaces existing entries with new values 1329 1330 Notes: 1331 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1332 MatSetUp() before using this routine 1333 1334 By default the values, v, are row-oriented. See MatSetOption() for other options. 1335 1336 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1337 options cannot be mixed without intervening calls to the assembly 1338 routines. 1339 1340 MatSetValues() uses 0-based row and column numbers in Fortran 1341 as well as in C. 1342 1343 Negative indices may be passed in idxm and idxn, these rows and columns are 1344 simply ignored. This allows easily inserting element stiffness matrices 1345 with homogeneous Dirchlet boundary conditions that you don't want represented 1346 in the matrix. 1347 1348 Efficiency Alert: 1349 The routine MatSetValuesBlocked() may offer much better efficiency 1350 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1351 1352 Level: beginner 1353 1354 Developer Notes: 1355 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1356 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1357 1358 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1359 InsertMode, INSERT_VALUES, ADD_VALUES 1360 @*/ 1361 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1362 { 1363 PetscErrorCode ierr; 1364 1365 PetscFunctionBeginHot; 1366 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1367 PetscValidType(mat,1); 1368 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1369 PetscValidIntPointer(idxm,3); 1370 PetscValidIntPointer(idxn,5); 1371 MatCheckPreallocated(mat,1); 1372 1373 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1374 else PetscCheckFalse(mat->insertmode != addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1375 1376 if (PetscDefined(USE_DEBUG)) { 1377 PetscInt i,j; 1378 1379 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1380 PetscCheckFalse(!mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1381 1382 for (i=0; i<m; i++) { 1383 for (j=0; j<n; j++) { 1384 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1385 #if defined(PETSC_USE_COMPLEX) 1386 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+i%g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1387 #else 1388 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)v[i*n+j],idxm[i],idxn[j]); 1389 #endif 1390 } 1391 } 1392 for (i=0; i<m; i++) PetscCheckFalse(idxm[i] >= mat->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxm[i],mat->rmap->N-1); 1393 for (i=0; i<n; i++) PetscCheckFalse(idxn[i] >= mat->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxn[i],mat->cmap->N-1); 1394 } 1395 1396 if (mat->assembled) { 1397 mat->was_assembled = PETSC_TRUE; 1398 mat->assembled = PETSC_FALSE; 1399 } 1400 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1401 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1402 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1403 PetscFunctionReturn(0); 1404 } 1405 1406 /*@ 1407 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1408 values into a matrix 1409 1410 Not Collective 1411 1412 Input Parameters: 1413 + mat - the matrix 1414 . row - the (block) row to set 1415 - v - a logically two-dimensional array of values 1416 1417 Notes: 1418 By the values, v, are column-oriented (for the block version) and sorted 1419 1420 All the nonzeros in the row must be provided 1421 1422 The matrix must have previously had its column indices set 1423 1424 The row must belong to this process 1425 1426 Level: intermediate 1427 1428 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1429 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1430 @*/ 1431 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1432 { 1433 PetscErrorCode ierr; 1434 PetscInt globalrow; 1435 1436 PetscFunctionBegin; 1437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1438 PetscValidType(mat,1); 1439 PetscValidScalarPointer(v,3); 1440 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1441 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1442 PetscFunctionReturn(0); 1443 } 1444 1445 /*@ 1446 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1447 values into a matrix 1448 1449 Not Collective 1450 1451 Input Parameters: 1452 + mat - the matrix 1453 . row - the (block) row to set 1454 - 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 1455 1456 Notes: 1457 The values, v, are column-oriented for the block version. 1458 1459 All the nonzeros in the row must be provided 1460 1461 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1462 1463 The row must belong to this process 1464 1465 Level: advanced 1466 1467 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1468 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1469 @*/ 1470 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1471 { 1472 PetscErrorCode ierr; 1473 1474 PetscFunctionBeginHot; 1475 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1476 PetscValidType(mat,1); 1477 MatCheckPreallocated(mat,1); 1478 PetscValidScalarPointer(v,3); 1479 PetscCheckFalse(mat->insertmode == ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1480 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1481 mat->insertmode = INSERT_VALUES; 1482 1483 if (mat->assembled) { 1484 mat->was_assembled = PETSC_TRUE; 1485 mat->assembled = PETSC_FALSE; 1486 } 1487 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1488 PetscCheckFalse(!mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1489 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1490 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1491 PetscFunctionReturn(0); 1492 } 1493 1494 /*@ 1495 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1496 Using structured grid indexing 1497 1498 Not Collective 1499 1500 Input Parameters: 1501 + mat - the matrix 1502 . m - number of rows being entered 1503 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1504 . n - number of columns being entered 1505 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1506 . v - a logically two-dimensional array of values 1507 - addv - either ADD_VALUES or INSERT_VALUES, where 1508 ADD_VALUES adds values to any existing entries, and 1509 INSERT_VALUES replaces existing entries with new values 1510 1511 Notes: 1512 By default the values, v, are row-oriented. See MatSetOption() for other options. 1513 1514 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1515 options cannot be mixed without intervening calls to the assembly 1516 routines. 1517 1518 The grid coordinates are across the entire grid, not just the local portion 1519 1520 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1521 as well as in C. 1522 1523 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1524 1525 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1526 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1527 1528 The columns and rows in the stencil passed in MUST be contained within the 1529 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1530 if you create a DMDA with an overlap of one grid level and on a particular process its first 1531 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1532 first i index you can use in your column and row indices in MatSetStencil() is 5. 1533 1534 In Fortran idxm and idxn should be declared as 1535 $ MatStencil idxm(4,m),idxn(4,n) 1536 and the values inserted using 1537 $ idxm(MatStencil_i,1) = i 1538 $ idxm(MatStencil_j,1) = j 1539 $ idxm(MatStencil_k,1) = k 1540 $ idxm(MatStencil_c,1) = c 1541 etc 1542 1543 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1544 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1545 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1546 DM_BOUNDARY_PERIODIC boundary type. 1547 1548 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 1549 a single value per point) you can skip filling those indices. 1550 1551 Inspired by the structured grid interface to the HYPRE package 1552 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1553 1554 Efficiency Alert: 1555 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1556 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1557 1558 Level: beginner 1559 1560 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1561 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1562 @*/ 1563 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1564 { 1565 PetscErrorCode ierr; 1566 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1567 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1568 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1569 1570 PetscFunctionBegin; 1571 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1572 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1573 PetscValidType(mat,1); 1574 PetscValidPointer(idxm,3); 1575 PetscValidPointer(idxn,5); 1576 1577 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1578 jdxm = buf; jdxn = buf+m; 1579 } else { 1580 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1581 jdxm = bufm; jdxn = bufn; 1582 } 1583 for (i=0; i<m; i++) { 1584 for (j=0; j<3-sdim; j++) dxm++; 1585 tmp = *dxm++ - starts[0]; 1586 for (j=0; j<dim-1; j++) { 1587 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1588 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1589 } 1590 if (mat->stencil.noc) dxm++; 1591 jdxm[i] = tmp; 1592 } 1593 for (i=0; i<n; i++) { 1594 for (j=0; j<3-sdim; j++) dxn++; 1595 tmp = *dxn++ - starts[0]; 1596 for (j=0; j<dim-1; j++) { 1597 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1598 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1599 } 1600 if (mat->stencil.noc) dxn++; 1601 jdxn[i] = tmp; 1602 } 1603 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1604 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1605 PetscFunctionReturn(0); 1606 } 1607 1608 /*@ 1609 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1610 Using structured grid indexing 1611 1612 Not Collective 1613 1614 Input Parameters: 1615 + mat - the matrix 1616 . m - number of rows being entered 1617 . idxm - grid coordinates for matrix rows being entered 1618 . n - number of columns being entered 1619 . idxn - grid coordinates for matrix columns being entered 1620 . v - a logically two-dimensional array of values 1621 - addv - either ADD_VALUES or INSERT_VALUES, where 1622 ADD_VALUES adds values to any existing entries, and 1623 INSERT_VALUES replaces existing entries with new values 1624 1625 Notes: 1626 By default the values, v, are row-oriented and unsorted. 1627 See MatSetOption() for other options. 1628 1629 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1630 options cannot be mixed without intervening calls to the assembly 1631 routines. 1632 1633 The grid coordinates are across the entire grid, not just the local portion 1634 1635 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1636 as well as in C. 1637 1638 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1639 1640 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1641 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1642 1643 The columns and rows in the stencil passed in MUST be contained within the 1644 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1645 if you create a DMDA with an overlap of one grid level and on a particular process its first 1646 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1647 first i index you can use in your column and row indices in MatSetStencil() is 5. 1648 1649 In Fortran idxm and idxn should be declared as 1650 $ MatStencil idxm(4,m),idxn(4,n) 1651 and the values inserted using 1652 $ idxm(MatStencil_i,1) = i 1653 $ idxm(MatStencil_j,1) = j 1654 $ idxm(MatStencil_k,1) = k 1655 etc 1656 1657 Negative indices may be passed in idxm and idxn, these rows and columns are 1658 simply ignored. This allows easily inserting element stiffness matrices 1659 with homogeneous Dirchlet boundary conditions that you don't want represented 1660 in the matrix. 1661 1662 Inspired by the structured grid interface to the HYPRE package 1663 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1664 1665 Level: beginner 1666 1667 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1668 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1669 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1670 @*/ 1671 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1672 { 1673 PetscErrorCode ierr; 1674 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1675 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1676 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1677 1678 PetscFunctionBegin; 1679 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1681 PetscValidType(mat,1); 1682 PetscValidPointer(idxm,3); 1683 PetscValidPointer(idxn,5); 1684 PetscValidScalarPointer(v,6); 1685 1686 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1687 jdxm = buf; jdxn = buf+m; 1688 } else { 1689 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1690 jdxm = bufm; jdxn = bufn; 1691 } 1692 for (i=0; i<m; i++) { 1693 for (j=0; j<3-sdim; j++) dxm++; 1694 tmp = *dxm++ - starts[0]; 1695 for (j=0; j<sdim-1; j++) { 1696 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1697 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1698 } 1699 dxm++; 1700 jdxm[i] = tmp; 1701 } 1702 for (i=0; i<n; i++) { 1703 for (j=0; j<3-sdim; j++) dxn++; 1704 tmp = *dxn++ - starts[0]; 1705 for (j=0; j<sdim-1; j++) { 1706 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1707 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1708 } 1709 dxn++; 1710 jdxn[i] = tmp; 1711 } 1712 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1713 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1714 PetscFunctionReturn(0); 1715 } 1716 1717 /*@ 1718 MatSetStencil - Sets the grid information for setting values into a matrix via 1719 MatSetValuesStencil() 1720 1721 Not Collective 1722 1723 Input Parameters: 1724 + mat - the matrix 1725 . dim - dimension of the grid 1, 2, or 3 1726 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1727 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1728 - dof - number of degrees of freedom per node 1729 1730 Inspired by the structured grid interface to the HYPRE package 1731 (www.llnl.gov/CASC/hyper) 1732 1733 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1734 user. 1735 1736 Level: beginner 1737 1738 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1739 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1740 @*/ 1741 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1742 { 1743 PetscInt i; 1744 1745 PetscFunctionBegin; 1746 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1747 PetscValidIntPointer(dims,3); 1748 PetscValidIntPointer(starts,4); 1749 1750 mat->stencil.dim = dim + (dof > 1); 1751 for (i=0; i<dim; i++) { 1752 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1753 mat->stencil.starts[i] = starts[dim-i-1]; 1754 } 1755 mat->stencil.dims[dim] = dof; 1756 mat->stencil.starts[dim] = 0; 1757 mat->stencil.noc = (PetscBool)(dof == 1); 1758 PetscFunctionReturn(0); 1759 } 1760 1761 /*@C 1762 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1763 1764 Not Collective 1765 1766 Input Parameters: 1767 + mat - the matrix 1768 . v - a logically two-dimensional array of values 1769 . m, idxm - the number of block rows and their global block indices 1770 . n, idxn - the number of block columns and their global block indices 1771 - addv - either ADD_VALUES or INSERT_VALUES, where 1772 ADD_VALUES adds values to any existing entries, and 1773 INSERT_VALUES replaces existing entries with new values 1774 1775 Notes: 1776 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1777 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1778 1779 The m and n count the NUMBER of blocks in the row direction and column direction, 1780 NOT the total number of rows/columns; for example, if the block size is 2 and 1781 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1782 The values in idxm would be 1 2; that is the first index for each block divided by 1783 the block size. 1784 1785 Note that you must call MatSetBlockSize() when constructing this matrix (before 1786 preallocating it). 1787 1788 By default the values, v, are row-oriented, so the layout of 1789 v is the same as for MatSetValues(). See MatSetOption() for other options. 1790 1791 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1792 options cannot be mixed without intervening calls to the assembly 1793 routines. 1794 1795 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1796 as well as in C. 1797 1798 Negative indices may be passed in idxm and idxn, these rows and columns are 1799 simply ignored. This allows easily inserting element stiffness matrices 1800 with homogeneous Dirchlet boundary conditions that you don't want represented 1801 in the matrix. 1802 1803 Each time an entry is set within a sparse matrix via MatSetValues(), 1804 internal searching must be done to determine where to place the 1805 data in the matrix storage space. By instead inserting blocks of 1806 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1807 reduced. 1808 1809 Example: 1810 $ Suppose m=n=2 and block size(bs) = 2 The array is 1811 $ 1812 $ 1 2 | 3 4 1813 $ 5 6 | 7 8 1814 $ - - - | - - - 1815 $ 9 10 | 11 12 1816 $ 13 14 | 15 16 1817 $ 1818 $ v[] should be passed in like 1819 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1820 $ 1821 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1822 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1823 1824 Level: intermediate 1825 1826 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1827 @*/ 1828 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1829 { 1830 PetscErrorCode ierr; 1831 1832 PetscFunctionBeginHot; 1833 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1834 PetscValidType(mat,1); 1835 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1836 PetscValidIntPointer(idxm,3); 1837 PetscValidIntPointer(idxn,5); 1838 MatCheckPreallocated(mat,1); 1839 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1840 else PetscCheckFalse(mat->insertmode != addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1841 if (PetscDefined(USE_DEBUG)) { 1842 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1843 PetscCheckFalse(!mat->ops->setvaluesblocked && !mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1844 } 1845 if (PetscDefined(USE_DEBUG)) { 1846 PetscInt rbs,cbs,M,N,i; 1847 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1848 ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); 1849 for (i=0; i<m; i++) { 1850 PetscCheckFalse(idxm[i]*rbs >= M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %" PetscInt_FMT " (index %" PetscInt_FMT ") greater than row length %" PetscInt_FMT,i,idxm[i],M); 1851 } 1852 for (i=0; i<n; i++) { 1853 PetscCheckFalse(idxn[i]*cbs >= N,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %" PetscInt_FMT " (index %" PetscInt_FMT ") great than column length %" PetscInt_FMT,i,idxn[i],N); 1854 } 1855 } 1856 if (mat->assembled) { 1857 mat->was_assembled = PETSC_TRUE; 1858 mat->assembled = PETSC_FALSE; 1859 } 1860 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1861 if (mat->ops->setvaluesblocked) { 1862 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1863 } else { 1864 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1865 PetscInt i,j,bs,cbs; 1866 1867 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1868 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1869 iidxm = buf; 1870 iidxn = buf + m*bs; 1871 } else { 1872 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1873 iidxm = bufr; 1874 iidxn = bufc; 1875 } 1876 for (i=0; i<m; i++) { 1877 for (j=0; j<bs; j++) { 1878 iidxm[i*bs+j] = bs*idxm[i] + j; 1879 } 1880 } 1881 if (m != n || bs != cbs || idxm != idxn) { 1882 for (i=0; i<n; i++) { 1883 for (j=0; j<cbs; j++) { 1884 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1885 } 1886 } 1887 } else iidxn = iidxm; 1888 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1889 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1890 } 1891 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1892 PetscFunctionReturn(0); 1893 } 1894 1895 /*@C 1896 MatGetValues - Gets a block of values from a matrix. 1897 1898 Not Collective; can only return values that are owned by the give process 1899 1900 Input Parameters: 1901 + mat - the matrix 1902 . v - a logically two-dimensional array for storing the values 1903 . m, idxm - the number of rows and their global indices 1904 - n, idxn - the number of columns and their global indices 1905 1906 Notes: 1907 The user must allocate space (m*n PetscScalars) for the values, v. 1908 The values, v, are then returned in a row-oriented format, 1909 analogous to that used by default in MatSetValues(). 1910 1911 MatGetValues() uses 0-based row and column numbers in 1912 Fortran as well as in C. 1913 1914 MatGetValues() requires that the matrix has been assembled 1915 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1916 MatSetValues() and MatGetValues() CANNOT be made in succession 1917 without intermediate matrix assembly. 1918 1919 Negative row or column indices will be ignored and those locations in v[] will be 1920 left unchanged. 1921 1922 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 1923 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 1924 from MatGetOwnershipRange(mat,&rstart,&rend). 1925 1926 Level: advanced 1927 1928 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues(), MatGetOwnershipRange(), MatGetValuesLocal(), MatGetValue() 1929 @*/ 1930 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1931 { 1932 PetscErrorCode ierr; 1933 1934 PetscFunctionBegin; 1935 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1936 PetscValidType(mat,1); 1937 if (!m || !n) PetscFunctionReturn(0); 1938 PetscValidIntPointer(idxm,3); 1939 PetscValidIntPointer(idxn,5); 1940 PetscValidScalarPointer(v,6); 1941 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1942 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1943 PetscCheckFalse(!mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1944 MatCheckPreallocated(mat,1); 1945 1946 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1947 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1948 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1949 PetscFunctionReturn(0); 1950 } 1951 1952 /*@C 1953 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 1954 defined previously by MatSetLocalToGlobalMapping() 1955 1956 Not Collective 1957 1958 Input Parameters: 1959 + mat - the matrix 1960 . nrow, irow - number of rows and their local indices 1961 - ncol, icol - number of columns and their local indices 1962 1963 Output Parameter: 1964 . y - a logically two-dimensional array of values 1965 1966 Notes: 1967 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 1968 1969 This routine can only return values that are owned by the requesting MPI rank. That is, for standard matrix formats, rows that, in the global numbering, 1970 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 1971 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 1972 with MatSetLocalToGlobalMapping(). 1973 1974 Developer Notes: 1975 This is labelled with C so does not automatically generate Fortran stubs and interfaces 1976 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1977 1978 Level: advanced 1979 1980 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 1981 MatSetValuesLocal(), MatGetValues() 1982 @*/ 1983 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 1984 { 1985 PetscErrorCode ierr; 1986 1987 PetscFunctionBeginHot; 1988 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1989 PetscValidType(mat,1); 1990 MatCheckPreallocated(mat,1); 1991 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 1992 PetscValidIntPointer(irow,3); 1993 PetscValidIntPointer(icol,5); 1994 if (PetscDefined(USE_DEBUG)) { 1995 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1996 PetscCheckFalse(!mat->ops->getvalueslocal && !mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1997 } 1998 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1999 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 2000 if (mat->ops->getvalueslocal) { 2001 ierr = (*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y);CHKERRQ(ierr); 2002 } else { 2003 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2004 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2005 irowm = buf; icolm = buf+nrow; 2006 } else { 2007 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2008 irowm = bufr; icolm = bufc; 2009 } 2010 PetscCheckFalse(!mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2011 PetscCheckFalse(!mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2012 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2013 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2014 ierr = MatGetValues(mat,nrow,irowm,ncol,icolm,y);CHKERRQ(ierr); 2015 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2016 } 2017 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 2018 PetscFunctionReturn(0); 2019 } 2020 2021 /*@ 2022 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2023 the same size. Currently, this can only be called once and creates the given matrix. 2024 2025 Not Collective 2026 2027 Input Parameters: 2028 + mat - the matrix 2029 . nb - the number of blocks 2030 . bs - the number of rows (and columns) in each block 2031 . rows - a concatenation of the rows for each block 2032 - v - a concatenation of logically two-dimensional arrays of values 2033 2034 Notes: 2035 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2036 2037 Level: advanced 2038 2039 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 2040 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 2041 @*/ 2042 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2043 { 2044 PetscErrorCode ierr; 2045 2046 PetscFunctionBegin; 2047 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2048 PetscValidType(mat,1); 2049 PetscValidIntPointer(rows,4); 2050 PetscValidScalarPointer(v,5); 2051 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2052 2053 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2054 if (mat->ops->setvaluesbatch) { 2055 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 2056 } else { 2057 PetscInt b; 2058 for (b = 0; b < nb; ++b) { 2059 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 2060 } 2061 } 2062 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 2063 PetscFunctionReturn(0); 2064 } 2065 2066 /*@ 2067 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2068 the routine MatSetValuesLocal() to allow users to insert matrix entries 2069 using a local (per-processor) numbering. 2070 2071 Not Collective 2072 2073 Input Parameters: 2074 + x - the matrix 2075 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2076 - cmapping - column mapping 2077 2078 Level: intermediate 2079 2080 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal(), MatGetValuesLocal() 2081 @*/ 2082 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2083 { 2084 PetscErrorCode ierr; 2085 2086 PetscFunctionBegin; 2087 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2088 PetscValidType(x,1); 2089 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2090 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2091 if (x->ops->setlocaltoglobalmapping) { 2092 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2093 } else { 2094 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2095 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2096 } 2097 PetscFunctionReturn(0); 2098 } 2099 2100 /*@ 2101 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2102 2103 Not Collective 2104 2105 Input Parameter: 2106 . A - the matrix 2107 2108 Output Parameters: 2109 + rmapping - row mapping 2110 - cmapping - column mapping 2111 2112 Level: advanced 2113 2114 .seealso: MatSetValuesLocal() 2115 @*/ 2116 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2117 { 2118 PetscFunctionBegin; 2119 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2120 PetscValidType(A,1); 2121 if (rmapping) PetscValidPointer(rmapping,2); 2122 if (cmapping) PetscValidPointer(cmapping,3); 2123 if (rmapping) *rmapping = A->rmap->mapping; 2124 if (cmapping) *cmapping = A->cmap->mapping; 2125 PetscFunctionReturn(0); 2126 } 2127 2128 /*@ 2129 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2130 2131 Logically Collective on A 2132 2133 Input Parameters: 2134 + A - the matrix 2135 . rmap - row layout 2136 - cmap - column layout 2137 2138 Level: advanced 2139 2140 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping(), MatGetLayouts() 2141 @*/ 2142 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2143 { 2144 PetscErrorCode ierr; 2145 2146 PetscFunctionBegin; 2147 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2148 2149 ierr = PetscLayoutReference(rmap,&A->rmap);CHKERRQ(ierr); 2150 ierr = PetscLayoutReference(cmap,&A->cmap);CHKERRQ(ierr); 2151 PetscFunctionReturn(0); 2152 } 2153 2154 /*@ 2155 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2156 2157 Not Collective 2158 2159 Input Parameter: 2160 . A - the matrix 2161 2162 Output Parameters: 2163 + rmap - row layout 2164 - cmap - column layout 2165 2166 Level: advanced 2167 2168 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping(), MatSetLayouts() 2169 @*/ 2170 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2171 { 2172 PetscFunctionBegin; 2173 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2174 PetscValidType(A,1); 2175 if (rmap) PetscValidPointer(rmap,2); 2176 if (cmap) PetscValidPointer(cmap,3); 2177 if (rmap) *rmap = A->rmap; 2178 if (cmap) *cmap = A->cmap; 2179 PetscFunctionReturn(0); 2180 } 2181 2182 /*@C 2183 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2184 using a local numbering of the nodes. 2185 2186 Not Collective 2187 2188 Input Parameters: 2189 + mat - the matrix 2190 . nrow, irow - number of rows and their local indices 2191 . ncol, icol - number of columns and their local indices 2192 . y - a logically two-dimensional array of values 2193 - addv - either INSERT_VALUES or ADD_VALUES, where 2194 ADD_VALUES adds values to any existing entries, and 2195 INSERT_VALUES replaces existing entries with new values 2196 2197 Notes: 2198 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2199 MatSetUp() before using this routine 2200 2201 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2202 2203 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2204 options cannot be mixed without intervening calls to the assembly 2205 routines. 2206 2207 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2208 MUST be called after all calls to MatSetValuesLocal() have been completed. 2209 2210 Level: intermediate 2211 2212 Developer Notes: 2213 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2214 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2215 2216 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2217 MatSetValueLocal(), MatGetValuesLocal() 2218 @*/ 2219 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2220 { 2221 PetscErrorCode ierr; 2222 2223 PetscFunctionBeginHot; 2224 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2225 PetscValidType(mat,1); 2226 MatCheckPreallocated(mat,1); 2227 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2228 PetscValidIntPointer(irow,3); 2229 PetscValidIntPointer(icol,5); 2230 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2231 else PetscCheckFalse(mat->insertmode != addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2232 if (PetscDefined(USE_DEBUG)) { 2233 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2234 PetscCheckFalse(!mat->ops->setvalueslocal && !mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2235 } 2236 2237 if (mat->assembled) { 2238 mat->was_assembled = PETSC_TRUE; 2239 mat->assembled = PETSC_FALSE; 2240 } 2241 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2242 if (mat->ops->setvalueslocal) { 2243 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2244 } else { 2245 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2246 const PetscInt *irowm,*icolm; 2247 2248 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2249 bufr = buf; 2250 bufc = buf + nrow; 2251 irowm = bufr; 2252 icolm = bufc; 2253 } else { 2254 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2255 irowm = bufr; 2256 icolm = bufc; 2257 } 2258 if (mat->rmap->mapping) { ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr);CHKERRQ(ierr); } 2259 else irowm = irow; 2260 if (mat->cmap->mapping) { 2261 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2262 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc);CHKERRQ(ierr); 2263 } else icolm = irowm; 2264 } else icolm = icol; 2265 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2266 if (bufr != buf) { ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); } 2267 } 2268 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2269 PetscFunctionReturn(0); 2270 } 2271 2272 /*@C 2273 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2274 using a local ordering of the nodes a block at a time. 2275 2276 Not Collective 2277 2278 Input Parameters: 2279 + x - the matrix 2280 . nrow, irow - number of rows and their local indices 2281 . ncol, icol - number of columns and their local indices 2282 . y - a logically two-dimensional array of values 2283 - addv - either INSERT_VALUES or ADD_VALUES, where 2284 ADD_VALUES adds values to any existing entries, and 2285 INSERT_VALUES replaces existing entries with new values 2286 2287 Notes: 2288 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2289 MatSetUp() before using this routine 2290 2291 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2292 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2293 2294 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2295 options cannot be mixed without intervening calls to the assembly 2296 routines. 2297 2298 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2299 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2300 2301 Level: intermediate 2302 2303 Developer Notes: 2304 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2305 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2306 2307 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2308 MatSetValuesLocal(), MatSetValuesBlocked() 2309 @*/ 2310 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2311 { 2312 PetscErrorCode ierr; 2313 2314 PetscFunctionBeginHot; 2315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2316 PetscValidType(mat,1); 2317 MatCheckPreallocated(mat,1); 2318 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2319 PetscValidIntPointer(irow,3); 2320 PetscValidIntPointer(icol,5); 2321 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2322 else PetscCheckFalse(mat->insertmode != addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2323 if (PetscDefined(USE_DEBUG)) { 2324 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2325 PetscCheckFalse(!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2326 } 2327 2328 if (mat->assembled) { 2329 mat->was_assembled = PETSC_TRUE; 2330 mat->assembled = PETSC_FALSE; 2331 } 2332 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2333 PetscInt irbs, rbs; 2334 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2335 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2336 PetscCheckFalse(rbs != irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2337 } 2338 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2339 PetscInt icbs, cbs; 2340 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2341 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2342 PetscCheckFalse(cbs != icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2343 } 2344 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2345 if (mat->ops->setvaluesblockedlocal) { 2346 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2347 } else { 2348 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2349 const PetscInt *irowm,*icolm; 2350 2351 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2352 bufr = buf; 2353 bufc = buf + nrow; 2354 irowm = bufr; 2355 icolm = bufc; 2356 } else { 2357 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2358 irowm = bufr; 2359 icolm = bufc; 2360 } 2361 if (mat->rmap->mapping) { ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr);CHKERRQ(ierr); } 2362 else irowm = irow; 2363 if (mat->cmap->mapping) { 2364 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2365 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc);CHKERRQ(ierr); 2366 } else icolm = irowm; 2367 } else icolm = icol; 2368 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2369 if (bufr != buf) { ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); } 2370 } 2371 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2372 PetscFunctionReturn(0); 2373 } 2374 2375 /*@ 2376 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2377 2378 Collective on Mat 2379 2380 Input Parameters: 2381 + mat - the matrix 2382 - x - the vector to be multiplied 2383 2384 Output Parameters: 2385 . y - the result 2386 2387 Notes: 2388 The vectors x and y cannot be the same. I.e., one cannot 2389 call MatMult(A,y,y). 2390 2391 Level: developer 2392 2393 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2394 @*/ 2395 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2396 { 2397 PetscErrorCode ierr; 2398 2399 PetscFunctionBegin; 2400 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2401 PetscValidType(mat,1); 2402 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2403 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2404 2405 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2406 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2407 PetscCheckFalse(x == y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2408 MatCheckPreallocated(mat,1); 2409 2410 PetscCheckFalse(!mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2411 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2412 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2413 PetscFunctionReturn(0); 2414 } 2415 2416 /* --------------------------------------------------------*/ 2417 /*@ 2418 MatMult - Computes the matrix-vector product, y = Ax. 2419 2420 Neighbor-wise Collective on Mat 2421 2422 Input Parameters: 2423 + mat - the matrix 2424 - x - the vector to be multiplied 2425 2426 Output Parameters: 2427 . y - the result 2428 2429 Notes: 2430 The vectors x and y cannot be the same. I.e., one cannot 2431 call MatMult(A,y,y). 2432 2433 Level: beginner 2434 2435 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2436 @*/ 2437 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2438 { 2439 PetscErrorCode ierr; 2440 2441 PetscFunctionBegin; 2442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2443 PetscValidType(mat,1); 2444 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2445 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2446 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2447 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2448 PetscCheckFalse(x == y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2449 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2450 PetscCheckFalse(mat->rmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2451 PetscCheckFalse(mat->cmap->n != x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,x->map->n); 2452 PetscCheckFalse(mat->rmap->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n); 2453 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2454 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2455 MatCheckPreallocated(mat,1); 2456 2457 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2458 PetscCheckFalse(!mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2459 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2460 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2461 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2462 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2463 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2464 PetscFunctionReturn(0); 2465 } 2466 2467 /*@ 2468 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2469 2470 Neighbor-wise Collective on Mat 2471 2472 Input Parameters: 2473 + mat - the matrix 2474 - x - the vector to be multiplied 2475 2476 Output Parameters: 2477 . y - the result 2478 2479 Notes: 2480 The vectors x and y cannot be the same. I.e., one cannot 2481 call MatMultTranspose(A,y,y). 2482 2483 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2484 use MatMultHermitianTranspose() 2485 2486 Level: beginner 2487 2488 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2489 @*/ 2490 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2491 { 2492 PetscErrorCode (*op)(Mat,Vec,Vec)=NULL,ierr; 2493 2494 PetscFunctionBegin; 2495 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2496 PetscValidType(mat,1); 2497 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2498 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2499 2500 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2501 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2502 PetscCheckFalse(x == y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2503 PetscCheckFalse(mat->cmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2504 PetscCheckFalse(mat->rmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2505 PetscCheckFalse(mat->cmap->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2506 PetscCheckFalse(mat->rmap->n != x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2507 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2508 MatCheckPreallocated(mat,1); 2509 2510 if (!mat->ops->multtranspose) { 2511 if (mat->symmetric && mat->ops->mult) op = mat->ops->mult; 2512 PetscCheckFalse(!op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined or is symmetric and does not have a multiply defined",((PetscObject)mat)->type_name); 2513 } else op = mat->ops->multtranspose; 2514 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2515 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2516 ierr = (*op)(mat,x,y);CHKERRQ(ierr); 2517 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2518 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2519 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2520 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2521 PetscFunctionReturn(0); 2522 } 2523 2524 /*@ 2525 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2526 2527 Neighbor-wise Collective on Mat 2528 2529 Input Parameters: 2530 + mat - the matrix 2531 - x - the vector to be multilplied 2532 2533 Output Parameters: 2534 . y - the result 2535 2536 Notes: 2537 The vectors x and y cannot be the same. I.e., one cannot 2538 call MatMultHermitianTranspose(A,y,y). 2539 2540 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2541 2542 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2543 2544 Level: beginner 2545 2546 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2547 @*/ 2548 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2549 { 2550 PetscErrorCode ierr; 2551 2552 PetscFunctionBegin; 2553 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2554 PetscValidType(mat,1); 2555 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2556 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2557 2558 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2559 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2560 PetscCheckFalse(x == y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2561 PetscCheckFalse(mat->cmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2562 PetscCheckFalse(mat->rmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2563 PetscCheckFalse(mat->cmap->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2564 PetscCheckFalse(mat->rmap->n != x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2565 MatCheckPreallocated(mat,1); 2566 2567 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2568 #if defined(PETSC_USE_COMPLEX) 2569 if (mat->ops->multhermitiantranspose || (mat->hermitian && mat->ops->mult)) { 2570 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2571 if (mat->ops->multhermitiantranspose) { 2572 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2573 } else { 2574 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2575 } 2576 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2577 } else { 2578 Vec w; 2579 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2580 ierr = VecCopy(x,w);CHKERRQ(ierr); 2581 ierr = VecConjugate(w);CHKERRQ(ierr); 2582 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2583 ierr = VecDestroy(&w);CHKERRQ(ierr); 2584 ierr = VecConjugate(y);CHKERRQ(ierr); 2585 } 2586 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2587 #else 2588 ierr = MatMultTranspose(mat,x,y);CHKERRQ(ierr); 2589 #endif 2590 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2591 PetscFunctionReturn(0); 2592 } 2593 2594 /*@ 2595 MatMultAdd - Computes v3 = v2 + A * v1. 2596 2597 Neighbor-wise Collective on Mat 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 MatMultAdd(A,v1,v2,v1). 2609 2610 Level: beginner 2611 2612 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2613 @*/ 2614 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2615 { 2616 PetscErrorCode ierr; 2617 2618 PetscFunctionBegin; 2619 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2620 PetscValidType(mat,1); 2621 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2622 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2623 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2624 2625 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2626 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2627 PetscCheckFalse(mat->cmap->N != v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v1->map->N); 2628 /* PetscCheckFalse(mat->rmap->N != v2->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v2->map->N); 2629 PetscCheckFalse(mat->rmap->N != v3->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v3->map->N); */ 2630 PetscCheckFalse(mat->rmap->n != v3->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v3->map->n); 2631 PetscCheckFalse(mat->rmap->n != v2->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v2->map->n); 2632 PetscCheckFalse(v1 == v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2633 MatCheckPreallocated(mat,1); 2634 2635 PetscCheckFalse(!mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2636 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2637 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2638 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2639 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2640 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2641 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2642 PetscFunctionReturn(0); 2643 } 2644 2645 /*@ 2646 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2647 2648 Neighbor-wise Collective on Mat 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 MatMultTransposeAdd(A,v1,v2,v1). 2660 2661 Level: beginner 2662 2663 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2664 @*/ 2665 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2666 { 2667 PetscErrorCode ierr; 2668 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2669 2670 PetscFunctionBegin; 2671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2672 PetscValidType(mat,1); 2673 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2674 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2675 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2676 2677 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2678 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2679 PetscCheckFalse(mat->rmap->N != v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2680 PetscCheckFalse(mat->cmap->N != v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2681 PetscCheckFalse(mat->cmap->N != v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2682 PetscCheckFalse(v1 == v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2683 PetscCheckFalse(!op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2684 MatCheckPreallocated(mat,1); 2685 2686 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2687 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2688 ierr = (*op)(mat,v1,v2,v3);CHKERRQ(ierr); 2689 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2690 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2691 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2692 PetscFunctionReturn(0); 2693 } 2694 2695 /*@ 2696 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2697 2698 Neighbor-wise Collective on Mat 2699 2700 Input Parameters: 2701 + mat - the matrix 2702 - v1, v2 - the vectors 2703 2704 Output Parameters: 2705 . v3 - the result 2706 2707 Notes: 2708 The vectors v1 and v3 cannot be the same. I.e., one cannot 2709 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2710 2711 Level: beginner 2712 2713 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2714 @*/ 2715 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2716 { 2717 PetscErrorCode ierr; 2718 2719 PetscFunctionBegin; 2720 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2721 PetscValidType(mat,1); 2722 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2723 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2724 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2725 2726 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2727 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2728 PetscCheckFalse(v1 == v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2729 PetscCheckFalse(mat->rmap->N != v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2730 PetscCheckFalse(mat->cmap->N != v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2731 PetscCheckFalse(mat->cmap->N != v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2732 MatCheckPreallocated(mat,1); 2733 2734 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2735 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2736 if (mat->ops->multhermitiantransposeadd) { 2737 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2738 } else { 2739 Vec w,z; 2740 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2741 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2742 ierr = VecConjugate(w);CHKERRQ(ierr); 2743 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2744 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2745 ierr = VecDestroy(&w);CHKERRQ(ierr); 2746 ierr = VecConjugate(z);CHKERRQ(ierr); 2747 if (v2 != v3) { 2748 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2749 } else { 2750 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2751 } 2752 ierr = VecDestroy(&z);CHKERRQ(ierr); 2753 } 2754 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2755 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2756 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2757 PetscFunctionReturn(0); 2758 } 2759 2760 /*@ 2761 MatMultConstrained - The inner multiplication routine for a 2762 constrained matrix P^T A P. 2763 2764 Neighbor-wise Collective on Mat 2765 2766 Input Parameters: 2767 + mat - the matrix 2768 - x - the vector to be multilplied 2769 2770 Output Parameters: 2771 . y - the result 2772 2773 Notes: 2774 The vectors x and y cannot be the same. I.e., one cannot 2775 call MatMult(A,y,y). 2776 2777 Level: beginner 2778 2779 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2780 @*/ 2781 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2782 { 2783 PetscErrorCode ierr; 2784 2785 PetscFunctionBegin; 2786 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2787 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2788 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2789 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2790 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2791 PetscCheckFalse(x == y,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2792 PetscCheckFalse(mat->cmap->N != x->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2793 PetscCheckFalse(mat->rmap->N != y->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2794 PetscCheckFalse(mat->rmap->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n); 2795 2796 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2797 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2798 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2799 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2800 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2801 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2802 PetscFunctionReturn(0); 2803 } 2804 2805 /*@ 2806 MatMultTransposeConstrained - The inner multiplication routine for a 2807 constrained matrix P^T A^T P. 2808 2809 Neighbor-wise Collective on Mat 2810 2811 Input Parameters: 2812 + mat - the matrix 2813 - x - the vector to be multilplied 2814 2815 Output Parameters: 2816 . y - the result 2817 2818 Notes: 2819 The vectors x and y cannot be the same. I.e., one cannot 2820 call MatMult(A,y,y). 2821 2822 Level: beginner 2823 2824 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2825 @*/ 2826 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2827 { 2828 PetscErrorCode ierr; 2829 2830 PetscFunctionBegin; 2831 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2832 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2833 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2834 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2835 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2836 PetscCheckFalse(x == y,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2837 PetscCheckFalse(mat->rmap->N != x->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2838 PetscCheckFalse(mat->cmap->N != y->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2839 2840 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2841 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2842 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2843 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2844 PetscFunctionReturn(0); 2845 } 2846 2847 /*@C 2848 MatGetFactorType - gets the type of factorization it is 2849 2850 Not Collective 2851 2852 Input Parameters: 2853 . mat - the matrix 2854 2855 Output Parameters: 2856 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2857 2858 Level: intermediate 2859 2860 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2861 @*/ 2862 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2863 { 2864 PetscFunctionBegin; 2865 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2866 PetscValidType(mat,1); 2867 PetscValidPointer(t,2); 2868 *t = mat->factortype; 2869 PetscFunctionReturn(0); 2870 } 2871 2872 /*@C 2873 MatSetFactorType - sets the type of factorization it is 2874 2875 Logically Collective on Mat 2876 2877 Input Parameters: 2878 + mat - the matrix 2879 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2880 2881 Level: intermediate 2882 2883 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2884 @*/ 2885 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2886 { 2887 PetscFunctionBegin; 2888 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2889 PetscValidType(mat,1); 2890 mat->factortype = t; 2891 PetscFunctionReturn(0); 2892 } 2893 2894 /* ------------------------------------------------------------*/ 2895 /*@C 2896 MatGetInfo - Returns information about matrix storage (number of 2897 nonzeros, memory, etc.). 2898 2899 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2900 2901 Input Parameter: 2902 . mat - the matrix 2903 2904 Output Parameters: 2905 + flag - flag indicating the type of parameters to be returned 2906 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2907 MAT_GLOBAL_SUM - sum over all processors) 2908 - info - matrix information context 2909 2910 Notes: 2911 The MatInfo context contains a variety of matrix data, including 2912 number of nonzeros allocated and used, number of mallocs during 2913 matrix assembly, etc. Additional information for factored matrices 2914 is provided (such as the fill ratio, number of mallocs during 2915 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2916 when using the runtime options 2917 $ -info -mat_view ::ascii_info 2918 2919 Example for C/C++ Users: 2920 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2921 data within the MatInfo context. For example, 2922 .vb 2923 MatInfo info; 2924 Mat A; 2925 double mal, nz_a, nz_u; 2926 2927 MatGetInfo(A,MAT_LOCAL,&info); 2928 mal = info.mallocs; 2929 nz_a = info.nz_allocated; 2930 .ve 2931 2932 Example for Fortran Users: 2933 Fortran users should declare info as a double precision 2934 array of dimension MAT_INFO_SIZE, and then extract the parameters 2935 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2936 a complete list of parameter names. 2937 .vb 2938 double precision info(MAT_INFO_SIZE) 2939 double precision mal, nz_a 2940 Mat A 2941 integer ierr 2942 2943 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2944 mal = info(MAT_INFO_MALLOCS) 2945 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2946 .ve 2947 2948 Level: intermediate 2949 2950 Developer Note: fortran interface is not autogenerated as the f90 2951 interface definition cannot be generated correctly [due to MatInfo] 2952 2953 .seealso: MatStashGetInfo() 2954 2955 @*/ 2956 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2957 { 2958 PetscErrorCode ierr; 2959 2960 PetscFunctionBegin; 2961 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2962 PetscValidType(mat,1); 2963 PetscValidPointer(info,3); 2964 PetscCheckFalse(!mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2965 MatCheckPreallocated(mat,1); 2966 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2967 PetscFunctionReturn(0); 2968 } 2969 2970 /* 2971 This is used by external packages where it is not easy to get the info from the actual 2972 matrix factorization. 2973 */ 2974 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2975 { 2976 PetscErrorCode ierr; 2977 2978 PetscFunctionBegin; 2979 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2980 PetscFunctionReturn(0); 2981 } 2982 2983 /* ----------------------------------------------------------*/ 2984 2985 /*@C 2986 MatLUFactor - Performs in-place LU factorization of matrix. 2987 2988 Collective on Mat 2989 2990 Input Parameters: 2991 + mat - the matrix 2992 . row - row permutation 2993 . col - column permutation 2994 - info - options for factorization, includes 2995 $ fill - expected fill as ratio of original fill. 2996 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2997 $ Run with the option -info to determine an optimal value to use 2998 2999 Notes: 3000 Most users should employ the simplified KSP interface for linear solvers 3001 instead of working directly with matrix algebra routines such as this. 3002 See, e.g., KSPCreate(). 3003 3004 This changes the state of the matrix to a factored matrix; it cannot be used 3005 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3006 3007 Level: developer 3008 3009 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 3010 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 3011 3012 Developer Note: fortran interface is not autogenerated as the f90 3013 interface definition cannot be generated correctly [due to MatFactorInfo] 3014 3015 @*/ 3016 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3017 { 3018 PetscErrorCode ierr; 3019 MatFactorInfo tinfo; 3020 3021 PetscFunctionBegin; 3022 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3023 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3024 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3025 if (info) PetscValidPointer(info,4); 3026 PetscValidType(mat,1); 3027 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3028 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3029 PetscCheckFalse(!mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3030 MatCheckPreallocated(mat,1); 3031 if (!info) { 3032 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3033 info = &tinfo; 3034 } 3035 3036 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 3037 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 3038 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 3039 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3040 PetscFunctionReturn(0); 3041 } 3042 3043 /*@C 3044 MatILUFactor - Performs in-place ILU factorization of matrix. 3045 3046 Collective on Mat 3047 3048 Input Parameters: 3049 + mat - the matrix 3050 . row - row permutation 3051 . col - column permutation 3052 - info - structure containing 3053 $ levels - number of levels of fill. 3054 $ expected fill - as ratio of original fill. 3055 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3056 missing diagonal entries) 3057 3058 Notes: 3059 Probably really in-place only when level of fill is zero, otherwise allocates 3060 new space to store factored matrix and deletes previous memory. 3061 3062 Most users should employ the simplified KSP interface for linear solvers 3063 instead of working directly with matrix algebra routines such as this. 3064 See, e.g., KSPCreate(). 3065 3066 Level: developer 3067 3068 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 3069 3070 Developer Note: fortran interface is not autogenerated as the f90 3071 interface definition cannot be generated correctly [due to MatFactorInfo] 3072 3073 @*/ 3074 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3075 { 3076 PetscErrorCode ierr; 3077 3078 PetscFunctionBegin; 3079 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3080 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3081 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3082 PetscValidPointer(info,4); 3083 PetscValidType(mat,1); 3084 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3085 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3086 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3087 PetscCheckFalse(!mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3088 MatCheckPreallocated(mat,1); 3089 3090 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3091 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 3092 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 3093 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3094 PetscFunctionReturn(0); 3095 } 3096 3097 /*@C 3098 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3099 Call this routine before calling MatLUFactorNumeric(). 3100 3101 Collective on Mat 3102 3103 Input Parameters: 3104 + fact - the factor matrix obtained with MatGetFactor() 3105 . mat - the matrix 3106 . row, col - row and column permutations 3107 - info - options for factorization, includes 3108 $ fill - expected fill as ratio of original fill. 3109 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3110 $ Run with the option -info to determine an optimal value to use 3111 3112 Notes: 3113 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3114 3115 Most users should employ the simplified KSP interface for linear solvers 3116 instead of working directly with matrix algebra routines such as this. 3117 See, e.g., KSPCreate(). 3118 3119 Level: developer 3120 3121 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 3122 3123 Developer Note: fortran interface is not autogenerated as the f90 3124 interface definition cannot be generated correctly [due to MatFactorInfo] 3125 3126 @*/ 3127 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3128 { 3129 PetscErrorCode ierr; 3130 MatFactorInfo tinfo; 3131 3132 PetscFunctionBegin; 3133 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3134 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3135 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3136 if (info) PetscValidPointer(info,5); 3137 PetscValidType(mat,2); 3138 PetscValidPointer(fact,1); 3139 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3140 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3141 if (!(fact)->ops->lufactorsymbolic) { 3142 MatSolverType stype; 3143 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr); 3144 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3145 } 3146 MatCheckPreallocated(mat,2); 3147 if (!info) { 3148 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3149 info = &tinfo; 3150 } 3151 3152 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);} 3153 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3154 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);} 3155 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3156 PetscFunctionReturn(0); 3157 } 3158 3159 /*@C 3160 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3161 Call this routine after first calling MatLUFactorSymbolic(). 3162 3163 Collective on Mat 3164 3165 Input Parameters: 3166 + fact - the factor matrix obtained with MatGetFactor() 3167 . mat - the matrix 3168 - info - options for factorization 3169 3170 Notes: 3171 See MatLUFactor() for in-place factorization. See 3172 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3173 3174 Most users should employ the simplified KSP interface for linear solvers 3175 instead of working directly with matrix algebra routines such as this. 3176 See, e.g., KSPCreate(). 3177 3178 Level: developer 3179 3180 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3181 3182 Developer Note: fortran interface is not autogenerated as the f90 3183 interface definition cannot be generated correctly [due to MatFactorInfo] 3184 3185 @*/ 3186 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3187 { 3188 MatFactorInfo tinfo; 3189 PetscErrorCode ierr; 3190 3191 PetscFunctionBegin; 3192 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3193 PetscValidType(mat,2); 3194 PetscValidPointer(fact,1); 3195 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3196 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3197 PetscCheckFalse(mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3198 3199 PetscCheckFalse(!(fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3200 MatCheckPreallocated(mat,2); 3201 if (!info) { 3202 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3203 info = &tinfo; 3204 } 3205 3206 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);} 3207 else {ierr = PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0);CHKERRQ(ierr);} 3208 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3209 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);} 3210 else {ierr = PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0);CHKERRQ(ierr);} 3211 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3212 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3213 PetscFunctionReturn(0); 3214 } 3215 3216 /*@C 3217 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3218 symmetric matrix. 3219 3220 Collective on Mat 3221 3222 Input Parameters: 3223 + mat - the matrix 3224 . perm - row and column permutations 3225 - f - expected fill as ratio of original fill 3226 3227 Notes: 3228 See MatLUFactor() for the nonsymmetric case. See also 3229 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3230 3231 Most users should employ the simplified KSP interface for linear solvers 3232 instead of working directly with matrix algebra routines such as this. 3233 See, e.g., KSPCreate(). 3234 3235 Level: developer 3236 3237 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3238 MatGetOrdering() 3239 3240 Developer Note: fortran interface is not autogenerated as the f90 3241 interface definition cannot be generated correctly [due to MatFactorInfo] 3242 3243 @*/ 3244 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3245 { 3246 PetscErrorCode ierr; 3247 MatFactorInfo tinfo; 3248 3249 PetscFunctionBegin; 3250 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3251 PetscValidType(mat,1); 3252 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3253 if (info) PetscValidPointer(info,3); 3254 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3255 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3256 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3257 PetscCheckFalse(!mat->ops->choleskyfactor,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); 3258 MatCheckPreallocated(mat,1); 3259 if (!info) { 3260 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3261 info = &tinfo; 3262 } 3263 3264 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3265 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3266 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3267 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3268 PetscFunctionReturn(0); 3269 } 3270 3271 /*@C 3272 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3273 of a symmetric matrix. 3274 3275 Collective on Mat 3276 3277 Input Parameters: 3278 + fact - the factor matrix obtained with MatGetFactor() 3279 . mat - the matrix 3280 . perm - row and column permutations 3281 - info - options for factorization, includes 3282 $ fill - expected fill as ratio of original fill. 3283 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3284 $ Run with the option -info to determine an optimal value to use 3285 3286 Notes: 3287 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3288 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3289 3290 Most users should employ the simplified KSP interface for linear solvers 3291 instead of working directly with matrix algebra routines such as this. 3292 See, e.g., KSPCreate(). 3293 3294 Level: developer 3295 3296 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3297 MatGetOrdering() 3298 3299 Developer Note: fortran interface is not autogenerated as the f90 3300 interface definition cannot be generated correctly [due to MatFactorInfo] 3301 3302 @*/ 3303 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3304 { 3305 PetscErrorCode ierr; 3306 MatFactorInfo tinfo; 3307 3308 PetscFunctionBegin; 3309 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3310 PetscValidType(mat,2); 3311 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3312 if (info) PetscValidPointer(info,4); 3313 PetscValidPointer(fact,1); 3314 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3315 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3316 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3317 if (!(fact)->ops->choleskyfactorsymbolic) { 3318 MatSolverType stype; 3319 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr); 3320 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3321 } 3322 MatCheckPreallocated(mat,2); 3323 if (!info) { 3324 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3325 info = &tinfo; 3326 } 3327 3328 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);} 3329 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3330 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);} 3331 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3332 PetscFunctionReturn(0); 3333 } 3334 3335 /*@C 3336 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3337 of a symmetric matrix. Call this routine after first calling 3338 MatCholeskyFactorSymbolic(). 3339 3340 Collective on Mat 3341 3342 Input Parameters: 3343 + fact - the factor matrix obtained with MatGetFactor() 3344 . mat - the initial matrix 3345 . info - options for factorization 3346 - fact - the symbolic factor of mat 3347 3348 Notes: 3349 Most users should employ the simplified KSP interface for linear solvers 3350 instead of working directly with matrix algebra routines such as this. 3351 See, e.g., KSPCreate(). 3352 3353 Level: developer 3354 3355 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3356 3357 Developer Note: fortran interface is not autogenerated as the f90 3358 interface definition cannot be generated correctly [due to MatFactorInfo] 3359 3360 @*/ 3361 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3362 { 3363 MatFactorInfo tinfo; 3364 PetscErrorCode ierr; 3365 3366 PetscFunctionBegin; 3367 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3368 PetscValidType(mat,2); 3369 PetscValidPointer(fact,1); 3370 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3371 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3372 PetscCheckFalse(!(fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3373 PetscCheckFalse(mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3374 MatCheckPreallocated(mat,2); 3375 if (!info) { 3376 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3377 info = &tinfo; 3378 } 3379 3380 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);} 3381 else {ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0);CHKERRQ(ierr);} 3382 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3383 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);} 3384 else {ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0);CHKERRQ(ierr);} 3385 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3386 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3387 PetscFunctionReturn(0); 3388 } 3389 3390 /*@ 3391 MatQRFactor - Performs in-place QR factorization of matrix. 3392 3393 Collective on Mat 3394 3395 Input Parameters: 3396 + mat - the matrix 3397 . col - column permutation 3398 - info - options for factorization, includes 3399 $ fill - expected fill as ratio of original fill. 3400 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3401 $ Run with the option -info to determine an optimal value to use 3402 3403 Notes: 3404 Most users should employ the simplified KSP interface for linear solvers 3405 instead of working directly with matrix algebra routines such as this. 3406 See, e.g., KSPCreate(). 3407 3408 This changes the state of the matrix to a factored matrix; it cannot be used 3409 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3410 3411 Level: developer 3412 3413 .seealso: MatQRFactorSymbolic(), MatQRFactorNumeric(), MatLUFactor(), 3414 MatSetUnfactored(), MatFactorInfo, MatGetFactor() 3415 3416 Developer Note: fortran interface is not autogenerated as the f90 3417 interface definition cannot be generated correctly [due to MatFactorInfo] 3418 3419 @*/ 3420 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3421 { 3422 PetscErrorCode ierr; 3423 3424 PetscFunctionBegin; 3425 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3426 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3427 if (info) PetscValidPointer(info,3); 3428 PetscValidType(mat,1); 3429 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3430 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3431 MatCheckPreallocated(mat,1); 3432 ierr = PetscLogEventBegin(MAT_QRFactor,mat,col,0,0);CHKERRQ(ierr); 3433 ierr = PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info));CHKERRQ(ierr); 3434 ierr = PetscLogEventEnd(MAT_QRFactor,mat,col,0,0);CHKERRQ(ierr); 3435 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3436 PetscFunctionReturn(0); 3437 } 3438 3439 /*@ 3440 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3441 Call this routine before calling MatQRFactorNumeric(). 3442 3443 Collective on Mat 3444 3445 Input Parameters: 3446 + fact - the factor matrix obtained with MatGetFactor() 3447 . mat - the matrix 3448 . col - column permutation 3449 - info - options for factorization, includes 3450 $ fill - expected fill as ratio of original fill. 3451 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3452 $ Run with the option -info to determine an optimal value to use 3453 3454 Most users should employ the simplified KSP interface for linear solvers 3455 instead of working directly with matrix algebra routines such as this. 3456 See, e.g., KSPCreate(). 3457 3458 Level: developer 3459 3460 .seealso: MatQRFactor(), MatQRFactorNumeric(), MatLUFactor(), MatFactorInfo, MatFactorInfoInitialize() 3461 3462 Developer Note: fortran interface is not autogenerated as the f90 3463 interface definition cannot be generated correctly [due to MatFactorInfo] 3464 3465 @*/ 3466 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3467 { 3468 PetscErrorCode ierr; 3469 MatFactorInfo tinfo; 3470 3471 PetscFunctionBegin; 3472 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3473 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3474 if (info) PetscValidPointer(info,4); 3475 PetscValidType(mat,2); 3476 PetscValidPointer(fact,1); 3477 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3478 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3479 MatCheckPreallocated(mat,2); 3480 if (!info) { 3481 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3482 info = &tinfo; 3483 } 3484 3485 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0);CHKERRQ(ierr);} 3486 ierr = PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info));CHKERRQ(ierr); 3487 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0);CHKERRQ(ierr);} 3488 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3489 PetscFunctionReturn(0); 3490 } 3491 3492 /*@ 3493 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3494 Call this routine after first calling MatQRFactorSymbolic(). 3495 3496 Collective on Mat 3497 3498 Input Parameters: 3499 + fact - the factor matrix obtained with MatGetFactor() 3500 . mat - the matrix 3501 - info - options for factorization 3502 3503 Notes: 3504 See MatQRFactor() for in-place factorization. 3505 3506 Most users should employ the simplified KSP interface for linear solvers 3507 instead of working directly with matrix algebra routines such as this. 3508 See, e.g., KSPCreate(). 3509 3510 Level: developer 3511 3512 .seealso: MatQRFactorSymbolic(), MatLUFactor() 3513 3514 Developer Note: fortran interface is not autogenerated as the f90 3515 interface definition cannot be generated correctly [due to MatFactorInfo] 3516 3517 @*/ 3518 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3519 { 3520 MatFactorInfo tinfo; 3521 PetscErrorCode ierr; 3522 3523 PetscFunctionBegin; 3524 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3525 PetscValidType(mat,2); 3526 PetscValidPointer(fact,1); 3527 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3528 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3529 PetscCheckFalse(mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3530 3531 MatCheckPreallocated(mat,2); 3532 if (!info) { 3533 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3534 info = &tinfo; 3535 } 3536 3537 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);} 3538 else {ierr = PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0);CHKERRQ(ierr);} 3539 ierr = PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info));CHKERRQ(ierr); 3540 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0);CHKERRQ(ierr);} 3541 else {ierr = PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0);CHKERRQ(ierr);} 3542 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3543 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3544 PetscFunctionReturn(0); 3545 } 3546 3547 /* ----------------------------------------------------------------*/ 3548 /*@ 3549 MatSolve - Solves A x = b, given a factored matrix. 3550 3551 Neighbor-wise Collective on Mat 3552 3553 Input Parameters: 3554 + mat - the factored matrix 3555 - b - the right-hand-side vector 3556 3557 Output Parameter: 3558 . x - the result vector 3559 3560 Notes: 3561 The vectors b and x cannot be the same. I.e., one cannot 3562 call MatSolve(A,x,x). 3563 3564 Notes: 3565 Most users should employ the simplified KSP interface for linear solvers 3566 instead of working directly with matrix algebra routines such as this. 3567 See, e.g., KSPCreate(). 3568 3569 Level: developer 3570 3571 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3572 @*/ 3573 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3574 { 3575 PetscErrorCode ierr; 3576 3577 PetscFunctionBegin; 3578 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3579 PetscValidType(mat,1); 3580 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3581 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3582 PetscCheckSameComm(mat,1,b,2); 3583 PetscCheckSameComm(mat,1,x,3); 3584 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3585 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3586 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3587 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3588 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3589 MatCheckPreallocated(mat,1); 3590 3591 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3592 if (mat->factorerrortype) { 3593 ierr = PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype);CHKERRQ(ierr); 3594 ierr = VecSetInf(x);CHKERRQ(ierr); 3595 } else { 3596 PetscCheckFalse(!mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3597 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3598 } 3599 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3600 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3601 PetscFunctionReturn(0); 3602 } 3603 3604 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3605 { 3606 PetscErrorCode ierr; 3607 Vec b,x; 3608 PetscInt N,i; 3609 PetscErrorCode (*f)(Mat,Vec,Vec); 3610 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3611 3612 PetscFunctionBegin; 3613 if (A->factorerrortype) { 3614 ierr = PetscInfo(A,"MatFactorError %d\n",A->factorerrortype);CHKERRQ(ierr); 3615 ierr = MatSetInf(X);CHKERRQ(ierr); 3616 PetscFunctionReturn(0); 3617 } 3618 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3619 PetscCheckFalse(!f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3620 ierr = MatBoundToCPU(A,&Abound);CHKERRQ(ierr); 3621 if (!Abound) { 3622 ierr = PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 3623 ierr = PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 3624 } 3625 if (Bneedconv) { 3626 ierr = MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 3627 } 3628 if (Xneedconv) { 3629 ierr = MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X);CHKERRQ(ierr); 3630 } 3631 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); 3632 for (i=0; i<N; i++) { 3633 ierr = MatDenseGetColumnVecRead(B,i,&b);CHKERRQ(ierr); 3634 ierr = MatDenseGetColumnVecWrite(X,i,&x);CHKERRQ(ierr); 3635 ierr = (*f)(A,b,x);CHKERRQ(ierr); 3636 ierr = MatDenseRestoreColumnVecWrite(X,i,&x);CHKERRQ(ierr); 3637 ierr = MatDenseRestoreColumnVecRead(B,i,&b);CHKERRQ(ierr); 3638 } 3639 if (Bneedconv) { 3640 ierr = MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 3641 } 3642 if (Xneedconv) { 3643 ierr = MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X);CHKERRQ(ierr); 3644 } 3645 PetscFunctionReturn(0); 3646 } 3647 3648 /*@ 3649 MatMatSolve - Solves A X = B, given a factored matrix. 3650 3651 Neighbor-wise Collective on Mat 3652 3653 Input Parameters: 3654 + A - the factored matrix 3655 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3656 3657 Output Parameter: 3658 . X - the result matrix (dense matrix) 3659 3660 Notes: 3661 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3662 otherwise, B and X cannot be the same. 3663 3664 Notes: 3665 Most users should usually employ the simplified KSP interface for linear solvers 3666 instead of working directly with matrix algebra routines such as this. 3667 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3668 at a time. 3669 3670 Level: developer 3671 3672 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3673 @*/ 3674 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3675 { 3676 PetscErrorCode ierr; 3677 3678 PetscFunctionBegin; 3679 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3680 PetscValidType(A,1); 3681 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3682 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3683 PetscCheckSameComm(A,1,B,2); 3684 PetscCheckSameComm(A,1,X,3); 3685 PetscCheckFalse(A->cmap->N != X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3686 PetscCheckFalse(A->rmap->N != B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3687 PetscCheckFalse(X->cmap->N != B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3688 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3689 PetscCheckFalse(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3690 MatCheckPreallocated(A,1); 3691 3692 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3693 if (!A->ops->matsolve) { 3694 ierr = PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3695 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3696 } else { 3697 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3698 } 3699 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3700 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3701 PetscFunctionReturn(0); 3702 } 3703 3704 /*@ 3705 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3706 3707 Neighbor-wise Collective on Mat 3708 3709 Input Parameters: 3710 + A - the factored matrix 3711 - B - the right-hand-side matrix (dense matrix) 3712 3713 Output Parameter: 3714 . X - the result matrix (dense matrix) 3715 3716 Notes: 3717 The matrices B and X cannot be the same. I.e., one cannot 3718 call MatMatSolveTranspose(A,X,X). 3719 3720 Notes: 3721 Most users should usually employ the simplified KSP interface for linear solvers 3722 instead of working directly with matrix algebra routines such as this. 3723 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3724 at a time. 3725 3726 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3727 3728 Level: developer 3729 3730 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3731 @*/ 3732 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3733 { 3734 PetscErrorCode ierr; 3735 3736 PetscFunctionBegin; 3737 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3738 PetscValidType(A,1); 3739 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3740 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3741 PetscCheckSameComm(A,1,B,2); 3742 PetscCheckSameComm(A,1,X,3); 3743 PetscCheckFalse(X == B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3744 PetscCheckFalse(A->cmap->N != X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3745 PetscCheckFalse(A->rmap->N != B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3746 PetscCheckFalse(A->rmap->n != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->n,B->rmap->n); 3747 PetscCheckFalse(X->cmap->N < B->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3748 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3749 PetscCheckFalse(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3750 MatCheckPreallocated(A,1); 3751 3752 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3753 if (!A->ops->matsolvetranspose) { 3754 ierr = PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3755 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3756 } else { 3757 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3758 } 3759 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3760 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3761 PetscFunctionReturn(0); 3762 } 3763 3764 /*@ 3765 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3766 3767 Neighbor-wise Collective on Mat 3768 3769 Input Parameters: 3770 + A - the factored matrix 3771 - Bt - the transpose of right-hand-side matrix 3772 3773 Output Parameter: 3774 . X - the result matrix (dense matrix) 3775 3776 Notes: 3777 Most users should usually employ the simplified KSP interface for linear solvers 3778 instead of working directly with matrix algebra routines such as this. 3779 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3780 at a time. 3781 3782 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(). 3783 3784 Level: developer 3785 3786 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3787 @*/ 3788 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3789 { 3790 PetscErrorCode ierr; 3791 3792 PetscFunctionBegin; 3793 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3794 PetscValidType(A,1); 3795 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3796 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3797 PetscCheckSameComm(A,1,Bt,2); 3798 PetscCheckSameComm(A,1,X,3); 3799 3800 PetscCheckFalse(X == Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3801 PetscCheckFalse(A->cmap->N != X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3802 PetscCheckFalse(A->rmap->N != Bt->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,Bt->cmap->N); 3803 PetscCheckFalse(X->cmap->N < Bt->rmap->N,PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3804 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3805 PetscCheckFalse(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3806 MatCheckPreallocated(A,1); 3807 3808 PetscCheckFalse(!A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3809 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3810 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3811 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3812 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3813 PetscFunctionReturn(0); 3814 } 3815 3816 /*@ 3817 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3818 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3819 3820 Neighbor-wise Collective on Mat 3821 3822 Input Parameters: 3823 + mat - the factored matrix 3824 - b - the right-hand-side vector 3825 3826 Output Parameter: 3827 . x - the result vector 3828 3829 Notes: 3830 MatSolve() should be used for most applications, as it performs 3831 a forward solve followed by a backward solve. 3832 3833 The vectors b and x cannot be the same, i.e., one cannot 3834 call MatForwardSolve(A,x,x). 3835 3836 For matrix in seqsbaij format with block size larger than 1, 3837 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3838 MatForwardSolve() solves U^T*D y = b, and 3839 MatBackwardSolve() solves U x = y. 3840 Thus they do not provide a symmetric preconditioner. 3841 3842 Most users should employ the simplified KSP interface for linear solvers 3843 instead of working directly with matrix algebra routines such as this. 3844 See, e.g., KSPCreate(). 3845 3846 Level: developer 3847 3848 .seealso: MatSolve(), MatBackwardSolve() 3849 @*/ 3850 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3851 { 3852 PetscErrorCode ierr; 3853 3854 PetscFunctionBegin; 3855 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3856 PetscValidType(mat,1); 3857 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3858 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3859 PetscCheckSameComm(mat,1,b,2); 3860 PetscCheckSameComm(mat,1,x,3); 3861 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3862 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3863 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3864 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3865 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3866 MatCheckPreallocated(mat,1); 3867 3868 PetscCheckFalse(!mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3869 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3870 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3871 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3872 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3873 PetscFunctionReturn(0); 3874 } 3875 3876 /*@ 3877 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3878 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3879 3880 Neighbor-wise Collective on Mat 3881 3882 Input Parameters: 3883 + mat - the factored matrix 3884 - b - the right-hand-side vector 3885 3886 Output Parameter: 3887 . x - the result vector 3888 3889 Notes: 3890 MatSolve() should be used for most applications, as it performs 3891 a forward solve followed by a backward solve. 3892 3893 The vectors b and x cannot be the same. I.e., one cannot 3894 call MatBackwardSolve(A,x,x). 3895 3896 For matrix in seqsbaij format with block size larger than 1, 3897 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3898 MatForwardSolve() solves U^T*D y = b, and 3899 MatBackwardSolve() solves U x = y. 3900 Thus they do not provide a symmetric preconditioner. 3901 3902 Most users should employ the simplified KSP interface for linear solvers 3903 instead of working directly with matrix algebra routines such as this. 3904 See, e.g., KSPCreate(). 3905 3906 Level: developer 3907 3908 .seealso: MatSolve(), MatForwardSolve() 3909 @*/ 3910 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3911 { 3912 PetscErrorCode ierr; 3913 3914 PetscFunctionBegin; 3915 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3916 PetscValidType(mat,1); 3917 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3918 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3919 PetscCheckSameComm(mat,1,b,2); 3920 PetscCheckSameComm(mat,1,x,3); 3921 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3922 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3923 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3924 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3925 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3926 MatCheckPreallocated(mat,1); 3927 3928 PetscCheckFalse(!mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3929 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3930 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3931 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3932 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3933 PetscFunctionReturn(0); 3934 } 3935 3936 /*@ 3937 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3938 3939 Neighbor-wise Collective on Mat 3940 3941 Input Parameters: 3942 + mat - the factored matrix 3943 . b - the right-hand-side vector 3944 - y - the vector to be added to 3945 3946 Output Parameter: 3947 . x - the result vector 3948 3949 Notes: 3950 The vectors b and x cannot be the same. I.e., one cannot 3951 call MatSolveAdd(A,x,y,x). 3952 3953 Most users should employ the simplified KSP interface for linear solvers 3954 instead of working directly with matrix algebra routines such as this. 3955 See, e.g., KSPCreate(). 3956 3957 Level: developer 3958 3959 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3960 @*/ 3961 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3962 { 3963 PetscScalar one = 1.0; 3964 Vec tmp; 3965 PetscErrorCode ierr; 3966 3967 PetscFunctionBegin; 3968 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3969 PetscValidType(mat,1); 3970 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3971 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3972 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3973 PetscCheckSameComm(mat,1,b,2); 3974 PetscCheckSameComm(mat,1,y,3); 3975 PetscCheckSameComm(mat,1,x,4); 3976 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3977 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3978 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3979 PetscCheckFalse(mat->rmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 3980 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3981 PetscCheckFalse(x->map->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 3982 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3983 MatCheckPreallocated(mat,1); 3984 3985 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3986 if (mat->factorerrortype) { 3987 3988 ierr = PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype);CHKERRQ(ierr); 3989 ierr = VecSetInf(x);CHKERRQ(ierr); 3990 } else if (mat->ops->solveadd) { 3991 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3992 } else { 3993 /* do the solve then the add manually */ 3994 if (x != y) { 3995 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3996 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3997 } else { 3998 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3999 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 4000 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 4001 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 4002 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 4003 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 4004 } 4005 } 4006 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 4007 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4008 PetscFunctionReturn(0); 4009 } 4010 4011 /*@ 4012 MatSolveTranspose - Solves A' x = b, given a factored matrix. 4013 4014 Neighbor-wise Collective on Mat 4015 4016 Input Parameters: 4017 + mat - the factored matrix 4018 - b - the right-hand-side vector 4019 4020 Output Parameter: 4021 . x - the result vector 4022 4023 Notes: 4024 The vectors b and x cannot be the same. I.e., one cannot 4025 call MatSolveTranspose(A,x,x). 4026 4027 Most users should employ the simplified KSP interface for linear solvers 4028 instead of working directly with matrix algebra routines such as this. 4029 See, e.g., KSPCreate(). 4030 4031 Level: developer 4032 4033 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 4034 @*/ 4035 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 4036 { 4037 PetscErrorCode ierr; 4038 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 4039 4040 PetscFunctionBegin; 4041 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4042 PetscValidType(mat,1); 4043 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4044 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4045 PetscCheckSameComm(mat,1,b,2); 4046 PetscCheckSameComm(mat,1,x,3); 4047 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4048 PetscCheckFalse(mat->rmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 4049 PetscCheckFalse(mat->cmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 4050 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4051 MatCheckPreallocated(mat,1); 4052 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 4053 if (mat->factorerrortype) { 4054 ierr = PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype);CHKERRQ(ierr); 4055 ierr = VecSetInf(x);CHKERRQ(ierr); 4056 } else { 4057 PetscCheckFalse(!f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 4058 ierr = (*f)(mat,b,x);CHKERRQ(ierr); 4059 } 4060 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 4061 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4062 PetscFunctionReturn(0); 4063 } 4064 4065 /*@ 4066 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 4067 factored matrix. 4068 4069 Neighbor-wise Collective on Mat 4070 4071 Input Parameters: 4072 + mat - the factored matrix 4073 . b - the right-hand-side vector 4074 - y - the vector to be added to 4075 4076 Output Parameter: 4077 . x - the result vector 4078 4079 Notes: 4080 The vectors b and x cannot be the same. I.e., one cannot 4081 call MatSolveTransposeAdd(A,x,y,x). 4082 4083 Most users should employ the simplified KSP interface for linear solvers 4084 instead of working directly with matrix algebra routines such as this. 4085 See, e.g., KSPCreate(). 4086 4087 Level: developer 4088 4089 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 4090 @*/ 4091 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4092 { 4093 PetscScalar one = 1.0; 4094 PetscErrorCode ierr; 4095 Vec tmp; 4096 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4097 4098 PetscFunctionBegin; 4099 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4100 PetscValidType(mat,1); 4101 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4102 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4103 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4104 PetscCheckSameComm(mat,1,b,2); 4105 PetscCheckSameComm(mat,1,y,3); 4106 PetscCheckSameComm(mat,1,x,4); 4107 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4108 PetscCheckFalse(mat->rmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 4109 PetscCheckFalse(mat->cmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 4110 PetscCheckFalse(mat->cmap->N != y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 4111 PetscCheckFalse(x->map->n != y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 4112 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4113 MatCheckPreallocated(mat,1); 4114 4115 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 4116 if (mat->factorerrortype) { 4117 ierr = PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype);CHKERRQ(ierr); 4118 ierr = VecSetInf(x);CHKERRQ(ierr); 4119 } else if (f) { 4120 ierr = (*f)(mat,b,y,x);CHKERRQ(ierr); 4121 } else { 4122 /* do the solve then the add manually */ 4123 if (x != y) { 4124 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 4125 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 4126 } else { 4127 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 4128 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 4129 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 4130 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 4131 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 4132 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 4133 } 4134 } 4135 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 4136 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4137 PetscFunctionReturn(0); 4138 } 4139 /* ----------------------------------------------------------------*/ 4140 4141 /*@ 4142 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4143 4144 Neighbor-wise Collective on Mat 4145 4146 Input Parameters: 4147 + mat - the matrix 4148 . b - the right hand side 4149 . omega - the relaxation factor 4150 . flag - flag indicating the type of SOR (see below) 4151 . shift - diagonal shift 4152 . its - the number of iterations 4153 - lits - the number of local iterations 4154 4155 Output Parameter: 4156 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4157 4158 SOR Flags: 4159 + SOR_FORWARD_SWEEP - forward SOR 4160 . SOR_BACKWARD_SWEEP - backward SOR 4161 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4162 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4163 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4164 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4165 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4166 upper/lower triangular part of matrix to 4167 vector (with omega) 4168 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4169 4170 Notes: 4171 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4172 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4173 on each processor. 4174 4175 Application programmers will not generally use MatSOR() directly, 4176 but instead will employ the KSP/PC interface. 4177 4178 Notes: 4179 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4180 4181 Notes for Advanced Users: 4182 The flags are implemented as bitwise inclusive or operations. 4183 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4184 to specify a zero initial guess for SSOR. 4185 4186 Most users should employ the simplified KSP interface for linear solvers 4187 instead of working directly with matrix algebra routines such as this. 4188 See, e.g., KSPCreate(). 4189 4190 Vectors x and b CANNOT be the same 4191 4192 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4193 4194 Level: developer 4195 4196 @*/ 4197 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4198 { 4199 PetscErrorCode ierr; 4200 4201 PetscFunctionBegin; 4202 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4203 PetscValidType(mat,1); 4204 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4205 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4206 PetscCheckSameComm(mat,1,b,2); 4207 PetscCheckSameComm(mat,1,x,8); 4208 PetscCheckFalse(!mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4209 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4210 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4211 PetscCheckFalse(mat->cmap->N != x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 4212 PetscCheckFalse(mat->rmap->N != b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 4213 PetscCheckFalse(mat->rmap->n != b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 4214 PetscCheckFalse(its <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4215 PetscCheckFalse(lits <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4216 PetscCheckFalse(b == x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4217 4218 MatCheckPreallocated(mat,1); 4219 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4220 ierr = (*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 4221 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 4222 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 4223 PetscFunctionReturn(0); 4224 } 4225 4226 /* 4227 Default matrix copy routine. 4228 */ 4229 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4230 { 4231 PetscErrorCode ierr; 4232 PetscInt i,rstart = 0,rend = 0,nz; 4233 const PetscInt *cwork; 4234 const PetscScalar *vwork; 4235 4236 PetscFunctionBegin; 4237 if (B->assembled) { 4238 ierr = MatZeroEntries(B);CHKERRQ(ierr); 4239 } 4240 if (str == SAME_NONZERO_PATTERN) { 4241 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 4242 for (i=rstart; i<rend; i++) { 4243 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4244 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 4245 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 4246 } 4247 } else { 4248 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 4249 } 4250 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4251 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4252 PetscFunctionReturn(0); 4253 } 4254 4255 /*@ 4256 MatCopy - Copies a matrix to another matrix. 4257 4258 Collective on Mat 4259 4260 Input Parameters: 4261 + A - the matrix 4262 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4263 4264 Output Parameter: 4265 . B - where the copy is put 4266 4267 Notes: 4268 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4269 4270 MatCopy() copies the matrix entries of a matrix to another existing 4271 matrix (after first zeroing the second matrix). A related routine is 4272 MatConvert(), which first creates a new matrix and then copies the data. 4273 4274 Level: intermediate 4275 4276 .seealso: MatConvert(), MatDuplicate() 4277 @*/ 4278 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4279 { 4280 PetscErrorCode ierr; 4281 PetscInt i; 4282 4283 PetscFunctionBegin; 4284 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4285 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4286 PetscValidType(A,1); 4287 PetscValidType(B,2); 4288 PetscCheckSameComm(A,1,B,2); 4289 MatCheckPreallocated(B,2); 4290 PetscCheckFalse(!A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4291 PetscCheckFalse(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4292 PetscCheckFalse(A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%" PetscInt_FMT ",%" PetscInt_FMT ") (%" PetscInt_FMT ",%" PetscInt_FMT ")",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 4293 MatCheckPreallocated(A,1); 4294 if (A == B) PetscFunctionReturn(0); 4295 4296 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4297 if (A->ops->copy) { 4298 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4299 } else { /* generic conversion */ 4300 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4301 } 4302 4303 B->stencil.dim = A->stencil.dim; 4304 B->stencil.noc = A->stencil.noc; 4305 for (i=0; i<=A->stencil.dim; i++) { 4306 B->stencil.dims[i] = A->stencil.dims[i]; 4307 B->stencil.starts[i] = A->stencil.starts[i]; 4308 } 4309 4310 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4311 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4312 PetscFunctionReturn(0); 4313 } 4314 4315 /*@C 4316 MatConvert - Converts a matrix to another matrix, either of the same 4317 or different type. 4318 4319 Collective on Mat 4320 4321 Input Parameters: 4322 + mat - the matrix 4323 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4324 same type as the original matrix. 4325 - reuse - denotes if the destination matrix is to be created or reused. 4326 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 4327 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). 4328 4329 Output Parameter: 4330 . M - pointer to place new matrix 4331 4332 Notes: 4333 MatConvert() first creates a new matrix and then copies the data from 4334 the first matrix. A related routine is MatCopy(), which copies the matrix 4335 entries of one matrix to another already existing matrix context. 4336 4337 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4338 the MPI communicator of the generated matrix is always the same as the communicator 4339 of the input matrix. 4340 4341 Level: intermediate 4342 4343 .seealso: MatCopy(), MatDuplicate() 4344 @*/ 4345 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4346 { 4347 PetscErrorCode ierr; 4348 PetscBool sametype,issame,flg,issymmetric,ishermitian; 4349 char convname[256],mtype[256]; 4350 Mat B; 4351 4352 PetscFunctionBegin; 4353 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4354 PetscValidType(mat,1); 4355 PetscValidPointer(M,4); 4356 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4357 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4358 MatCheckPreallocated(mat,1); 4359 4360 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg);CHKERRQ(ierr); 4361 if (flg) newtype = mtype; 4362 4363 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4364 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4365 PetscCheckFalse((reuse == MAT_INPLACE_MATRIX) && (mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4366 PetscCheckFalse((reuse == MAT_REUSE_MATRIX) && (mat == *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4367 4368 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4369 ierr = PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4370 PetscFunctionReturn(0); 4371 } 4372 4373 /* Cache Mat options because some converter use MatHeaderReplace */ 4374 issymmetric = mat->symmetric; 4375 ishermitian = mat->hermitian; 4376 4377 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4378 ierr = PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4379 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4380 } else { 4381 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4382 const char *prefix[3] = {"seq","mpi",""}; 4383 PetscInt i; 4384 /* 4385 Order of precedence: 4386 0) See if newtype is a superclass of the current matrix. 4387 1) See if a specialized converter is known to the current matrix. 4388 2) See if a specialized converter is known to the desired matrix class. 4389 3) See if a good general converter is registered for the desired class 4390 (as of 6/27/03 only MATMPIADJ falls into this category). 4391 4) See if a good general converter is known for the current matrix. 4392 5) Use a really basic converter. 4393 */ 4394 4395 /* 0) See if newtype is a superclass of the current matrix. 4396 i.e mat is mpiaij and newtype is aij */ 4397 for (i=0; i<2; i++) { 4398 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4399 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4400 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4401 ierr = PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4402 if (flg) { 4403 if (reuse == MAT_INPLACE_MATRIX) { 4404 ierr = PetscInfo(mat,"Early return\n");CHKERRQ(ierr); 4405 PetscFunctionReturn(0); 4406 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4407 ierr = PetscInfo(mat,"Calling MatDuplicate\n");CHKERRQ(ierr); 4408 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4409 PetscFunctionReturn(0); 4410 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4411 ierr = PetscInfo(mat,"Calling MatCopy\n");CHKERRQ(ierr); 4412 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4413 PetscFunctionReturn(0); 4414 } 4415 } 4416 } 4417 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4418 for (i=0; i<3; i++) { 4419 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4420 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4421 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4422 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4423 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4424 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4425 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4426 ierr = PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4427 if (conv) goto foundconv; 4428 } 4429 4430 /* 2) See if a specialized converter is known to the desired matrix class. */ 4431 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4432 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4433 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4434 for (i=0; i<3; i++) { 4435 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4436 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4437 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4438 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4439 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4440 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4441 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4442 ierr = PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4443 if (conv) { 4444 ierr = MatDestroy(&B);CHKERRQ(ierr); 4445 goto foundconv; 4446 } 4447 } 4448 4449 /* 3) See if a good general converter is registered for the desired class */ 4450 conv = B->ops->convertfrom; 4451 ierr = PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4452 ierr = MatDestroy(&B);CHKERRQ(ierr); 4453 if (conv) goto foundconv; 4454 4455 /* 4) See if a good general converter is known for the current matrix */ 4456 if (mat->ops->convert) conv = mat->ops->convert; 4457 ierr = PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4458 if (conv) goto foundconv; 4459 4460 /* 5) Use a really basic converter. */ 4461 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr); 4462 conv = MatConvert_Basic; 4463 4464 foundconv: 4465 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4466 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4467 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4468 /* the block sizes must be same if the mappings are copied over */ 4469 (*M)->rmap->bs = mat->rmap->bs; 4470 (*M)->cmap->bs = mat->cmap->bs; 4471 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4472 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4473 (*M)->rmap->mapping = mat->rmap->mapping; 4474 (*M)->cmap->mapping = mat->cmap->mapping; 4475 } 4476 (*M)->stencil.dim = mat->stencil.dim; 4477 (*M)->stencil.noc = mat->stencil.noc; 4478 for (i=0; i<=mat->stencil.dim; i++) { 4479 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4480 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4481 } 4482 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4483 } 4484 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4485 4486 /* Copy Mat options */ 4487 if (issymmetric) { 4488 ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 4489 } 4490 if (ishermitian) { 4491 ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 4492 } 4493 PetscFunctionReturn(0); 4494 } 4495 4496 /*@C 4497 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4498 4499 Not Collective 4500 4501 Input Parameter: 4502 . mat - the matrix, must be a factored matrix 4503 4504 Output Parameter: 4505 . type - the string name of the package (do not free this string) 4506 4507 Notes: 4508 In Fortran you pass in a empty string and the package name will be copied into it. 4509 (Make sure the string is long enough) 4510 4511 Level: intermediate 4512 4513 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4514 @*/ 4515 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4516 { 4517 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4518 4519 PetscFunctionBegin; 4520 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4521 PetscValidType(mat,1); 4522 PetscCheckFalse(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4523 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4524 if (!conv) { 4525 *type = MATSOLVERPETSC; 4526 } else { 4527 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4528 } 4529 PetscFunctionReturn(0); 4530 } 4531 4532 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4533 struct _MatSolverTypeForSpecifcType { 4534 MatType mtype; 4535 /* no entry for MAT_FACTOR_NONE */ 4536 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4537 MatSolverTypeForSpecifcType next; 4538 }; 4539 4540 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4541 struct _MatSolverTypeHolder { 4542 char *name; 4543 MatSolverTypeForSpecifcType handlers; 4544 MatSolverTypeHolder next; 4545 }; 4546 4547 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4548 4549 /*@C 4550 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4551 4552 Input Parameters: 4553 + package - name of the package, for example petsc or superlu 4554 . mtype - the matrix type that works with this package 4555 . ftype - the type of factorization supported by the package 4556 - createfactor - routine that will create the factored matrix ready to be used 4557 4558 Level: intermediate 4559 4560 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4561 @*/ 4562 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4563 { 4564 PetscErrorCode ierr; 4565 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4566 PetscBool flg; 4567 MatSolverTypeForSpecifcType inext,iprev = NULL; 4568 4569 PetscFunctionBegin; 4570 ierr = MatInitializePackage();CHKERRQ(ierr); 4571 if (!next) { 4572 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4573 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4574 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4575 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4576 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4577 PetscFunctionReturn(0); 4578 } 4579 while (next) { 4580 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4581 if (flg) { 4582 PetscCheckFalse(!next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4583 inext = next->handlers; 4584 while (inext) { 4585 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4586 if (flg) { 4587 inext->createfactor[(int)ftype-1] = createfactor; 4588 PetscFunctionReturn(0); 4589 } 4590 iprev = inext; 4591 inext = inext->next; 4592 } 4593 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4594 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4595 iprev->next->createfactor[(int)ftype-1] = createfactor; 4596 PetscFunctionReturn(0); 4597 } 4598 prev = next; 4599 next = next->next; 4600 } 4601 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4602 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4603 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4604 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4605 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4606 PetscFunctionReturn(0); 4607 } 4608 4609 /*@C 4610 MatSolveTypeGet - Gets the function that creates the factor matrix if it exist 4611 4612 Input Parameters: 4613 + type - name of the package, for example petsc or superlu 4614 . ftype - the type of factorization supported by the type 4615 - mtype - the matrix type that works with this type 4616 4617 Output Parameters: 4618 + foundtype - PETSC_TRUE if the type was registered 4619 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4620 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4621 4622 Level: intermediate 4623 4624 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatSolverTypeRegister(), MatGetFactor() 4625 @*/ 4626 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4627 { 4628 PetscErrorCode ierr; 4629 MatSolverTypeHolder next = MatSolverTypeHolders; 4630 PetscBool flg; 4631 MatSolverTypeForSpecifcType inext; 4632 4633 PetscFunctionBegin; 4634 if (foundtype) *foundtype = PETSC_FALSE; 4635 if (foundmtype) *foundmtype = PETSC_FALSE; 4636 if (createfactor) *createfactor = NULL; 4637 4638 if (type) { 4639 while (next) { 4640 ierr = PetscStrcasecmp(type,next->name,&flg);CHKERRQ(ierr); 4641 if (flg) { 4642 if (foundtype) *foundtype = PETSC_TRUE; 4643 inext = next->handlers; 4644 while (inext) { 4645 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4646 if (flg) { 4647 if (foundmtype) *foundmtype = PETSC_TRUE; 4648 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4649 PetscFunctionReturn(0); 4650 } 4651 inext = inext->next; 4652 } 4653 } 4654 next = next->next; 4655 } 4656 } else { 4657 while (next) { 4658 inext = next->handlers; 4659 while (inext) { 4660 ierr = PetscStrcmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4661 if (flg && inext->createfactor[(int)ftype-1]) { 4662 if (foundtype) *foundtype = PETSC_TRUE; 4663 if (foundmtype) *foundmtype = PETSC_TRUE; 4664 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4665 PetscFunctionReturn(0); 4666 } 4667 inext = inext->next; 4668 } 4669 next = next->next; 4670 } 4671 /* try with base classes inext->mtype */ 4672 next = MatSolverTypeHolders; 4673 while (next) { 4674 inext = next->handlers; 4675 while (inext) { 4676 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4677 if (flg && inext->createfactor[(int)ftype-1]) { 4678 if (foundtype) *foundtype = PETSC_TRUE; 4679 if (foundmtype) *foundmtype = PETSC_TRUE; 4680 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4681 PetscFunctionReturn(0); 4682 } 4683 inext = inext->next; 4684 } 4685 next = next->next; 4686 } 4687 } 4688 PetscFunctionReturn(0); 4689 } 4690 4691 PetscErrorCode MatSolverTypeDestroy(void) 4692 { 4693 PetscErrorCode ierr; 4694 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4695 MatSolverTypeForSpecifcType inext,iprev; 4696 4697 PetscFunctionBegin; 4698 while (next) { 4699 ierr = PetscFree(next->name);CHKERRQ(ierr); 4700 inext = next->handlers; 4701 while (inext) { 4702 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4703 iprev = inext; 4704 inext = inext->next; 4705 ierr = PetscFree(iprev);CHKERRQ(ierr); 4706 } 4707 prev = next; 4708 next = next->next; 4709 ierr = PetscFree(prev);CHKERRQ(ierr); 4710 } 4711 MatSolverTypeHolders = NULL; 4712 PetscFunctionReturn(0); 4713 } 4714 4715 /*@C 4716 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4717 4718 Logically Collective on Mat 4719 4720 Input Parameters: 4721 . mat - the matrix 4722 4723 Output Parameters: 4724 . flg - PETSC_TRUE if uses the ordering 4725 4726 Notes: 4727 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4728 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4729 4730 Level: developer 4731 4732 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4733 @*/ 4734 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4735 { 4736 PetscFunctionBegin; 4737 *flg = mat->canuseordering; 4738 PetscFunctionReturn(0); 4739 } 4740 4741 /*@C 4742 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4743 4744 Logically Collective on Mat 4745 4746 Input Parameters: 4747 . mat - the matrix 4748 4749 Output Parameters: 4750 . otype - the preferred type 4751 4752 Level: developer 4753 4754 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor(), MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4755 @*/ 4756 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4757 { 4758 PetscFunctionBegin; 4759 *otype = mat->preferredordering[ftype]; 4760 PetscCheckFalse(!*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4761 PetscFunctionReturn(0); 4762 } 4763 4764 /*@C 4765 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4766 4767 Collective on Mat 4768 4769 Input Parameters: 4770 + mat - the matrix 4771 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4772 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4773 4774 Output Parameters: 4775 . f - the factor matrix used with MatXXFactorSymbolic() calls 4776 4777 Notes: 4778 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4779 such as pastix, superlu, mumps etc. 4780 4781 PETSc must have been ./configure to use the external solver, using the option --download-package 4782 4783 Developer Notes: 4784 This should actually be called MatCreateFactor() since it creates a new factor object 4785 4786 Level: intermediate 4787 4788 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatFactorGetCanUseOrdering(), MatSolverTypeRegister() 4789 @*/ 4790 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4791 { 4792 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4793 PetscBool foundtype,foundmtype; 4794 4795 PetscFunctionBegin; 4796 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4797 PetscValidType(mat,1); 4798 4799 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4800 MatCheckPreallocated(mat,1); 4801 4802 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv);CHKERRQ(ierr); 4803 if (!foundtype) { 4804 if (type) { 4805 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver type %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type); 4806 } else { 4807 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver type for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4808 } 4809 } 4810 PetscCheckFalse(!foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4811 PetscCheckFalse(!conv,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); 4812 4813 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4814 PetscFunctionReturn(0); 4815 } 4816 4817 /*@C 4818 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4819 4820 Not Collective 4821 4822 Input Parameters: 4823 + mat - the matrix 4824 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4825 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4826 4827 Output Parameter: 4828 . flg - PETSC_TRUE if the factorization is available 4829 4830 Notes: 4831 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4832 such as pastix, superlu, mumps etc. 4833 4834 PETSc must have been ./configure to use the external solver, using the option --download-package 4835 4836 Developer Notes: 4837 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4838 4839 Level: intermediate 4840 4841 .seealso: MatCopy(), MatDuplicate(), MatGetFactor(), MatSolverTypeRegister() 4842 @*/ 4843 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4844 { 4845 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4846 4847 PetscFunctionBegin; 4848 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4849 PetscValidType(mat,1); 4850 4851 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4852 MatCheckPreallocated(mat,1); 4853 4854 *flg = PETSC_FALSE; 4855 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4856 if (gconv) { 4857 *flg = PETSC_TRUE; 4858 } 4859 PetscFunctionReturn(0); 4860 } 4861 4862 /*@ 4863 MatDuplicate - Duplicates a matrix including the non-zero structure. 4864 4865 Collective on Mat 4866 4867 Input Parameters: 4868 + mat - the matrix 4869 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4870 See the manual page for MatDuplicateOption for an explanation of these options. 4871 4872 Output Parameter: 4873 . M - pointer to place new matrix 4874 4875 Level: intermediate 4876 4877 Notes: 4878 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4879 May be called with an unassembled input Mat if MAT_DO_NOT_COPY_VALUES is used, in which case the output Mat is unassembled as well. 4880 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. 4881 4882 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4883 @*/ 4884 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4885 { 4886 PetscErrorCode ierr; 4887 Mat B; 4888 VecType vtype; 4889 PetscInt i; 4890 PetscObject dm; 4891 void (*viewf)(void); 4892 4893 PetscFunctionBegin; 4894 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4895 PetscValidType(mat,1); 4896 PetscValidPointer(M,3); 4897 PetscCheckFalse(op == MAT_COPY_VALUES && !mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4898 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4899 MatCheckPreallocated(mat,1); 4900 4901 *M = NULL; 4902 PetscCheckFalse(!mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4903 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4904 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4905 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4906 B = *M; 4907 4908 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4909 if (viewf) { 4910 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4911 } 4912 ierr = MatGetVecType(mat,&vtype);CHKERRQ(ierr); 4913 ierr = MatSetVecType(B,vtype);CHKERRQ(ierr); 4914 4915 B->stencil.dim = mat->stencil.dim; 4916 B->stencil.noc = mat->stencil.noc; 4917 for (i=0; i<=mat->stencil.dim; i++) { 4918 B->stencil.dims[i] = mat->stencil.dims[i]; 4919 B->stencil.starts[i] = mat->stencil.starts[i]; 4920 } 4921 4922 B->nooffproczerorows = mat->nooffproczerorows; 4923 B->nooffprocentries = mat->nooffprocentries; 4924 4925 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm);CHKERRQ(ierr); 4926 if (dm) { 4927 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm);CHKERRQ(ierr); 4928 } 4929 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4930 PetscFunctionReturn(0); 4931 } 4932 4933 /*@ 4934 MatGetDiagonal - Gets the diagonal of a matrix. 4935 4936 Logically Collective on Mat 4937 4938 Input Parameters: 4939 + mat - the matrix 4940 - v - the vector for storing the diagonal 4941 4942 Output Parameter: 4943 . v - the diagonal of the matrix 4944 4945 Level: intermediate 4946 4947 Note: 4948 Currently only correct in parallel for square matrices. 4949 4950 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4951 @*/ 4952 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4953 { 4954 PetscErrorCode ierr; 4955 4956 PetscFunctionBegin; 4957 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4958 PetscValidType(mat,1); 4959 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4960 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4961 PetscCheckFalse(!mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4962 MatCheckPreallocated(mat,1); 4963 4964 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4965 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4966 PetscFunctionReturn(0); 4967 } 4968 4969 /*@C 4970 MatGetRowMin - Gets the minimum value (of the real part) of each 4971 row of the matrix 4972 4973 Logically Collective on Mat 4974 4975 Input Parameter: 4976 . mat - the matrix 4977 4978 Output Parameters: 4979 + v - the vector for storing the maximums 4980 - idx - the indices of the column found for each row (optional) 4981 4982 Level: intermediate 4983 4984 Notes: 4985 The result of this call are the same as if one converted the matrix to dense format 4986 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4987 4988 This code is only implemented for a couple of matrix formats. 4989 4990 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4991 MatGetRowMax() 4992 @*/ 4993 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4994 { 4995 PetscErrorCode ierr; 4996 4997 PetscFunctionBegin; 4998 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4999 PetscValidType(mat,1); 5000 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5001 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5002 5003 if (!mat->cmap->N) { 5004 ierr = VecSet(v,PETSC_MAX_REAL);CHKERRQ(ierr); 5005 if (idx) { 5006 PetscInt i,m = mat->rmap->n; 5007 for (i=0; i<m; i++) idx[i] = -1; 5008 } 5009 } else { 5010 PetscCheckFalse(!mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5011 MatCheckPreallocated(mat,1); 5012 } 5013 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 5014 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 5015 PetscFunctionReturn(0); 5016 } 5017 5018 /*@C 5019 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 5020 row of the matrix 5021 5022 Logically Collective on Mat 5023 5024 Input Parameter: 5025 . mat - the matrix 5026 5027 Output Parameters: 5028 + v - the vector for storing the minimums 5029 - idx - the indices of the column found for each row (or NULL if not needed) 5030 5031 Level: intermediate 5032 5033 Notes: 5034 if a row is completely empty or has only 0.0 values then the idx[] value for that 5035 row is 0 (the first column). 5036 5037 This code is only implemented for a couple of matrix formats. 5038 5039 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 5040 @*/ 5041 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 5042 { 5043 PetscErrorCode ierr; 5044 5045 PetscFunctionBegin; 5046 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5047 PetscValidType(mat,1); 5048 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5049 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5050 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5051 5052 if (!mat->cmap->N) { 5053 ierr = VecSet(v,0.0);CHKERRQ(ierr); 5054 if (idx) { 5055 PetscInt i,m = mat->rmap->n; 5056 for (i=0; i<m; i++) idx[i] = -1; 5057 } 5058 } else { 5059 PetscCheckFalse(!mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5060 MatCheckPreallocated(mat,1); 5061 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 5062 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 5063 } 5064 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 5065 PetscFunctionReturn(0); 5066 } 5067 5068 /*@C 5069 MatGetRowMax - Gets the maximum value (of the real part) of each 5070 row of the matrix 5071 5072 Logically Collective on Mat 5073 5074 Input Parameter: 5075 . mat - the matrix 5076 5077 Output Parameters: 5078 + v - the vector for storing the maximums 5079 - idx - the indices of the column found for each row (optional) 5080 5081 Level: intermediate 5082 5083 Notes: 5084 The result of this call are the same as if one converted the matrix to dense format 5085 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 5086 5087 This code is only implemented for a couple of matrix formats. 5088 5089 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 5090 @*/ 5091 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 5092 { 5093 PetscErrorCode ierr; 5094 5095 PetscFunctionBegin; 5096 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5097 PetscValidType(mat,1); 5098 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5099 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5100 5101 if (!mat->cmap->N) { 5102 ierr = VecSet(v,PETSC_MIN_REAL);CHKERRQ(ierr); 5103 if (idx) { 5104 PetscInt i,m = mat->rmap->n; 5105 for (i=0; i<m; i++) idx[i] = -1; 5106 } 5107 } else { 5108 PetscCheckFalse(!mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5109 MatCheckPreallocated(mat,1); 5110 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 5111 } 5112 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 5113 PetscFunctionReturn(0); 5114 } 5115 5116 /*@C 5117 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5118 row of the matrix 5119 5120 Logically Collective on Mat 5121 5122 Input Parameter: 5123 . mat - the matrix 5124 5125 Output Parameters: 5126 + v - the vector for storing the maximums 5127 - idx - the indices of the column found for each row (or NULL if not needed) 5128 5129 Level: intermediate 5130 5131 Notes: 5132 if a row is completely empty or has only 0.0 values then the idx[] value for that 5133 row is 0 (the first column). 5134 5135 This code is only implemented for a couple of matrix formats. 5136 5137 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 5138 @*/ 5139 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5140 { 5141 PetscErrorCode ierr; 5142 5143 PetscFunctionBegin; 5144 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5145 PetscValidType(mat,1); 5146 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5147 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5148 5149 if (!mat->cmap->N) { 5150 ierr = VecSet(v,0.0);CHKERRQ(ierr); 5151 if (idx) { 5152 PetscInt i,m = mat->rmap->n; 5153 for (i=0; i<m; i++) idx[i] = -1; 5154 } 5155 } else { 5156 PetscCheckFalse(!mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5157 MatCheckPreallocated(mat,1); 5158 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 5159 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 5160 } 5161 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 5162 PetscFunctionReturn(0); 5163 } 5164 5165 /*@ 5166 MatGetRowSum - Gets the sum of each row of the matrix 5167 5168 Logically or Neighborhood Collective on Mat 5169 5170 Input Parameters: 5171 . mat - the matrix 5172 5173 Output Parameter: 5174 . v - the vector for storing the sum of rows 5175 5176 Level: intermediate 5177 5178 Notes: 5179 This code is slow since it is not currently specialized for different formats 5180 5181 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 5182 @*/ 5183 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5184 { 5185 Vec ones; 5186 PetscErrorCode ierr; 5187 5188 PetscFunctionBegin; 5189 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5190 PetscValidType(mat,1); 5191 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5192 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5193 MatCheckPreallocated(mat,1); 5194 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 5195 ierr = VecSet(ones,1.);CHKERRQ(ierr); 5196 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 5197 ierr = VecDestroy(&ones);CHKERRQ(ierr); 5198 PetscFunctionReturn(0); 5199 } 5200 5201 /*@ 5202 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5203 5204 Collective on Mat 5205 5206 Input Parameters: 5207 + mat - the matrix to transpose 5208 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5209 5210 Output Parameter: 5211 . B - the transpose 5212 5213 Notes: 5214 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 5215 5216 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 5217 5218 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5219 5220 Level: intermediate 5221 5222 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 5223 @*/ 5224 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5225 { 5226 PetscErrorCode ierr; 5227 5228 PetscFunctionBegin; 5229 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5230 PetscValidType(mat,1); 5231 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5232 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5233 PetscCheckFalse(!mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5234 PetscCheckFalse(reuse == MAT_INPLACE_MATRIX && mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5235 PetscCheckFalse(reuse == MAT_REUSE_MATRIX && mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5236 MatCheckPreallocated(mat,1); 5237 5238 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 5239 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 5240 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 5241 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 5242 PetscFunctionReturn(0); 5243 } 5244 5245 /*@ 5246 MatIsTranspose - Test whether a matrix is another one's transpose, 5247 or its own, in which case it tests symmetry. 5248 5249 Collective on Mat 5250 5251 Input Parameters: 5252 + A - the matrix to test 5253 - B - the matrix to test against, this can equal the first parameter 5254 5255 Output Parameters: 5256 . flg - the result 5257 5258 Notes: 5259 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5260 has a running time of the order of the number of nonzeros; the parallel 5261 test involves parallel copies of the block-offdiagonal parts of the matrix. 5262 5263 Level: intermediate 5264 5265 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 5266 @*/ 5267 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5268 { 5269 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5270 5271 PetscFunctionBegin; 5272 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5273 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5274 PetscValidBoolPointer(flg,4); 5275 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 5276 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 5277 *flg = PETSC_FALSE; 5278 if (f && g) { 5279 if (f == g) { 5280 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5281 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5282 } else { 5283 MatType mattype; 5284 if (!f) { 5285 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 5286 } else { 5287 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 5288 } 5289 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5290 } 5291 PetscFunctionReturn(0); 5292 } 5293 5294 /*@ 5295 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5296 5297 Collective on Mat 5298 5299 Input Parameters: 5300 + mat - the matrix to transpose and complex conjugate 5301 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5302 5303 Output Parameter: 5304 . B - the Hermitian 5305 5306 Level: intermediate 5307 5308 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 5309 @*/ 5310 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5311 { 5312 PetscErrorCode ierr; 5313 5314 PetscFunctionBegin; 5315 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 5316 #if defined(PETSC_USE_COMPLEX) 5317 ierr = MatConjugate(*B);CHKERRQ(ierr); 5318 #endif 5319 PetscFunctionReturn(0); 5320 } 5321 5322 /*@ 5323 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5324 5325 Collective on Mat 5326 5327 Input Parameters: 5328 + A - the matrix to test 5329 - B - the matrix to test against, this can equal the first parameter 5330 5331 Output Parameters: 5332 . flg - the result 5333 5334 Notes: 5335 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5336 has a running time of the order of the number of nonzeros; the parallel 5337 test involves parallel copies of the block-offdiagonal parts of the matrix. 5338 5339 Level: intermediate 5340 5341 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 5342 @*/ 5343 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5344 { 5345 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5346 5347 PetscFunctionBegin; 5348 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5349 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5350 PetscValidBoolPointer(flg,4); 5351 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 5352 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 5353 if (f && g) { 5354 if (f==g) { 5355 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 5356 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5357 } 5358 PetscFunctionReturn(0); 5359 } 5360 5361 /*@ 5362 MatPermute - Creates a new matrix with rows and columns permuted from the 5363 original. 5364 5365 Collective on Mat 5366 5367 Input Parameters: 5368 + mat - the matrix to permute 5369 . row - row permutation, each processor supplies only the permutation for its rows 5370 - col - column permutation, each processor supplies only the permutation for its columns 5371 5372 Output Parameters: 5373 . B - the permuted matrix 5374 5375 Level: advanced 5376 5377 Note: 5378 The index sets map from row/col of permuted matrix to row/col of original matrix. 5379 The index sets should be on the same communicator as Mat and have the same local sizes. 5380 5381 Developer Note: 5382 If you want to implement MatPermute for a matrix type, and your approach doesn't 5383 exploit the fact that row and col are permutations, consider implementing the 5384 more general MatCreateSubMatrix() instead. 5385 5386 .seealso: MatGetOrdering(), ISAllGather() 5387 5388 @*/ 5389 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5390 { 5391 PetscErrorCode ierr; 5392 5393 PetscFunctionBegin; 5394 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5395 PetscValidType(mat,1); 5396 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5397 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5398 PetscValidPointer(B,4); 5399 PetscCheckSameComm(mat,1,row,2); 5400 if (row != col) PetscCheckSameComm(row,2,col,3); 5401 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5402 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5403 PetscCheckFalse(!mat->ops->permute && !mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5404 MatCheckPreallocated(mat,1); 5405 5406 if (mat->ops->permute) { 5407 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5408 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5409 } else { 5410 ierr = MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B);CHKERRQ(ierr); 5411 } 5412 PetscFunctionReturn(0); 5413 } 5414 5415 /*@ 5416 MatEqual - Compares two matrices. 5417 5418 Collective on Mat 5419 5420 Input Parameters: 5421 + A - the first matrix 5422 - B - the second matrix 5423 5424 Output Parameter: 5425 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5426 5427 Level: intermediate 5428 5429 @*/ 5430 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5431 { 5432 PetscErrorCode ierr; 5433 5434 PetscFunctionBegin; 5435 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5436 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5437 PetscValidType(A,1); 5438 PetscValidType(B,2); 5439 PetscValidBoolPointer(flg,3); 5440 PetscCheckSameComm(A,1,B,2); 5441 MatCheckPreallocated(A,1); 5442 MatCheckPreallocated(B,2); 5443 PetscCheckFalse(!A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5444 PetscCheckFalse(!B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5445 PetscCheckFalse(A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 5446 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5447 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5448 } else { 5449 ierr = MatMultEqual(A,B,10,flg);CHKERRQ(ierr); 5450 } 5451 PetscFunctionReturn(0); 5452 } 5453 5454 /*@ 5455 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5456 matrices that are stored as vectors. Either of the two scaling 5457 matrices can be NULL. 5458 5459 Collective on Mat 5460 5461 Input Parameters: 5462 + mat - the matrix to be scaled 5463 . l - the left scaling vector (or NULL) 5464 - r - the right scaling vector (or NULL) 5465 5466 Notes: 5467 MatDiagonalScale() computes A = LAR, where 5468 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5469 The L scales the rows of the matrix, the R scales the columns of the matrix. 5470 5471 Level: intermediate 5472 5473 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5474 @*/ 5475 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5476 { 5477 PetscErrorCode ierr; 5478 5479 PetscFunctionBegin; 5480 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5481 PetscValidType(mat,1); 5482 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5483 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5484 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5485 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5486 MatCheckPreallocated(mat,1); 5487 if (!l && !r) PetscFunctionReturn(0); 5488 5489 PetscCheckFalse(!mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5490 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5491 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5492 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5493 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5494 if (l != r && mat->symmetric) mat->symmetric = PETSC_FALSE; 5495 PetscFunctionReturn(0); 5496 } 5497 5498 /*@ 5499 MatScale - Scales all elements of a matrix by a given number. 5500 5501 Logically Collective on Mat 5502 5503 Input Parameters: 5504 + mat - the matrix to be scaled 5505 - a - the scaling value 5506 5507 Output Parameter: 5508 . mat - the scaled matrix 5509 5510 Level: intermediate 5511 5512 .seealso: MatDiagonalScale() 5513 @*/ 5514 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5515 { 5516 PetscErrorCode ierr; 5517 5518 PetscFunctionBegin; 5519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5520 PetscValidType(mat,1); 5521 PetscCheckFalse(a != (PetscScalar)1.0 && !mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5522 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5523 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5524 PetscValidLogicalCollectiveScalar(mat,a,2); 5525 MatCheckPreallocated(mat,1); 5526 5527 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5528 if (a != (PetscScalar)1.0) { 5529 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5530 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5531 } 5532 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5533 PetscFunctionReturn(0); 5534 } 5535 5536 /*@ 5537 MatNorm - Calculates various norms of a matrix. 5538 5539 Collective on Mat 5540 5541 Input Parameters: 5542 + mat - the matrix 5543 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5544 5545 Output Parameter: 5546 . nrm - the resulting norm 5547 5548 Level: intermediate 5549 5550 @*/ 5551 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5552 { 5553 PetscErrorCode ierr; 5554 5555 PetscFunctionBegin; 5556 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5557 PetscValidType(mat,1); 5558 PetscValidRealPointer(nrm,3); 5559 5560 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5561 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5562 PetscCheckFalse(!mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5563 MatCheckPreallocated(mat,1); 5564 5565 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5566 PetscFunctionReturn(0); 5567 } 5568 5569 /* 5570 This variable is used to prevent counting of MatAssemblyBegin() that 5571 are called from within a MatAssemblyEnd(). 5572 */ 5573 static PetscInt MatAssemblyEnd_InUse = 0; 5574 /*@ 5575 MatAssemblyBegin - Begins assembling the matrix. This routine should 5576 be called after completing all calls to MatSetValues(). 5577 5578 Collective on Mat 5579 5580 Input Parameters: 5581 + mat - the matrix 5582 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5583 5584 Notes: 5585 MatSetValues() generally caches the values. The matrix is ready to 5586 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5587 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5588 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5589 using the matrix. 5590 5591 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5592 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 5593 a global collective operation requring all processes that share the matrix. 5594 5595 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5596 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5597 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5598 5599 Level: beginner 5600 5601 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5602 @*/ 5603 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5604 { 5605 PetscErrorCode ierr; 5606 5607 PetscFunctionBegin; 5608 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5609 PetscValidType(mat,1); 5610 MatCheckPreallocated(mat,1); 5611 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5612 if (mat->assembled) { 5613 mat->was_assembled = PETSC_TRUE; 5614 mat->assembled = PETSC_FALSE; 5615 } 5616 5617 if (!MatAssemblyEnd_InUse) { 5618 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5619 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5620 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5621 } else if (mat->ops->assemblybegin) { 5622 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5623 } 5624 PetscFunctionReturn(0); 5625 } 5626 5627 /*@ 5628 MatAssembled - Indicates if a matrix has been assembled and is ready for 5629 use; for example, in matrix-vector product. 5630 5631 Not Collective 5632 5633 Input Parameter: 5634 . mat - the matrix 5635 5636 Output Parameter: 5637 . assembled - PETSC_TRUE or PETSC_FALSE 5638 5639 Level: advanced 5640 5641 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5642 @*/ 5643 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5644 { 5645 PetscFunctionBegin; 5646 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5647 PetscValidPointer(assembled,2); 5648 *assembled = mat->assembled; 5649 PetscFunctionReturn(0); 5650 } 5651 5652 /*@ 5653 MatAssemblyEnd - Completes assembling the matrix. This routine should 5654 be called after MatAssemblyBegin(). 5655 5656 Collective on Mat 5657 5658 Input Parameters: 5659 + mat - the matrix 5660 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5661 5662 Options Database Keys: 5663 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5664 . -mat_view ::ascii_info_detail - Prints more detailed info 5665 . -mat_view - Prints matrix in ASCII format 5666 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5667 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5668 . -display <name> - Sets display name (default is host) 5669 . -draw_pause <sec> - Sets number of seconds to pause after display 5670 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5671 . -viewer_socket_machine <machine> - Machine to use for socket 5672 . -viewer_socket_port <port> - Port number to use for socket 5673 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5674 5675 Notes: 5676 MatSetValues() generally caches the values. The matrix is ready to 5677 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5678 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5679 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5680 using the matrix. 5681 5682 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5683 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5684 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5685 5686 Level: beginner 5687 5688 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5689 @*/ 5690 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5691 { 5692 PetscErrorCode ierr; 5693 static PetscInt inassm = 0; 5694 PetscBool flg = PETSC_FALSE; 5695 5696 PetscFunctionBegin; 5697 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5698 PetscValidType(mat,1); 5699 5700 inassm++; 5701 MatAssemblyEnd_InUse++; 5702 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5703 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5704 if (mat->ops->assemblyend) { 5705 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5706 } 5707 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5708 } else if (mat->ops->assemblyend) { 5709 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5710 } 5711 5712 /* Flush assembly is not a true assembly */ 5713 if (type != MAT_FLUSH_ASSEMBLY) { 5714 mat->num_ass++; 5715 mat->assembled = PETSC_TRUE; 5716 mat->ass_nonzerostate = mat->nonzerostate; 5717 } 5718 5719 mat->insertmode = NOT_SET_VALUES; 5720 MatAssemblyEnd_InUse--; 5721 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5722 if (!mat->symmetric_eternal) { 5723 mat->symmetric_set = PETSC_FALSE; 5724 mat->hermitian_set = PETSC_FALSE; 5725 mat->structurally_symmetric_set = PETSC_FALSE; 5726 } 5727 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5728 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5729 5730 if (mat->checksymmetryonassembly) { 5731 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5732 if (flg) { 5733 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5734 } else { 5735 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5736 } 5737 } 5738 if (mat->nullsp && mat->checknullspaceonassembly) { 5739 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5740 } 5741 } 5742 inassm--; 5743 PetscFunctionReturn(0); 5744 } 5745 5746 /*@ 5747 MatSetOption - Sets a parameter option for a matrix. Some options 5748 may be specific to certain storage formats. Some options 5749 determine how values will be inserted (or added). Sorted, 5750 row-oriented input will generally assemble the fastest. The default 5751 is row-oriented. 5752 5753 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5754 5755 Input Parameters: 5756 + mat - the matrix 5757 . option - the option, one of those listed below (and possibly others), 5758 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5759 5760 Options Describing Matrix Structure: 5761 + MAT_SPD - symmetric positive definite 5762 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5763 . MAT_HERMITIAN - transpose is the complex conjugation 5764 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5765 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5766 you set to be kept with all future use of the matrix 5767 including after MatAssemblyBegin/End() which could 5768 potentially change the symmetry structure, i.e. you 5769 KNOW the matrix will ALWAYS have the property you set. 5770 Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian; 5771 the relevant flags must be set independently. 5772 5773 Options For Use with MatSetValues(): 5774 Insert a logically dense subblock, which can be 5775 . MAT_ROW_ORIENTED - row-oriented (default) 5776 5777 Note these options reflect the data you pass in with MatSetValues(); it has 5778 nothing to do with how the data is stored internally in the matrix 5779 data structure. 5780 5781 When (re)assembling a matrix, we can restrict the input for 5782 efficiency/debugging purposes. These options include 5783 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5784 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5785 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5786 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5787 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5788 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5789 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5790 performance for very large process counts. 5791 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5792 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5793 functions, instead sending only neighbor messages. 5794 5795 Notes: 5796 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5797 5798 Some options are relevant only for particular matrix types and 5799 are thus ignored by others. Other options are not supported by 5800 certain matrix types and will generate an error message if set. 5801 5802 If using a Fortran 77 module to compute a matrix, one may need to 5803 use the column-oriented option (or convert to the row-oriented 5804 format). 5805 5806 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5807 that would generate a new entry in the nonzero structure is instead 5808 ignored. Thus, if memory has not alredy been allocated for this particular 5809 data, then the insertion is ignored. For dense matrices, in which 5810 the entire array is allocated, no entries are ever ignored. 5811 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5812 5813 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5814 that would generate a new entry in the nonzero structure instead produces 5815 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 5816 5817 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5818 that would generate a new entry that has not been preallocated will 5819 instead produce an error. (Currently supported for AIJ and BAIJ formats 5820 only.) This is a useful flag when debugging matrix memory preallocation. 5821 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5822 5823 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5824 other processors should be dropped, rather than stashed. 5825 This is useful if you know that the "owning" processor is also 5826 always generating the correct matrix entries, so that PETSc need 5827 not transfer duplicate entries generated on another processor. 5828 5829 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5830 searches during matrix assembly. When this flag is set, the hash table 5831 is created during the first Matrix Assembly. This hash table is 5832 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5833 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5834 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5835 supported by MATMPIBAIJ format only. 5836 5837 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5838 are kept in the nonzero structure 5839 5840 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5841 a zero location in the matrix 5842 5843 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5844 5845 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5846 zero row routines and thus improves performance for very large process counts. 5847 5848 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5849 part of the matrix (since they should match the upper triangular part). 5850 5851 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5852 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5853 with finite difference schemes with non-periodic boundary conditions. 5854 5855 Level: intermediate 5856 5857 .seealso: MatOption, Mat 5858 5859 @*/ 5860 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5861 { 5862 PetscErrorCode ierr; 5863 5864 PetscFunctionBegin; 5865 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5866 if (op > 0) { 5867 PetscValidLogicalCollectiveEnum(mat,op,2); 5868 PetscValidLogicalCollectiveBool(mat,flg,3); 5869 } 5870 5871 PetscCheckFalse(((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5872 5873 switch (op) { 5874 case MAT_FORCE_DIAGONAL_ENTRIES: 5875 mat->force_diagonals = flg; 5876 PetscFunctionReturn(0); 5877 case MAT_NO_OFF_PROC_ENTRIES: 5878 mat->nooffprocentries = flg; 5879 PetscFunctionReturn(0); 5880 case MAT_SUBSET_OFF_PROC_ENTRIES: 5881 mat->assembly_subset = flg; 5882 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5883 #if !defined(PETSC_HAVE_MPIUNI) 5884 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5885 #endif 5886 mat->stash.first_assembly_done = PETSC_FALSE; 5887 } 5888 PetscFunctionReturn(0); 5889 case MAT_NO_OFF_PROC_ZERO_ROWS: 5890 mat->nooffproczerorows = flg; 5891 PetscFunctionReturn(0); 5892 case MAT_SPD: 5893 mat->spd_set = PETSC_TRUE; 5894 mat->spd = flg; 5895 if (flg) { 5896 mat->symmetric = PETSC_TRUE; 5897 mat->structurally_symmetric = PETSC_TRUE; 5898 mat->symmetric_set = PETSC_TRUE; 5899 mat->structurally_symmetric_set = PETSC_TRUE; 5900 } 5901 break; 5902 case MAT_SYMMETRIC: 5903 mat->symmetric = flg; 5904 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5905 mat->symmetric_set = PETSC_TRUE; 5906 mat->structurally_symmetric_set = flg; 5907 #if !defined(PETSC_USE_COMPLEX) 5908 mat->hermitian = flg; 5909 mat->hermitian_set = PETSC_TRUE; 5910 #endif 5911 break; 5912 case MAT_HERMITIAN: 5913 mat->hermitian = flg; 5914 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5915 mat->hermitian_set = PETSC_TRUE; 5916 mat->structurally_symmetric_set = flg; 5917 #if !defined(PETSC_USE_COMPLEX) 5918 mat->symmetric = flg; 5919 mat->symmetric_set = PETSC_TRUE; 5920 #endif 5921 break; 5922 case MAT_STRUCTURALLY_SYMMETRIC: 5923 mat->structurally_symmetric = flg; 5924 mat->structurally_symmetric_set = PETSC_TRUE; 5925 break; 5926 case MAT_SYMMETRY_ETERNAL: 5927 mat->symmetric_eternal = flg; 5928 break; 5929 case MAT_STRUCTURE_ONLY: 5930 mat->structure_only = flg; 5931 break; 5932 case MAT_SORTED_FULL: 5933 mat->sortedfull = flg; 5934 break; 5935 default: 5936 break; 5937 } 5938 if (mat->ops->setoption) { 5939 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5940 } 5941 PetscFunctionReturn(0); 5942 } 5943 5944 /*@ 5945 MatGetOption - Gets a parameter option that has been set for a matrix. 5946 5947 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5948 5949 Input Parameters: 5950 + mat - the matrix 5951 - option - the option, this only responds to certain options, check the code for which ones 5952 5953 Output Parameter: 5954 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5955 5956 Notes: 5957 Can only be called after MatSetSizes() and MatSetType() have been set. 5958 5959 Level: intermediate 5960 5961 .seealso: MatOption, MatSetOption() 5962 5963 @*/ 5964 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5965 { 5966 PetscFunctionBegin; 5967 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5968 PetscValidType(mat,1); 5969 5970 PetscCheckFalse(((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5971 PetscCheckFalse(!((PetscObject)mat)->type_name,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()"); 5972 5973 switch (op) { 5974 case MAT_NO_OFF_PROC_ENTRIES: 5975 *flg = mat->nooffprocentries; 5976 break; 5977 case MAT_NO_OFF_PROC_ZERO_ROWS: 5978 *flg = mat->nooffproczerorows; 5979 break; 5980 case MAT_SYMMETRIC: 5981 *flg = mat->symmetric; 5982 break; 5983 case MAT_HERMITIAN: 5984 *flg = mat->hermitian; 5985 break; 5986 case MAT_STRUCTURALLY_SYMMETRIC: 5987 *flg = mat->structurally_symmetric; 5988 break; 5989 case MAT_SYMMETRY_ETERNAL: 5990 *flg = mat->symmetric_eternal; 5991 break; 5992 case MAT_SPD: 5993 *flg = mat->spd; 5994 break; 5995 default: 5996 break; 5997 } 5998 PetscFunctionReturn(0); 5999 } 6000 6001 /*@ 6002 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 6003 this routine retains the old nonzero structure. 6004 6005 Logically Collective on Mat 6006 6007 Input Parameters: 6008 . mat - the matrix 6009 6010 Level: intermediate 6011 6012 Notes: 6013 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. 6014 See the Performance chapter of the users manual for information on preallocating matrices. 6015 6016 .seealso: MatZeroRows() 6017 @*/ 6018 PetscErrorCode MatZeroEntries(Mat mat) 6019 { 6020 PetscErrorCode ierr; 6021 6022 PetscFunctionBegin; 6023 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6024 PetscValidType(mat,1); 6025 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6026 PetscCheckFalse(mat->insertmode != NOT_SET_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled"); 6027 PetscCheckFalse(!mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6028 MatCheckPreallocated(mat,1); 6029 6030 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 6031 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 6032 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 6033 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6034 PetscFunctionReturn(0); 6035 } 6036 6037 /*@ 6038 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 6039 of a set of rows and columns of a matrix. 6040 6041 Collective on Mat 6042 6043 Input Parameters: 6044 + mat - the matrix 6045 . numRows - the number of rows to remove 6046 . rows - the global row indices 6047 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6048 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6049 - b - optional vector of right hand side, that will be adjusted by provided solution 6050 6051 Notes: 6052 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6053 6054 The user can set a value in the diagonal entry (or for the AIJ and 6055 row formats can optionally remove the main diagonal entry from the 6056 nonzero structure as well, by passing 0.0 as the final argument). 6057 6058 For the parallel case, all processes that share the matrix (i.e., 6059 those in the communicator used for matrix creation) MUST call this 6060 routine, regardless of whether any rows being zeroed are owned by 6061 them. 6062 6063 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6064 list only rows local to itself). 6065 6066 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6067 6068 Level: intermediate 6069 6070 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6071 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6072 @*/ 6073 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6074 { 6075 PetscErrorCode ierr; 6076 6077 PetscFunctionBegin; 6078 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6079 PetscValidType(mat,1); 6080 if (numRows) PetscValidIntPointer(rows,3); 6081 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6082 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6083 PetscCheckFalse(!mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6084 MatCheckPreallocated(mat,1); 6085 6086 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6087 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 6088 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6089 PetscFunctionReturn(0); 6090 } 6091 6092 /*@ 6093 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6094 of a set of rows and columns of a matrix. 6095 6096 Collective on Mat 6097 6098 Input Parameters: 6099 + mat - the matrix 6100 . is - the rows to zero 6101 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6102 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6103 - b - optional vector of right hand side, that will be adjusted by provided solution 6104 6105 Notes: 6106 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 6107 6108 The user can set a value in the diagonal entry (or for the AIJ and 6109 row formats can optionally remove the main diagonal entry from the 6110 nonzero structure as well, by passing 0.0 as the final argument). 6111 6112 For the parallel case, all processes that share the matrix (i.e., 6113 those in the communicator used for matrix creation) MUST call this 6114 routine, regardless of whether any rows being zeroed are owned by 6115 them. 6116 6117 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6118 list only rows local to itself). 6119 6120 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6121 6122 Level: intermediate 6123 6124 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6125 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 6126 @*/ 6127 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6128 { 6129 PetscErrorCode ierr; 6130 PetscInt numRows; 6131 const PetscInt *rows; 6132 6133 PetscFunctionBegin; 6134 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6135 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6136 PetscValidType(mat,1); 6137 PetscValidType(is,2); 6138 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6139 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6140 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6141 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6142 PetscFunctionReturn(0); 6143 } 6144 6145 /*@ 6146 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6147 of a set of rows of a matrix. 6148 6149 Collective on Mat 6150 6151 Input Parameters: 6152 + mat - the matrix 6153 . numRows - the number of rows to remove 6154 . rows - the global row indices 6155 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6156 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6157 - b - optional vector of right hand side, that will be adjusted by provided solution 6158 6159 Notes: 6160 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6161 but does not release memory. For the dense and block diagonal 6162 formats this does not alter the nonzero structure. 6163 6164 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6165 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6166 merely zeroed. 6167 6168 The user can set a value in the diagonal entry (or for the AIJ and 6169 row formats can optionally remove the main diagonal entry from the 6170 nonzero structure as well, by passing 0.0 as the final argument). 6171 6172 For the parallel case, all processes that share the matrix (i.e., 6173 those in the communicator used for matrix creation) MUST call this 6174 routine, regardless of whether any rows being zeroed are owned by 6175 them. 6176 6177 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6178 list only rows local to itself). 6179 6180 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6181 owns that are to be zeroed. This saves a global synchronization in the implementation. 6182 6183 Level: intermediate 6184 6185 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6186 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6187 @*/ 6188 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6189 { 6190 PetscErrorCode ierr; 6191 6192 PetscFunctionBegin; 6193 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6194 PetscValidType(mat,1); 6195 if (numRows) PetscValidIntPointer(rows,3); 6196 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6197 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6198 PetscCheckFalse(!mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6199 MatCheckPreallocated(mat,1); 6200 6201 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6202 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 6203 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6204 PetscFunctionReturn(0); 6205 } 6206 6207 /*@ 6208 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6209 of a set of rows of a matrix. 6210 6211 Collective on Mat 6212 6213 Input Parameters: 6214 + mat - the matrix 6215 . is - index set of rows to remove (if NULL then no row is removed) 6216 . diag - value put in all diagonals of eliminated rows 6217 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6218 - b - optional vector of right hand side, that will be adjusted by provided solution 6219 6220 Notes: 6221 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6222 but does not release memory. For the dense and block diagonal 6223 formats this does not alter the nonzero structure. 6224 6225 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6226 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6227 merely zeroed. 6228 6229 The user can set a value in the diagonal entry (or for the AIJ and 6230 row formats can optionally remove the main diagonal entry from the 6231 nonzero structure as well, by passing 0.0 as the final argument). 6232 6233 For the parallel case, all processes that share the matrix (i.e., 6234 those in the communicator used for matrix creation) MUST call this 6235 routine, regardless of whether any rows being zeroed are owned by 6236 them. 6237 6238 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6239 list only rows local to itself). 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 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6247 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6248 @*/ 6249 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6250 { 6251 PetscInt numRows = 0; 6252 const PetscInt *rows = NULL; 6253 PetscErrorCode ierr; 6254 6255 PetscFunctionBegin; 6256 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6257 PetscValidType(mat,1); 6258 if (is) { 6259 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6260 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6261 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6262 } 6263 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6264 if (is) { 6265 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6266 } 6267 PetscFunctionReturn(0); 6268 } 6269 6270 /*@ 6271 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6272 of a set of rows of a matrix. These rows must be local to the process. 6273 6274 Collective on Mat 6275 6276 Input Parameters: 6277 + mat - the matrix 6278 . numRows - the number of rows to remove 6279 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6280 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6281 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6282 - b - optional vector of right hand side, that will be adjusted by provided solution 6283 6284 Notes: 6285 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6286 but does not release memory. For the dense and block diagonal 6287 formats this does not alter the nonzero structure. 6288 6289 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6290 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6291 merely zeroed. 6292 6293 The user can set a value in the diagonal entry (or for the AIJ and 6294 row formats can optionally remove the main diagonal entry from the 6295 nonzero structure as well, by passing 0.0 as the final argument). 6296 6297 For the parallel case, all processes that share the matrix (i.e., 6298 those in the communicator used for matrix creation) MUST call this 6299 routine, regardless of whether any rows being zeroed are owned by 6300 them. 6301 6302 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6303 list only rows local to itself). 6304 6305 The grid coordinates are across the entire grid, not just the local portion 6306 6307 In Fortran idxm and idxn should be declared as 6308 $ MatStencil idxm(4,m) 6309 and the values inserted using 6310 $ idxm(MatStencil_i,1) = i 6311 $ idxm(MatStencil_j,1) = j 6312 $ idxm(MatStencil_k,1) = k 6313 $ idxm(MatStencil_c,1) = c 6314 etc 6315 6316 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6317 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6318 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6319 DM_BOUNDARY_PERIODIC boundary type. 6320 6321 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 6322 a single value per point) you can skip filling those indices. 6323 6324 Level: intermediate 6325 6326 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6327 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6328 @*/ 6329 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6330 { 6331 PetscInt dim = mat->stencil.dim; 6332 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6333 PetscInt *dims = mat->stencil.dims+1; 6334 PetscInt *starts = mat->stencil.starts; 6335 PetscInt *dxm = (PetscInt*) rows; 6336 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6337 PetscErrorCode ierr; 6338 6339 PetscFunctionBegin; 6340 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6341 PetscValidType(mat,1); 6342 if (numRows) PetscValidPointer(rows,3); 6343 6344 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6345 for (i = 0; i < numRows; ++i) { 6346 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6347 for (j = 0; j < 3-sdim; ++j) dxm++; 6348 /* Local index in X dir */ 6349 tmp = *dxm++ - starts[0]; 6350 /* Loop over remaining dimensions */ 6351 for (j = 0; j < dim-1; ++j) { 6352 /* If nonlocal, set index to be negative */ 6353 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6354 /* Update local index */ 6355 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6356 } 6357 /* Skip component slot if necessary */ 6358 if (mat->stencil.noc) dxm++; 6359 /* Local row number */ 6360 if (tmp >= 0) { 6361 jdxm[numNewRows++] = tmp; 6362 } 6363 } 6364 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6365 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6366 PetscFunctionReturn(0); 6367 } 6368 6369 /*@ 6370 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6371 of a set of rows and columns of a matrix. 6372 6373 Collective on Mat 6374 6375 Input Parameters: 6376 + mat - the matrix 6377 . numRows - the number of rows/columns to remove 6378 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6379 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6380 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6381 - b - optional vector of right hand side, that will be adjusted by provided solution 6382 6383 Notes: 6384 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6385 but does not release memory. For the dense and block diagonal 6386 formats this does not alter the nonzero structure. 6387 6388 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6389 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6390 merely zeroed. 6391 6392 The user can set a value in the diagonal entry (or for the AIJ and 6393 row formats can optionally remove the main diagonal entry from the 6394 nonzero structure as well, by passing 0.0 as the final argument). 6395 6396 For the parallel case, all processes that share the matrix (i.e., 6397 those in the communicator used for matrix creation) MUST call this 6398 routine, regardless of whether any rows being zeroed are owned by 6399 them. 6400 6401 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6402 list only rows local to itself, but the row/column numbers are given in local numbering). 6403 6404 The grid coordinates are across the entire grid, not just the local portion 6405 6406 In Fortran idxm and idxn should be declared as 6407 $ MatStencil idxm(4,m) 6408 and the values inserted using 6409 $ idxm(MatStencil_i,1) = i 6410 $ idxm(MatStencil_j,1) = j 6411 $ idxm(MatStencil_k,1) = k 6412 $ idxm(MatStencil_c,1) = c 6413 etc 6414 6415 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6416 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6417 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6418 DM_BOUNDARY_PERIODIC boundary type. 6419 6420 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 6421 a single value per point) you can skip filling those indices. 6422 6423 Level: intermediate 6424 6425 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6426 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6427 @*/ 6428 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6429 { 6430 PetscInt dim = mat->stencil.dim; 6431 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6432 PetscInt *dims = mat->stencil.dims+1; 6433 PetscInt *starts = mat->stencil.starts; 6434 PetscInt *dxm = (PetscInt*) rows; 6435 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6436 PetscErrorCode ierr; 6437 6438 PetscFunctionBegin; 6439 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6440 PetscValidType(mat,1); 6441 if (numRows) PetscValidPointer(rows,3); 6442 6443 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6444 for (i = 0; i < numRows; ++i) { 6445 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6446 for (j = 0; j < 3-sdim; ++j) dxm++; 6447 /* Local index in X dir */ 6448 tmp = *dxm++ - starts[0]; 6449 /* Loop over remaining dimensions */ 6450 for (j = 0; j < dim-1; ++j) { 6451 /* If nonlocal, set index to be negative */ 6452 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6453 /* Update local index */ 6454 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6455 } 6456 /* Skip component slot if necessary */ 6457 if (mat->stencil.noc) dxm++; 6458 /* Local row number */ 6459 if (tmp >= 0) { 6460 jdxm[numNewRows++] = tmp; 6461 } 6462 } 6463 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6464 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6465 PetscFunctionReturn(0); 6466 } 6467 6468 /*@C 6469 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6470 of a set of rows of a matrix; using local numbering of rows. 6471 6472 Collective on Mat 6473 6474 Input Parameters: 6475 + mat - the matrix 6476 . numRows - the number of rows to remove 6477 . rows - the local row indices 6478 . diag - value put in all diagonals of eliminated rows 6479 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6480 - b - optional vector of right hand side, that will be adjusted by provided solution 6481 6482 Notes: 6483 Before calling MatZeroRowsLocal(), the user must first set the 6484 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6485 6486 For the AIJ matrix formats this removes the old nonzero structure, 6487 but does not release memory. For the dense and block diagonal 6488 formats this does not alter the nonzero structure. 6489 6490 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6491 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6492 merely zeroed. 6493 6494 The user can set a value in the diagonal entry (or for the AIJ and 6495 row formats can optionally remove the main diagonal entry from the 6496 nonzero structure as well, by passing 0.0 as the final argument). 6497 6498 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6499 owns that are to be zeroed. This saves a global synchronization in the implementation. 6500 6501 Level: intermediate 6502 6503 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6504 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6505 @*/ 6506 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6507 { 6508 PetscErrorCode ierr; 6509 6510 PetscFunctionBegin; 6511 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6512 PetscValidType(mat,1); 6513 if (numRows) PetscValidIntPointer(rows,3); 6514 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6515 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6516 MatCheckPreallocated(mat,1); 6517 6518 if (mat->ops->zerorowslocal) { 6519 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6520 } else { 6521 IS is, newis; 6522 const PetscInt *newRows; 6523 6524 PetscCheckFalse(!mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6525 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6526 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6527 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6528 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6529 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6530 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6531 ierr = ISDestroy(&is);CHKERRQ(ierr); 6532 } 6533 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6534 PetscFunctionReturn(0); 6535 } 6536 6537 /*@ 6538 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6539 of a set of rows of a matrix; using local numbering of rows. 6540 6541 Collective on Mat 6542 6543 Input Parameters: 6544 + mat - the matrix 6545 . is - index set of rows to remove 6546 . diag - value put in all diagonals of eliminated rows 6547 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6548 - b - optional vector of right hand side, that will be adjusted by provided solution 6549 6550 Notes: 6551 Before calling MatZeroRowsLocalIS(), the user must first set the 6552 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6553 6554 For the AIJ matrix formats this removes the old nonzero structure, 6555 but does not release memory. For the dense and block diagonal 6556 formats this does not alter the nonzero structure. 6557 6558 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6559 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6560 merely zeroed. 6561 6562 The user can set a value in the diagonal entry (or for the AIJ and 6563 row formats can optionally remove the main diagonal entry from the 6564 nonzero structure as well, by passing 0.0 as the final argument). 6565 6566 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6567 owns that are to be zeroed. This saves a global synchronization in the implementation. 6568 6569 Level: intermediate 6570 6571 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6572 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6573 @*/ 6574 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6575 { 6576 PetscErrorCode ierr; 6577 PetscInt numRows; 6578 const PetscInt *rows; 6579 6580 PetscFunctionBegin; 6581 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6582 PetscValidType(mat,1); 6583 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6584 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6585 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6586 MatCheckPreallocated(mat,1); 6587 6588 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6589 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6590 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6591 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6592 PetscFunctionReturn(0); 6593 } 6594 6595 /*@ 6596 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6597 of a set of rows and columns of a matrix; using local numbering of rows. 6598 6599 Collective on Mat 6600 6601 Input Parameters: 6602 + mat - the matrix 6603 . numRows - the number of rows to remove 6604 . rows - the global row indices 6605 . diag - value put in all diagonals of eliminated rows 6606 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6607 - b - optional vector of right hand side, that will be adjusted by provided solution 6608 6609 Notes: 6610 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6611 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6612 6613 The user can set a value in the diagonal entry (or for the AIJ and 6614 row formats can optionally remove the main diagonal entry from the 6615 nonzero structure as well, by passing 0.0 as the final argument). 6616 6617 Level: intermediate 6618 6619 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6620 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6621 @*/ 6622 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6623 { 6624 PetscErrorCode ierr; 6625 IS is, newis; 6626 const PetscInt *newRows; 6627 6628 PetscFunctionBegin; 6629 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6630 PetscValidType(mat,1); 6631 if (numRows) PetscValidIntPointer(rows,3); 6632 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6633 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6634 MatCheckPreallocated(mat,1); 6635 6636 PetscCheckFalse(!mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6637 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6638 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6639 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6640 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6641 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6642 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6643 ierr = ISDestroy(&is);CHKERRQ(ierr); 6644 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6645 PetscFunctionReturn(0); 6646 } 6647 6648 /*@ 6649 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6650 of a set of rows and columns of a matrix; using local numbering of rows. 6651 6652 Collective on Mat 6653 6654 Input Parameters: 6655 + mat - the matrix 6656 . is - index set of rows to remove 6657 . diag - value put in all diagonals of eliminated rows 6658 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6659 - b - optional vector of right hand side, that will be adjusted by provided solution 6660 6661 Notes: 6662 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6663 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6664 6665 The user can set a value in the diagonal entry (or for the AIJ and 6666 row formats can optionally remove the main diagonal entry from the 6667 nonzero structure as well, by passing 0.0 as the final argument). 6668 6669 Level: intermediate 6670 6671 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6672 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6673 @*/ 6674 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6675 { 6676 PetscErrorCode ierr; 6677 PetscInt numRows; 6678 const PetscInt *rows; 6679 6680 PetscFunctionBegin; 6681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6682 PetscValidType(mat,1); 6683 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6684 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6685 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6686 MatCheckPreallocated(mat,1); 6687 6688 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6689 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6690 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6691 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6692 PetscFunctionReturn(0); 6693 } 6694 6695 /*@C 6696 MatGetSize - Returns the numbers of rows and columns in a matrix. 6697 6698 Not Collective 6699 6700 Input Parameter: 6701 . mat - the matrix 6702 6703 Output Parameters: 6704 + m - the number of global rows 6705 - n - the number of global columns 6706 6707 Note: both output parameters can be NULL on input. 6708 6709 Level: beginner 6710 6711 .seealso: MatGetLocalSize() 6712 @*/ 6713 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6714 { 6715 PetscFunctionBegin; 6716 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6717 if (m) *m = mat->rmap->N; 6718 if (n) *n = mat->cmap->N; 6719 PetscFunctionReturn(0); 6720 } 6721 6722 /*@C 6723 MatGetLocalSize - Returns the number of local rows and local columns 6724 of a matrix, that is the local size of the left and right vectors as returned by MatCreateVecs(). 6725 6726 Not Collective 6727 6728 Input Parameter: 6729 . mat - the matrix 6730 6731 Output Parameters: 6732 + m - the number of local rows 6733 - n - the number of local columns 6734 6735 Note: both output parameters can be NULL on input. 6736 6737 Level: beginner 6738 6739 .seealso: MatGetSize() 6740 @*/ 6741 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6742 { 6743 PetscFunctionBegin; 6744 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6745 if (m) PetscValidIntPointer(m,2); 6746 if (n) PetscValidIntPointer(n,3); 6747 if (m) *m = mat->rmap->n; 6748 if (n) *n = mat->cmap->n; 6749 PetscFunctionReturn(0); 6750 } 6751 6752 /*@C 6753 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6754 this processor. (The columns of the "diagonal block") 6755 6756 Not Collective, unless matrix has not been allocated, then collective on Mat 6757 6758 Input Parameter: 6759 . mat - the matrix 6760 6761 Output Parameters: 6762 + m - the global index of the first local column 6763 - n - one more than the global index of the last local column 6764 6765 Notes: 6766 both output parameters can be NULL on input. 6767 6768 Level: developer 6769 6770 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6771 6772 @*/ 6773 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6774 { 6775 PetscFunctionBegin; 6776 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6777 PetscValidType(mat,1); 6778 if (m) PetscValidIntPointer(m,2); 6779 if (n) PetscValidIntPointer(n,3); 6780 MatCheckPreallocated(mat,1); 6781 if (m) *m = mat->cmap->rstart; 6782 if (n) *n = mat->cmap->rend; 6783 PetscFunctionReturn(0); 6784 } 6785 6786 /*@C 6787 MatGetOwnershipRange - Returns the range of matrix rows owned by 6788 this processor, assuming that the matrix is laid out with the first 6789 n1 rows on the first processor, the next n2 rows on the second, etc. 6790 For certain parallel layouts this range may not be well defined. 6791 6792 Not Collective 6793 6794 Input Parameter: 6795 . mat - the matrix 6796 6797 Output Parameters: 6798 + m - the global index of the first local row 6799 - n - one more than the global index of the last local row 6800 6801 Note: Both output parameters can be NULL on input. 6802 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6803 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6804 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6805 6806 Level: beginner 6807 6808 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6809 6810 @*/ 6811 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6812 { 6813 PetscFunctionBegin; 6814 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6815 PetscValidType(mat,1); 6816 if (m) PetscValidIntPointer(m,2); 6817 if (n) PetscValidIntPointer(n,3); 6818 MatCheckPreallocated(mat,1); 6819 if (m) *m = mat->rmap->rstart; 6820 if (n) *n = mat->rmap->rend; 6821 PetscFunctionReturn(0); 6822 } 6823 6824 /*@C 6825 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6826 each process 6827 6828 Not Collective, unless matrix has not been allocated, then collective on Mat 6829 6830 Input Parameters: 6831 . mat - the matrix 6832 6833 Output Parameters: 6834 . ranges - start of each processors portion plus one more than the total length at the end 6835 6836 Level: beginner 6837 6838 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6839 6840 @*/ 6841 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6842 { 6843 PetscErrorCode ierr; 6844 6845 PetscFunctionBegin; 6846 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6847 PetscValidType(mat,1); 6848 MatCheckPreallocated(mat,1); 6849 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6850 PetscFunctionReturn(0); 6851 } 6852 6853 /*@C 6854 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6855 this processor. (The columns of the "diagonal blocks" for each process) 6856 6857 Not Collective, unless matrix has not been allocated, then collective on Mat 6858 6859 Input Parameters: 6860 . mat - the matrix 6861 6862 Output Parameters: 6863 . ranges - start of each processors portion plus one more then the total length at the end 6864 6865 Level: beginner 6866 6867 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6868 6869 @*/ 6870 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6871 { 6872 PetscErrorCode ierr; 6873 6874 PetscFunctionBegin; 6875 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6876 PetscValidType(mat,1); 6877 MatCheckPreallocated(mat,1); 6878 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6879 PetscFunctionReturn(0); 6880 } 6881 6882 /*@C 6883 MatGetOwnershipIS - Get row and column ownership as index sets 6884 6885 Not Collective 6886 6887 Input Parameter: 6888 . A - matrix 6889 6890 Output Parameters: 6891 + rows - rows in which this process owns elements 6892 - cols - columns in which this process owns elements 6893 6894 Level: intermediate 6895 6896 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MATSCALAPACK 6897 @*/ 6898 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6899 { 6900 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6901 6902 PetscFunctionBegin; 6903 MatCheckPreallocated(A,1); 6904 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6905 if (f) { 6906 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6907 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6908 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6909 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6910 } 6911 PetscFunctionReturn(0); 6912 } 6913 6914 /*@C 6915 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6916 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6917 to complete the factorization. 6918 6919 Collective on Mat 6920 6921 Input Parameters: 6922 + mat - the matrix 6923 . row - row permutation 6924 . column - column permutation 6925 - info - structure containing 6926 $ levels - number of levels of fill. 6927 $ expected fill - as ratio of original fill. 6928 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6929 missing diagonal entries) 6930 6931 Output Parameters: 6932 . fact - new matrix that has been symbolically factored 6933 6934 Notes: 6935 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6936 6937 Most users should employ the simplified KSP interface for linear solvers 6938 instead of working directly with matrix algebra routines such as this. 6939 See, e.g., KSPCreate(). 6940 6941 Level: developer 6942 6943 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6944 MatGetOrdering(), MatFactorInfo 6945 6946 Note: this uses the definition of level of fill as in Y. Saad, 2003 6947 6948 Developer Note: fortran interface is not autogenerated as the f90 6949 interface definition cannot be generated correctly [due to MatFactorInfo] 6950 6951 References: 6952 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6953 @*/ 6954 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6955 { 6956 PetscErrorCode ierr; 6957 6958 PetscFunctionBegin; 6959 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6960 PetscValidType(mat,2); 6961 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6962 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6963 PetscValidPointer(info,5); 6964 PetscValidPointer(fact,1); 6965 PetscCheckFalse(info->levels < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6966 PetscCheckFalse(info->fill < 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6967 if (!fact->ops->ilufactorsymbolic) { 6968 MatSolverType stype; 6969 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr); 6970 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6971 } 6972 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6973 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6974 MatCheckPreallocated(mat,2); 6975 6976 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);} 6977 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6978 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr);} 6979 PetscFunctionReturn(0); 6980 } 6981 6982 /*@C 6983 MatICCFactorSymbolic - Performs symbolic incomplete 6984 Cholesky factorization for a symmetric matrix. Use 6985 MatCholeskyFactorNumeric() to complete the factorization. 6986 6987 Collective on Mat 6988 6989 Input Parameters: 6990 + mat - the matrix 6991 . perm - row and column permutation 6992 - info - structure containing 6993 $ levels - number of levels of fill. 6994 $ expected fill - as ratio of original fill. 6995 6996 Output Parameter: 6997 . fact - the factored matrix 6998 6999 Notes: 7000 Most users should employ the KSP interface for linear solvers 7001 instead of working directly with matrix algebra routines such as this. 7002 See, e.g., KSPCreate(). 7003 7004 Level: developer 7005 7006 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 7007 7008 Note: this uses the definition of level of fill as in Y. Saad, 2003 7009 7010 Developer Note: fortran interface is not autogenerated as the f90 7011 interface definition cannot be generated correctly [due to MatFactorInfo] 7012 7013 References: 7014 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 7015 @*/ 7016 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 7017 { 7018 PetscErrorCode ierr; 7019 7020 PetscFunctionBegin; 7021 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 7022 PetscValidType(mat,2); 7023 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 7024 PetscValidPointer(info,4); 7025 PetscValidPointer(fact,1); 7026 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7027 PetscCheckFalse(info->levels < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 7028 PetscCheckFalse(info->fill < 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 7029 if (!(fact)->ops->iccfactorsymbolic) { 7030 MatSolverType stype; 7031 ierr = MatFactorGetSolverType(fact,&stype);CHKERRQ(ierr); 7032 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 7033 } 7034 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7035 MatCheckPreallocated(mat,2); 7036 7037 if (!fact->trivialsymbolic) {ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);} 7038 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 7039 if (!fact->trivialsymbolic) {ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr);} 7040 PetscFunctionReturn(0); 7041 } 7042 7043 /*@C 7044 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 7045 points to an array of valid matrices, they may be reused to store the new 7046 submatrices. 7047 7048 Collective on Mat 7049 7050 Input Parameters: 7051 + mat - the matrix 7052 . n - the number of submatrixes to be extracted (on this processor, may be zero) 7053 . irow, icol - index sets of rows and columns to extract 7054 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7055 7056 Output Parameter: 7057 . submat - the array of submatrices 7058 7059 Notes: 7060 MatCreateSubMatrices() can extract ONLY sequential submatrices 7061 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 7062 to extract a parallel submatrix. 7063 7064 Some matrix types place restrictions on the row and column 7065 indices, such as that they be sorted or that they be equal to each other. 7066 7067 The index sets may not have duplicate entries. 7068 7069 When extracting submatrices from a parallel matrix, each processor can 7070 form a different submatrix by setting the rows and columns of its 7071 individual index sets according to the local submatrix desired. 7072 7073 When finished using the submatrices, the user should destroy 7074 them with MatDestroySubMatrices(). 7075 7076 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 7077 original matrix has not changed from that last call to MatCreateSubMatrices(). 7078 7079 This routine creates the matrices in submat; you should NOT create them before 7080 calling it. It also allocates the array of matrix pointers submat. 7081 7082 For BAIJ matrices the index sets must respect the block structure, that is if they 7083 request one row/column in a block, they must request all rows/columns that are in 7084 that block. For example, if the block size is 2 you cannot request just row 0 and 7085 column 0. 7086 7087 Fortran Note: 7088 The Fortran interface is slightly different from that given below; it 7089 requires one to pass in as submat a Mat (integer) array of size at least n+1. 7090 7091 Level: advanced 7092 7093 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 7094 @*/ 7095 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7096 { 7097 PetscErrorCode ierr; 7098 PetscInt i; 7099 PetscBool eq; 7100 7101 PetscFunctionBegin; 7102 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7103 PetscValidType(mat,1); 7104 if (n) { 7105 PetscValidPointer(irow,3); 7106 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7107 PetscValidPointer(icol,4); 7108 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7109 } 7110 PetscValidPointer(submat,6); 7111 if (n && scall == MAT_REUSE_MATRIX) { 7112 PetscValidPointer(*submat,6); 7113 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7114 } 7115 PetscCheckFalse(!mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7116 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7117 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7118 MatCheckPreallocated(mat,1); 7119 7120 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 7121 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 7122 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 7123 for (i=0; i<n; i++) { 7124 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 7125 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr); 7126 if (eq) { 7127 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr); 7128 } 7129 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 7130 if (mat->boundtocpu && mat->bindingpropagates) { 7131 ierr = MatBindToCPU((*submat)[i],PETSC_TRUE);CHKERRQ(ierr); 7132 ierr = MatSetBindingPropagates((*submat)[i],PETSC_TRUE);CHKERRQ(ierr); 7133 } 7134 #endif 7135 } 7136 PetscFunctionReturn(0); 7137 } 7138 7139 /*@C 7140 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7141 7142 Collective on Mat 7143 7144 Input Parameters: 7145 + mat - the matrix 7146 . n - the number of submatrixes to be extracted 7147 . irow, icol - index sets of rows and columns to extract 7148 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7149 7150 Output Parameter: 7151 . submat - the array of submatrices 7152 7153 Level: advanced 7154 7155 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 7156 @*/ 7157 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7158 { 7159 PetscErrorCode ierr; 7160 PetscInt i; 7161 PetscBool eq; 7162 7163 PetscFunctionBegin; 7164 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7165 PetscValidType(mat,1); 7166 if (n) { 7167 PetscValidPointer(irow,3); 7168 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7169 PetscValidPointer(icol,4); 7170 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7171 } 7172 PetscValidPointer(submat,6); 7173 if (n && scall == MAT_REUSE_MATRIX) { 7174 PetscValidPointer(*submat,6); 7175 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7176 } 7177 PetscCheckFalse(!mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7178 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7179 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7180 MatCheckPreallocated(mat,1); 7181 7182 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 7183 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 7184 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 7185 for (i=0; i<n; i++) { 7186 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr); 7187 if (eq) { 7188 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr); 7189 } 7190 } 7191 PetscFunctionReturn(0); 7192 } 7193 7194 /*@C 7195 MatDestroyMatrices - Destroys an array of matrices. 7196 7197 Collective on Mat 7198 7199 Input Parameters: 7200 + n - the number of local matrices 7201 - mat - the matrices (note that this is a pointer to the array of matrices) 7202 7203 Level: advanced 7204 7205 Notes: 7206 Frees not only the matrices, but also the array that contains the matrices 7207 In Fortran will not free the array. 7208 7209 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 7210 @*/ 7211 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7212 { 7213 PetscErrorCode ierr; 7214 PetscInt i; 7215 7216 PetscFunctionBegin; 7217 if (!*mat) PetscFunctionReturn(0); 7218 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7219 PetscValidPointer(mat,2); 7220 7221 for (i=0; i<n; i++) { 7222 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 7223 } 7224 7225 /* memory is allocated even if n = 0 */ 7226 ierr = PetscFree(*mat);CHKERRQ(ierr); 7227 PetscFunctionReturn(0); 7228 } 7229 7230 /*@C 7231 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7232 7233 Collective on Mat 7234 7235 Input Parameters: 7236 + n - the number of local matrices 7237 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7238 sequence of MatCreateSubMatrices()) 7239 7240 Level: advanced 7241 7242 Notes: 7243 Frees not only the matrices, but also the array that contains the matrices 7244 In Fortran will not free the array. 7245 7246 .seealso: MatCreateSubMatrices() 7247 @*/ 7248 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7249 { 7250 PetscErrorCode ierr; 7251 Mat mat0; 7252 7253 PetscFunctionBegin; 7254 if (!*mat) PetscFunctionReturn(0); 7255 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7256 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7257 PetscValidPointer(mat,2); 7258 7259 mat0 = (*mat)[0]; 7260 if (mat0 && mat0->ops->destroysubmatrices) { 7261 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 7262 } else { 7263 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 7264 } 7265 PetscFunctionReturn(0); 7266 } 7267 7268 /*@C 7269 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 7270 7271 Collective on Mat 7272 7273 Input Parameters: 7274 . mat - the matrix 7275 7276 Output Parameter: 7277 . matstruct - the sequential matrix with the nonzero structure of mat 7278 7279 Level: intermediate 7280 7281 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 7282 @*/ 7283 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7284 { 7285 PetscErrorCode ierr; 7286 7287 PetscFunctionBegin; 7288 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7289 PetscValidPointer(matstruct,2); 7290 7291 PetscValidType(mat,1); 7292 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7293 MatCheckPreallocated(mat,1); 7294 7295 PetscCheckFalse(!mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7296 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7297 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 7298 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 7299 PetscFunctionReturn(0); 7300 } 7301 7302 /*@C 7303 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7304 7305 Collective on Mat 7306 7307 Input Parameters: 7308 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7309 sequence of MatGetSequentialNonzeroStructure()) 7310 7311 Level: advanced 7312 7313 Notes: 7314 Frees not only the matrices, but also the array that contains the matrices 7315 7316 .seealso: MatGetSeqNonzeroStructure() 7317 @*/ 7318 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7319 { 7320 PetscErrorCode ierr; 7321 7322 PetscFunctionBegin; 7323 PetscValidPointer(mat,1); 7324 ierr = MatDestroy(mat);CHKERRQ(ierr); 7325 PetscFunctionReturn(0); 7326 } 7327 7328 /*@ 7329 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7330 replaces the index sets by larger ones that represent submatrices with 7331 additional overlap. 7332 7333 Collective on Mat 7334 7335 Input Parameters: 7336 + mat - the matrix 7337 . n - the number of index sets 7338 . is - the array of index sets (these index sets will changed during the call) 7339 - ov - the additional overlap requested 7340 7341 Options Database: 7342 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7343 7344 Level: developer 7345 7346 Developer Note: 7347 Any implementation must preserve block sizes. That is: if the row block size and the column block size of mat are equal to bs, then the output index sets must be compatible with bs. 7348 7349 .seealso: MatCreateSubMatrices() 7350 @*/ 7351 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7352 { 7353 PetscErrorCode ierr; 7354 PetscInt i,bs,cbs; 7355 7356 PetscFunctionBegin; 7357 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7358 PetscValidType(mat,1); 7359 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7360 if (n) { 7361 PetscValidPointer(is,3); 7362 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7363 PetscValidLogicalCollectiveInt(*is,n,2); 7364 } 7365 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7366 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7367 MatCheckPreallocated(mat,1); 7368 7369 if (!ov) PetscFunctionReturn(0); 7370 PetscCheckFalse(!mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7371 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7372 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7373 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7374 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 7375 if (bs == cbs) { 7376 for (i=0; i<n; i++) { 7377 ierr = ISSetBlockSize(is[i],bs);CHKERRQ(ierr); 7378 } 7379 } 7380 PetscFunctionReturn(0); 7381 } 7382 7383 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7384 7385 /*@ 7386 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7387 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7388 additional overlap. 7389 7390 Collective on Mat 7391 7392 Input Parameters: 7393 + mat - the matrix 7394 . n - the number of index sets 7395 . is - the array of index sets (these index sets will changed during the call) 7396 - ov - the additional overlap requested 7397 7398 Options Database: 7399 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7400 7401 Level: developer 7402 7403 .seealso: MatCreateSubMatrices() 7404 @*/ 7405 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7406 { 7407 PetscInt i; 7408 PetscErrorCode ierr; 7409 7410 PetscFunctionBegin; 7411 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7412 PetscValidType(mat,1); 7413 PetscCheckFalse(n < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7414 if (n) { 7415 PetscValidPointer(is,3); 7416 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7417 } 7418 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7419 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7420 MatCheckPreallocated(mat,1); 7421 if (!ov) PetscFunctionReturn(0); 7422 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7423 for (i=0; i<n; i++) { 7424 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7425 } 7426 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7427 PetscFunctionReturn(0); 7428 } 7429 7430 /*@ 7431 MatGetBlockSize - Returns the matrix block size. 7432 7433 Not Collective 7434 7435 Input Parameter: 7436 . mat - the matrix 7437 7438 Output Parameter: 7439 . bs - block size 7440 7441 Notes: 7442 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7443 7444 If the block size has not been set yet this routine returns 1. 7445 7446 Level: intermediate 7447 7448 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7449 @*/ 7450 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7451 { 7452 PetscFunctionBegin; 7453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7454 PetscValidIntPointer(bs,2); 7455 *bs = PetscAbs(mat->rmap->bs); 7456 PetscFunctionReturn(0); 7457 } 7458 7459 /*@ 7460 MatGetBlockSizes - Returns the matrix block row and column sizes. 7461 7462 Not Collective 7463 7464 Input Parameter: 7465 . mat - the matrix 7466 7467 Output Parameters: 7468 + rbs - row block size 7469 - cbs - column block size 7470 7471 Notes: 7472 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7473 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7474 7475 If a block size has not been set yet this routine returns 1. 7476 7477 Level: intermediate 7478 7479 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7480 @*/ 7481 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7482 { 7483 PetscFunctionBegin; 7484 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7485 if (rbs) PetscValidIntPointer(rbs,2); 7486 if (cbs) PetscValidIntPointer(cbs,3); 7487 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7488 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7489 PetscFunctionReturn(0); 7490 } 7491 7492 /*@ 7493 MatSetBlockSize - Sets the matrix block size. 7494 7495 Logically Collective on Mat 7496 7497 Input Parameters: 7498 + mat - the matrix 7499 - bs - block size 7500 7501 Notes: 7502 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7503 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7504 7505 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7506 is compatible with the matrix local sizes. 7507 7508 Level: intermediate 7509 7510 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7511 @*/ 7512 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7513 { 7514 PetscErrorCode ierr; 7515 7516 PetscFunctionBegin; 7517 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7518 PetscValidLogicalCollectiveInt(mat,bs,2); 7519 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7520 PetscFunctionReturn(0); 7521 } 7522 7523 /*@ 7524 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7525 7526 Logically Collective on Mat 7527 7528 Input Parameters: 7529 + mat - the matrix 7530 . nblocks - the number of blocks on this process 7531 - bsizes - the block sizes 7532 7533 Notes: 7534 Currently used by PCVPBJACOBI for AIJ matrices 7535 7536 Each variable point-block set of degrees of freedom must live on a single MPI rank. That is a point block cannot straddle two MPI ranks. 7537 7538 Level: intermediate 7539 7540 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes(), PCVPBJACOBI 7541 @*/ 7542 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7543 { 7544 PetscErrorCode ierr; 7545 PetscInt i,ncnt = 0, nlocal; 7546 7547 PetscFunctionBegin; 7548 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7549 PetscCheckFalse(nblocks < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7550 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7551 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7552 PetscCheckFalse(ncnt != nlocal,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %" PetscInt_FMT " does not equal local size of matrix %" PetscInt_FMT,ncnt,nlocal); 7553 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7554 mat->nblocks = nblocks; 7555 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7556 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7557 PetscFunctionReturn(0); 7558 } 7559 7560 /*@C 7561 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7562 7563 Logically Collective on Mat 7564 7565 Input Parameter: 7566 . mat - the matrix 7567 7568 Output Parameters: 7569 + nblocks - the number of blocks on this process 7570 - bsizes - the block sizes 7571 7572 Notes: Currently not supported from Fortran 7573 7574 Level: intermediate 7575 7576 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7577 @*/ 7578 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7579 { 7580 PetscFunctionBegin; 7581 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7582 *nblocks = mat->nblocks; 7583 *bsizes = mat->bsizes; 7584 PetscFunctionReturn(0); 7585 } 7586 7587 /*@ 7588 MatSetBlockSizes - Sets the matrix block row and column sizes. 7589 7590 Logically Collective on Mat 7591 7592 Input Parameters: 7593 + mat - the matrix 7594 . rbs - row block size 7595 - cbs - column block size 7596 7597 Notes: 7598 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7599 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7600 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7601 7602 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7603 are compatible with the matrix local sizes. 7604 7605 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7606 7607 Level: intermediate 7608 7609 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7610 @*/ 7611 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7612 { 7613 PetscErrorCode ierr; 7614 7615 PetscFunctionBegin; 7616 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7617 PetscValidLogicalCollectiveInt(mat,rbs,2); 7618 PetscValidLogicalCollectiveInt(mat,cbs,3); 7619 if (mat->ops->setblocksizes) { 7620 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7621 } 7622 if (mat->rmap->refcnt) { 7623 ISLocalToGlobalMapping l2g = NULL; 7624 PetscLayout nmap = NULL; 7625 7626 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7627 if (mat->rmap->mapping) { 7628 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7629 } 7630 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7631 mat->rmap = nmap; 7632 mat->rmap->mapping = l2g; 7633 } 7634 if (mat->cmap->refcnt) { 7635 ISLocalToGlobalMapping l2g = NULL; 7636 PetscLayout nmap = NULL; 7637 7638 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7639 if (mat->cmap->mapping) { 7640 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7641 } 7642 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7643 mat->cmap = nmap; 7644 mat->cmap->mapping = l2g; 7645 } 7646 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7647 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7648 PetscFunctionReturn(0); 7649 } 7650 7651 /*@ 7652 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7653 7654 Logically Collective on Mat 7655 7656 Input Parameters: 7657 + mat - the matrix 7658 . fromRow - matrix from which to copy row block size 7659 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7660 7661 Level: developer 7662 7663 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7664 @*/ 7665 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7666 { 7667 PetscErrorCode ierr; 7668 7669 PetscFunctionBegin; 7670 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7671 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7672 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7673 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7674 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7675 PetscFunctionReturn(0); 7676 } 7677 7678 /*@ 7679 MatResidual - Default routine to calculate the residual. 7680 7681 Collective on Mat 7682 7683 Input Parameters: 7684 + mat - the matrix 7685 . b - the right-hand-side 7686 - x - the approximate solution 7687 7688 Output Parameter: 7689 . r - location to store the residual 7690 7691 Level: developer 7692 7693 .seealso: PCMGSetResidual() 7694 @*/ 7695 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7696 { 7697 PetscErrorCode ierr; 7698 7699 PetscFunctionBegin; 7700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7701 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7702 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7703 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7704 PetscValidType(mat,1); 7705 MatCheckPreallocated(mat,1); 7706 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7707 if (!mat->ops->residual) { 7708 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7709 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7710 } else { 7711 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7712 } 7713 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7714 PetscFunctionReturn(0); 7715 } 7716 7717 /*@C 7718 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7719 7720 Collective on Mat 7721 7722 Input Parameters: 7723 + mat - the matrix 7724 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7725 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7726 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7727 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7728 always used. 7729 7730 Output Parameters: 7731 + n - number of rows in the (possibly compressed) matrix 7732 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7733 . ja - the column indices 7734 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7735 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7736 7737 Level: developer 7738 7739 Notes: 7740 You CANNOT change any of the ia[] or ja[] values. 7741 7742 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7743 7744 Fortran Notes: 7745 In Fortran use 7746 $ 7747 $ PetscInt ia(1), ja(1) 7748 $ PetscOffset iia, jja 7749 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7750 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7751 7752 or 7753 $ 7754 $ PetscInt, pointer :: ia(:),ja(:) 7755 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7756 $ ! Access the ith and jth entries via ia(i) and ja(j) 7757 7758 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7759 @*/ 7760 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7761 { 7762 PetscErrorCode ierr; 7763 7764 PetscFunctionBegin; 7765 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7766 PetscValidType(mat,1); 7767 PetscValidIntPointer(n,5); 7768 if (ia) PetscValidIntPointer(ia,6); 7769 if (ja) PetscValidIntPointer(ja,7); 7770 PetscValidBoolPointer(done,8); 7771 MatCheckPreallocated(mat,1); 7772 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7773 else { 7774 *done = PETSC_TRUE; 7775 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7776 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7777 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7778 } 7779 PetscFunctionReturn(0); 7780 } 7781 7782 /*@C 7783 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7784 7785 Collective on Mat 7786 7787 Input Parameters: 7788 + mat - the matrix 7789 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7790 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7791 symmetrized 7792 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7793 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7794 always used. 7795 . n - number of columns in the (possibly compressed) matrix 7796 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7797 - ja - the row indices 7798 7799 Output Parameters: 7800 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7801 7802 Level: developer 7803 7804 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7805 @*/ 7806 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7807 { 7808 PetscErrorCode ierr; 7809 7810 PetscFunctionBegin; 7811 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7812 PetscValidType(mat,1); 7813 PetscValidIntPointer(n,5); 7814 if (ia) PetscValidIntPointer(ia,6); 7815 if (ja) PetscValidIntPointer(ja,7); 7816 PetscValidBoolPointer(done,8); 7817 MatCheckPreallocated(mat,1); 7818 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7819 else { 7820 *done = PETSC_TRUE; 7821 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7822 } 7823 PetscFunctionReturn(0); 7824 } 7825 7826 /*@C 7827 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7828 MatGetRowIJ(). 7829 7830 Collective on Mat 7831 7832 Input Parameters: 7833 + mat - the matrix 7834 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7835 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7836 symmetrized 7837 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7838 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7839 always used. 7840 . n - size of (possibly compressed) matrix 7841 . ia - the row pointers 7842 - ja - the column indices 7843 7844 Output Parameters: 7845 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7846 7847 Note: 7848 This routine zeros out n, ia, and ja. This is to prevent accidental 7849 us of the array after it has been restored. If you pass NULL, it will 7850 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7851 7852 Level: developer 7853 7854 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7855 @*/ 7856 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7857 { 7858 PetscErrorCode ierr; 7859 7860 PetscFunctionBegin; 7861 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7862 PetscValidType(mat,1); 7863 if (ia) PetscValidIntPointer(ia,6); 7864 if (ja) PetscValidIntPointer(ja,7); 7865 PetscValidBoolPointer(done,8); 7866 MatCheckPreallocated(mat,1); 7867 7868 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7869 else { 7870 *done = PETSC_TRUE; 7871 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7872 if (n) *n = 0; 7873 if (ia) *ia = NULL; 7874 if (ja) *ja = NULL; 7875 } 7876 PetscFunctionReturn(0); 7877 } 7878 7879 /*@C 7880 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7881 MatGetColumnIJ(). 7882 7883 Collective on Mat 7884 7885 Input Parameters: 7886 + mat - the matrix 7887 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7888 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7889 symmetrized 7890 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7891 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7892 always used. 7893 7894 Output Parameters: 7895 + n - size of (possibly compressed) matrix 7896 . ia - the column pointers 7897 . ja - the row indices 7898 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7899 7900 Level: developer 7901 7902 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7903 @*/ 7904 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7905 { 7906 PetscErrorCode ierr; 7907 7908 PetscFunctionBegin; 7909 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7910 PetscValidType(mat,1); 7911 if (ia) PetscValidIntPointer(ia,6); 7912 if (ja) PetscValidIntPointer(ja,7); 7913 PetscValidBoolPointer(done,8); 7914 MatCheckPreallocated(mat,1); 7915 7916 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7917 else { 7918 *done = PETSC_TRUE; 7919 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7920 if (n) *n = 0; 7921 if (ia) *ia = NULL; 7922 if (ja) *ja = NULL; 7923 } 7924 PetscFunctionReturn(0); 7925 } 7926 7927 /*@C 7928 MatColoringPatch -Used inside matrix coloring routines that 7929 use MatGetRowIJ() and/or MatGetColumnIJ(). 7930 7931 Collective on Mat 7932 7933 Input Parameters: 7934 + mat - the matrix 7935 . ncolors - max color value 7936 . n - number of entries in colorarray 7937 - colorarray - array indicating color for each column 7938 7939 Output Parameters: 7940 . iscoloring - coloring generated using colorarray information 7941 7942 Level: developer 7943 7944 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7945 7946 @*/ 7947 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7948 { 7949 PetscErrorCode ierr; 7950 7951 PetscFunctionBegin; 7952 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7953 PetscValidType(mat,1); 7954 PetscValidIntPointer(colorarray,4); 7955 PetscValidPointer(iscoloring,5); 7956 MatCheckPreallocated(mat,1); 7957 7958 if (!mat->ops->coloringpatch) { 7959 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7960 } else { 7961 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7962 } 7963 PetscFunctionReturn(0); 7964 } 7965 7966 /*@ 7967 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7968 7969 Logically Collective on Mat 7970 7971 Input Parameter: 7972 . mat - the factored matrix to be reset 7973 7974 Notes: 7975 This routine should be used only with factored matrices formed by in-place 7976 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7977 format). This option can save memory, for example, when solving nonlinear 7978 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7979 ILU(0) preconditioner. 7980 7981 Note that one can specify in-place ILU(0) factorization by calling 7982 .vb 7983 PCType(pc,PCILU); 7984 PCFactorSeUseInPlace(pc); 7985 .ve 7986 or by using the options -pc_type ilu -pc_factor_in_place 7987 7988 In-place factorization ILU(0) can also be used as a local 7989 solver for the blocks within the block Jacobi or additive Schwarz 7990 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7991 for details on setting local solver options. 7992 7993 Most users should employ the simplified KSP interface for linear solvers 7994 instead of working directly with matrix algebra routines such as this. 7995 See, e.g., KSPCreate(). 7996 7997 Level: developer 7998 7999 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 8000 8001 @*/ 8002 PetscErrorCode MatSetUnfactored(Mat mat) 8003 { 8004 PetscErrorCode ierr; 8005 8006 PetscFunctionBegin; 8007 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8008 PetscValidType(mat,1); 8009 MatCheckPreallocated(mat,1); 8010 mat->factortype = MAT_FACTOR_NONE; 8011 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8012 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 8013 PetscFunctionReturn(0); 8014 } 8015 8016 /*MC 8017 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8018 8019 Synopsis: 8020 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8021 8022 Not collective 8023 8024 Input Parameter: 8025 . x - matrix 8026 8027 Output Parameters: 8028 + xx_v - the Fortran90 pointer to the array 8029 - ierr - error code 8030 8031 Example of Usage: 8032 .vb 8033 PetscScalar, pointer xx_v(:,:) 8034 .... 8035 call MatDenseGetArrayF90(x,xx_v,ierr) 8036 a = xx_v(3) 8037 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8038 .ve 8039 8040 Level: advanced 8041 8042 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 8043 8044 M*/ 8045 8046 /*MC 8047 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8048 accessed with MatDenseGetArrayF90(). 8049 8050 Synopsis: 8051 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8052 8053 Not collective 8054 8055 Input Parameters: 8056 + x - matrix 8057 - xx_v - the Fortran90 pointer to the array 8058 8059 Output Parameter: 8060 . ierr - error code 8061 8062 Example of Usage: 8063 .vb 8064 PetscScalar, pointer xx_v(:,:) 8065 .... 8066 call MatDenseGetArrayF90(x,xx_v,ierr) 8067 a = xx_v(3) 8068 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8069 .ve 8070 8071 Level: advanced 8072 8073 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 8074 8075 M*/ 8076 8077 /*MC 8078 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8079 8080 Synopsis: 8081 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8082 8083 Not collective 8084 8085 Input Parameter: 8086 . x - matrix 8087 8088 Output Parameters: 8089 + xx_v - the Fortran90 pointer to the array 8090 - ierr - error code 8091 8092 Example of Usage: 8093 .vb 8094 PetscScalar, pointer xx_v(:) 8095 .... 8096 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8097 a = xx_v(3) 8098 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8099 .ve 8100 8101 Level: advanced 8102 8103 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 8104 8105 M*/ 8106 8107 /*MC 8108 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8109 accessed with MatSeqAIJGetArrayF90(). 8110 8111 Synopsis: 8112 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8113 8114 Not collective 8115 8116 Input Parameters: 8117 + x - matrix 8118 - xx_v - the Fortran90 pointer to the array 8119 8120 Output Parameter: 8121 . ierr - error code 8122 8123 Example of Usage: 8124 .vb 8125 PetscScalar, pointer xx_v(:) 8126 .... 8127 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8128 a = xx_v(3) 8129 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8130 .ve 8131 8132 Level: advanced 8133 8134 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 8135 8136 M*/ 8137 8138 /*@ 8139 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8140 as the original matrix. 8141 8142 Collective on Mat 8143 8144 Input Parameters: 8145 + mat - the original matrix 8146 . isrow - parallel IS containing the rows this processor should obtain 8147 . 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. 8148 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8149 8150 Output Parameter: 8151 . newmat - the new submatrix, of the same type as the old 8152 8153 Level: advanced 8154 8155 Notes: 8156 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8157 8158 Some matrix types place restrictions on the row and column indices, such 8159 as that they be sorted or that they be equal to each other. 8160 8161 The index sets may not have duplicate entries. 8162 8163 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8164 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8165 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8166 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8167 you are finished using it. 8168 8169 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8170 the input matrix. 8171 8172 If iscol is NULL then all columns are obtained (not supported in Fortran). 8173 8174 Example usage: 8175 Consider the following 8x8 matrix with 34 non-zero values, that is 8176 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8177 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8178 as follows: 8179 8180 .vb 8181 1 2 0 | 0 3 0 | 0 4 8182 Proc0 0 5 6 | 7 0 0 | 8 0 8183 9 0 10 | 11 0 0 | 12 0 8184 ------------------------------------- 8185 13 0 14 | 15 16 17 | 0 0 8186 Proc1 0 18 0 | 19 20 21 | 0 0 8187 0 0 0 | 22 23 0 | 24 0 8188 ------------------------------------- 8189 Proc2 25 26 27 | 0 0 28 | 29 0 8190 30 0 0 | 31 32 33 | 0 34 8191 .ve 8192 8193 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8194 8195 .vb 8196 2 0 | 0 3 0 | 0 8197 Proc0 5 6 | 7 0 0 | 8 8198 ------------------------------- 8199 Proc1 18 0 | 19 20 21 | 0 8200 ------------------------------- 8201 Proc2 26 27 | 0 0 28 | 29 8202 0 0 | 31 32 33 | 0 8203 .ve 8204 8205 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate() 8206 @*/ 8207 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8208 { 8209 PetscErrorCode ierr; 8210 PetscMPIInt size; 8211 Mat *local; 8212 IS iscoltmp; 8213 PetscBool flg; 8214 8215 PetscFunctionBegin; 8216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8217 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8218 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8219 PetscValidPointer(newmat,5); 8220 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8221 PetscValidType(mat,1); 8222 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8223 PetscCheckFalse(cll == MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8224 8225 MatCheckPreallocated(mat,1); 8226 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 8227 8228 if (!iscol || isrow == iscol) { 8229 PetscBool stride; 8230 PetscMPIInt grabentirematrix = 0,grab; 8231 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 8232 if (stride) { 8233 PetscInt first,step,n,rstart,rend; 8234 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 8235 if (step == 1) { 8236 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 8237 if (rstart == first) { 8238 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 8239 if (n == rend-rstart) { 8240 grabentirematrix = 1; 8241 } 8242 } 8243 } 8244 } 8245 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRMPI(ierr); 8246 if (grab) { 8247 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 8248 if (cll == MAT_INITIAL_MATRIX) { 8249 *newmat = mat; 8250 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 8251 } 8252 PetscFunctionReturn(0); 8253 } 8254 } 8255 8256 if (!iscol) { 8257 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 8258 } else { 8259 iscoltmp = iscol; 8260 } 8261 8262 /* if original matrix is on just one processor then use submatrix generated */ 8263 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8264 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 8265 goto setproperties; 8266 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8267 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 8268 *newmat = *local; 8269 ierr = PetscFree(local);CHKERRQ(ierr); 8270 goto setproperties; 8271 } else if (!mat->ops->createsubmatrix) { 8272 /* Create a new matrix type that implements the operation using the full matrix */ 8273 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8274 switch (cll) { 8275 case MAT_INITIAL_MATRIX: 8276 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 8277 break; 8278 case MAT_REUSE_MATRIX: 8279 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 8280 break; 8281 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8282 } 8283 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8284 goto setproperties; 8285 } 8286 8287 PetscCheckFalse(!mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8288 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8289 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 8290 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 8291 8292 setproperties: 8293 ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr); 8294 if (flg) { 8295 ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr); 8296 } 8297 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 8298 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 8299 PetscFunctionReturn(0); 8300 } 8301 8302 /*@ 8303 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8304 8305 Not Collective 8306 8307 Input Parameters: 8308 + A - the matrix we wish to propagate options from 8309 - B - the matrix we wish to propagate options to 8310 8311 Level: beginner 8312 8313 Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC 8314 8315 .seealso: MatSetOption() 8316 @*/ 8317 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8318 { 8319 PetscErrorCode ierr; 8320 8321 PetscFunctionBegin; 8322 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8323 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8324 if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */ 8325 ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr); 8326 } 8327 if (A->structurally_symmetric_set) { 8328 ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr); 8329 } 8330 if (A->hermitian_set) { 8331 ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr); 8332 } 8333 if (A->spd_set) { 8334 ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr); 8335 } 8336 if (A->symmetric_set) { 8337 ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr); 8338 } 8339 PetscFunctionReturn(0); 8340 } 8341 8342 /*@ 8343 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8344 used during the assembly process to store values that belong to 8345 other processors. 8346 8347 Not Collective 8348 8349 Input Parameters: 8350 + mat - the matrix 8351 . size - the initial size of the stash. 8352 - bsize - the initial size of the block-stash(if used). 8353 8354 Options Database Keys: 8355 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8356 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8357 8358 Level: intermediate 8359 8360 Notes: 8361 The block-stash is used for values set with MatSetValuesBlocked() while 8362 the stash is used for values set with MatSetValues() 8363 8364 Run with the option -info and look for output of the form 8365 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8366 to determine the appropriate value, MM, to use for size and 8367 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8368 to determine the value, BMM to use for bsize 8369 8370 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 8371 8372 @*/ 8373 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8374 { 8375 PetscErrorCode ierr; 8376 8377 PetscFunctionBegin; 8378 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8379 PetscValidType(mat,1); 8380 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 8381 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 8382 PetscFunctionReturn(0); 8383 } 8384 8385 /*@ 8386 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8387 the matrix 8388 8389 Neighbor-wise Collective on Mat 8390 8391 Input Parameters: 8392 + mat - the matrix 8393 . x,y - the vectors 8394 - w - where the result is stored 8395 8396 Level: intermediate 8397 8398 Notes: 8399 w may be the same vector as y. 8400 8401 This allows one to use either the restriction or interpolation (its transpose) 8402 matrix to do the interpolation 8403 8404 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8405 8406 @*/ 8407 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8408 { 8409 PetscErrorCode ierr; 8410 PetscInt M,N,Ny; 8411 8412 PetscFunctionBegin; 8413 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8414 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8415 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8416 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8417 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8418 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8419 if (M == Ny) { 8420 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8421 } else { 8422 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8423 } 8424 PetscFunctionReturn(0); 8425 } 8426 8427 /*@ 8428 MatInterpolate - y = A*x or A'*x depending on the shape of 8429 the matrix 8430 8431 Neighbor-wise Collective on Mat 8432 8433 Input Parameters: 8434 + mat - the matrix 8435 - x,y - the vectors 8436 8437 Level: intermediate 8438 8439 Notes: 8440 This allows one to use either the restriction or interpolation (its transpose) 8441 matrix to do the interpolation 8442 8443 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8444 8445 @*/ 8446 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8447 { 8448 PetscErrorCode ierr; 8449 PetscInt M,N,Ny; 8450 8451 PetscFunctionBegin; 8452 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8453 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8454 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8455 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8456 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8457 if (M == Ny) { 8458 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8459 } else { 8460 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8461 } 8462 PetscFunctionReturn(0); 8463 } 8464 8465 /*@ 8466 MatRestrict - y = A*x or A'*x 8467 8468 Neighbor-wise Collective on Mat 8469 8470 Input Parameters: 8471 + mat - the matrix 8472 - x,y - the vectors 8473 8474 Level: intermediate 8475 8476 Notes: 8477 This allows one to use either the restriction or interpolation (its transpose) 8478 matrix to do the restriction 8479 8480 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8481 8482 @*/ 8483 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8484 { 8485 PetscErrorCode ierr; 8486 PetscInt M,N,Ny; 8487 8488 PetscFunctionBegin; 8489 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8490 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8491 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8492 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8493 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8494 if (M == Ny) { 8495 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8496 } else { 8497 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8498 } 8499 PetscFunctionReturn(0); 8500 } 8501 8502 /*@ 8503 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8504 8505 Neighbor-wise Collective on Mat 8506 8507 Input Parameters: 8508 + mat - the matrix 8509 - w, x - the input dense matrices 8510 8511 Output Parameters: 8512 . y - the output dense matrix 8513 8514 Level: intermediate 8515 8516 Notes: 8517 This allows one to use either the restriction or interpolation (its transpose) 8518 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8519 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8520 8521 .seealso: MatInterpolateAdd(), MatMatInterpolate(), MatMatRestrict() 8522 8523 @*/ 8524 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8525 { 8526 PetscErrorCode ierr; 8527 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8528 PetscBool trans = PETSC_TRUE; 8529 MatReuse reuse = MAT_INITIAL_MATRIX; 8530 8531 PetscFunctionBegin; 8532 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8533 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8534 PetscValidType(x,2); 8535 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8536 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8537 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8538 ierr = MatGetSize(x,&Mx,&Nx);CHKERRQ(ierr); 8539 if (N == Mx) trans = PETSC_FALSE; 8540 else PetscCheckFalse(M != Mx,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Size mismatch: A %" PetscInt_FMT "x%" PetscInt_FMT ", X %" PetscInt_FMT "x%" PetscInt_FMT,M,N,Mx,Nx); 8541 Mo = trans ? N : M; 8542 if (*y) { 8543 ierr = MatGetSize(*y,&My,&Ny);CHKERRQ(ierr); 8544 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8545 else { 8546 PetscCheckFalse(w && *y == w,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot reuse y and w, size mismatch: A %" PetscInt_FMT "x%" PetscInt_FMT ", X %" PetscInt_FMT "x%" PetscInt_FMT ", Y %" PetscInt_FMT "x%" PetscInt_FMT,M,N,Mx,Nx,My,Ny); 8547 ierr = MatDestroy(y);CHKERRQ(ierr); 8548 } 8549 } 8550 8551 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8552 PetscBool flg; 8553 8554 ierr = PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w);CHKERRQ(ierr); 8555 if (w) { 8556 PetscInt My,Ny,Mw,Nw; 8557 8558 ierr = PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg);CHKERRQ(ierr); 8559 ierr = MatGetSize(*y,&My,&Ny);CHKERRQ(ierr); 8560 ierr = MatGetSize(w,&Mw,&Nw);CHKERRQ(ierr); 8561 if (!flg || My != Mw || Ny != Nw) w = NULL; 8562 } 8563 if (!w) { 8564 ierr = MatDuplicate(*y,MAT_COPY_VALUES,&w);CHKERRQ(ierr); 8565 ierr = PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w);CHKERRQ(ierr); 8566 ierr = PetscLogObjectParent((PetscObject)*y,(PetscObject)w);CHKERRQ(ierr); 8567 ierr = PetscObjectDereference((PetscObject)w);CHKERRQ(ierr); 8568 } else { 8569 ierr = MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr); 8570 } 8571 } 8572 if (!trans) { 8573 ierr = MatMatMult(A,x,reuse,PETSC_DEFAULT,y);CHKERRQ(ierr); 8574 } else { 8575 ierr = MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y);CHKERRQ(ierr); 8576 } 8577 if (w) { 8578 ierr = MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN);CHKERRQ(ierr); 8579 } 8580 PetscFunctionReturn(0); 8581 } 8582 8583 /*@ 8584 MatMatInterpolate - Y = A*X or A'*X 8585 8586 Neighbor-wise Collective on Mat 8587 8588 Input Parameters: 8589 + mat - the matrix 8590 - x - the input dense matrix 8591 8592 Output Parameters: 8593 . y - the output dense matrix 8594 8595 Level: intermediate 8596 8597 Notes: 8598 This allows one to use either the restriction or interpolation (its transpose) 8599 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8600 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8601 8602 .seealso: MatInterpolate(), MatRestrict(), MatMatRestrict() 8603 8604 @*/ 8605 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8606 { 8607 PetscErrorCode ierr; 8608 8609 PetscFunctionBegin; 8610 ierr = MatMatInterpolateAdd(A,x,NULL,y);CHKERRQ(ierr); 8611 PetscFunctionReturn(0); 8612 } 8613 8614 /*@ 8615 MatMatRestrict - Y = A*X or A'*X 8616 8617 Neighbor-wise Collective on Mat 8618 8619 Input Parameters: 8620 + mat - the matrix 8621 - x - the input dense matrix 8622 8623 Output Parameters: 8624 . y - the output dense matrix 8625 8626 Level: intermediate 8627 8628 Notes: 8629 This allows one to use either the restriction or interpolation (its transpose) 8630 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8631 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8632 8633 .seealso: MatRestrict(), MatInterpolate(), MatMatInterpolate() 8634 @*/ 8635 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8636 { 8637 PetscErrorCode ierr; 8638 8639 PetscFunctionBegin; 8640 ierr = MatMatInterpolateAdd(A,x,NULL,y);CHKERRQ(ierr); 8641 PetscFunctionReturn(0); 8642 } 8643 8644 /*@ 8645 MatGetNullSpace - retrieves the null space of a matrix. 8646 8647 Logically Collective on Mat 8648 8649 Input Parameters: 8650 + mat - the matrix 8651 - nullsp - the null space object 8652 8653 Level: developer 8654 8655 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8656 @*/ 8657 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8658 { 8659 PetscFunctionBegin; 8660 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8661 PetscValidPointer(nullsp,2); 8662 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8663 PetscFunctionReturn(0); 8664 } 8665 8666 /*@ 8667 MatSetNullSpace - attaches a null space to a matrix. 8668 8669 Logically Collective on Mat 8670 8671 Input Parameters: 8672 + mat - the matrix 8673 - nullsp - the null space object 8674 8675 Level: advanced 8676 8677 Notes: 8678 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8679 8680 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8681 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8682 8683 You can remove the null space by calling this routine with an nullsp of NULL 8684 8685 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8686 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). 8687 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 8688 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 8689 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). 8690 8691 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8692 8693 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 8694 routine also automatically calls MatSetTransposeNullSpace(). 8695 8696 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8697 @*/ 8698 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8699 { 8700 PetscErrorCode ierr; 8701 8702 PetscFunctionBegin; 8703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8704 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8705 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8706 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8707 mat->nullsp = nullsp; 8708 if (mat->symmetric_set && mat->symmetric) { 8709 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8710 } 8711 PetscFunctionReturn(0); 8712 } 8713 8714 /*@ 8715 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8716 8717 Logically Collective on Mat 8718 8719 Input Parameters: 8720 + mat - the matrix 8721 - nullsp - the null space object 8722 8723 Level: developer 8724 8725 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8726 @*/ 8727 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8728 { 8729 PetscFunctionBegin; 8730 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8731 PetscValidType(mat,1); 8732 PetscValidPointer(nullsp,2); 8733 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8734 PetscFunctionReturn(0); 8735 } 8736 8737 /*@ 8738 MatSetTransposeNullSpace - attaches a null space to a matrix. 8739 8740 Logically Collective on Mat 8741 8742 Input Parameters: 8743 + mat - the matrix 8744 - nullsp - the null space object 8745 8746 Level: advanced 8747 8748 Notes: 8749 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. 8750 You must also call MatSetNullSpace() 8751 8752 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8753 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). 8754 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 8755 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 8756 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). 8757 8758 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8759 8760 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8761 @*/ 8762 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8763 { 8764 PetscErrorCode ierr; 8765 8766 PetscFunctionBegin; 8767 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8768 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8769 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8770 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8771 mat->transnullsp = nullsp; 8772 PetscFunctionReturn(0); 8773 } 8774 8775 /*@ 8776 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8777 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8778 8779 Logically Collective on Mat 8780 8781 Input Parameters: 8782 + mat - the matrix 8783 - nullsp - the null space object 8784 8785 Level: advanced 8786 8787 Notes: 8788 Overwrites any previous near null space that may have been attached 8789 8790 You can remove the null space by calling this routine with an nullsp of NULL 8791 8792 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8793 @*/ 8794 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8795 { 8796 PetscErrorCode ierr; 8797 8798 PetscFunctionBegin; 8799 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8800 PetscValidType(mat,1); 8801 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8802 MatCheckPreallocated(mat,1); 8803 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8804 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8805 mat->nearnullsp = nullsp; 8806 PetscFunctionReturn(0); 8807 } 8808 8809 /*@ 8810 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8811 8812 Not Collective 8813 8814 Input Parameter: 8815 . mat - the matrix 8816 8817 Output Parameter: 8818 . nullsp - the null space object, NULL if not set 8819 8820 Level: developer 8821 8822 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8823 @*/ 8824 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8825 { 8826 PetscFunctionBegin; 8827 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8828 PetscValidType(mat,1); 8829 PetscValidPointer(nullsp,2); 8830 MatCheckPreallocated(mat,1); 8831 *nullsp = mat->nearnullsp; 8832 PetscFunctionReturn(0); 8833 } 8834 8835 /*@C 8836 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8837 8838 Collective on Mat 8839 8840 Input Parameters: 8841 + mat - the matrix 8842 . row - row/column permutation 8843 . fill - expected fill factor >= 1.0 8844 - level - level of fill, for ICC(k) 8845 8846 Notes: 8847 Probably really in-place only when level of fill is zero, otherwise allocates 8848 new space to store factored matrix and deletes previous memory. 8849 8850 Most users should employ the simplified KSP interface for linear solvers 8851 instead of working directly with matrix algebra routines such as this. 8852 See, e.g., KSPCreate(). 8853 8854 Level: developer 8855 8856 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8857 8858 Developer Note: fortran interface is not autogenerated as the f90 8859 interface definition cannot be generated correctly [due to MatFactorInfo] 8860 8861 @*/ 8862 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8863 { 8864 PetscErrorCode ierr; 8865 8866 PetscFunctionBegin; 8867 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8868 PetscValidType(mat,1); 8869 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8870 PetscValidPointer(info,3); 8871 PetscCheckFalse(mat->rmap->N != mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8872 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8873 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8874 PetscCheckFalse(!mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8875 MatCheckPreallocated(mat,1); 8876 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8877 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8878 PetscFunctionReturn(0); 8879 } 8880 8881 /*@ 8882 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8883 ghosted ones. 8884 8885 Not Collective 8886 8887 Input Parameters: 8888 + mat - the matrix 8889 - diag - the diagonal values, including ghost ones 8890 8891 Level: developer 8892 8893 Notes: 8894 Works only for MPIAIJ and MPIBAIJ matrices 8895 8896 .seealso: MatDiagonalScale() 8897 @*/ 8898 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8899 { 8900 PetscErrorCode ierr; 8901 PetscMPIInt size; 8902 8903 PetscFunctionBegin; 8904 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8905 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8906 PetscValidType(mat,1); 8907 8908 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8909 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8910 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 8911 if (size == 1) { 8912 PetscInt n,m; 8913 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8914 ierr = MatGetSize(mat,NULL,&m);CHKERRQ(ierr); 8915 if (m == n) { 8916 ierr = MatDiagonalScale(mat,NULL,diag);CHKERRQ(ierr); 8917 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8918 } else { 8919 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8920 } 8921 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8922 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8923 PetscFunctionReturn(0); 8924 } 8925 8926 /*@ 8927 MatGetInertia - Gets the inertia from a factored matrix 8928 8929 Collective on Mat 8930 8931 Input Parameter: 8932 . mat - the matrix 8933 8934 Output Parameters: 8935 + nneg - number of negative eigenvalues 8936 . nzero - number of zero eigenvalues 8937 - npos - number of positive eigenvalues 8938 8939 Level: advanced 8940 8941 Notes: 8942 Matrix must have been factored by MatCholeskyFactor() 8943 8944 @*/ 8945 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8946 { 8947 PetscErrorCode ierr; 8948 8949 PetscFunctionBegin; 8950 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8951 PetscValidType(mat,1); 8952 PetscCheckFalse(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8953 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8954 PetscCheckFalse(!mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8955 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8956 PetscFunctionReturn(0); 8957 } 8958 8959 /* ----------------------------------------------------------------*/ 8960 /*@C 8961 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8962 8963 Neighbor-wise Collective on Mats 8964 8965 Input Parameters: 8966 + mat - the factored matrix 8967 - b - the right-hand-side vectors 8968 8969 Output Parameter: 8970 . x - the result vectors 8971 8972 Notes: 8973 The vectors b and x cannot be the same. I.e., one cannot 8974 call MatSolves(A,x,x). 8975 8976 Notes: 8977 Most users should employ the simplified KSP interface for linear solvers 8978 instead of working directly with matrix algebra routines such as this. 8979 See, e.g., KSPCreate(). 8980 8981 Level: developer 8982 8983 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8984 @*/ 8985 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8986 { 8987 PetscErrorCode ierr; 8988 8989 PetscFunctionBegin; 8990 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8991 PetscValidType(mat,1); 8992 PetscCheckFalse(x == b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8993 PetscCheckFalse(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8994 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8995 8996 PetscCheckFalse(!mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8997 MatCheckPreallocated(mat,1); 8998 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8999 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 9000 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 9001 PetscFunctionReturn(0); 9002 } 9003 9004 /*@ 9005 MatIsSymmetric - Test whether a matrix is symmetric 9006 9007 Collective on Mat 9008 9009 Input Parameters: 9010 + A - the matrix to test 9011 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9012 9013 Output Parameters: 9014 . flg - the result 9015 9016 Notes: 9017 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9018 9019 Level: intermediate 9020 9021 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 9022 @*/ 9023 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9024 { 9025 PetscErrorCode ierr; 9026 9027 PetscFunctionBegin; 9028 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9029 PetscValidBoolPointer(flg,3); 9030 9031 if (!A->symmetric_set) { 9032 if (!A->ops->issymmetric) { 9033 MatType mattype; 9034 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 9035 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9036 } 9037 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 9038 if (!tol) { 9039 ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr); 9040 } 9041 } else if (A->symmetric) { 9042 *flg = PETSC_TRUE; 9043 } else if (!tol) { 9044 *flg = PETSC_FALSE; 9045 } else { 9046 if (!A->ops->issymmetric) { 9047 MatType mattype; 9048 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 9049 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9050 } 9051 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 9052 } 9053 PetscFunctionReturn(0); 9054 } 9055 9056 /*@ 9057 MatIsHermitian - Test whether a matrix is Hermitian 9058 9059 Collective on Mat 9060 9061 Input Parameters: 9062 + A - the matrix to test 9063 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9064 9065 Output Parameters: 9066 . flg - the result 9067 9068 Level: intermediate 9069 9070 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 9071 MatIsSymmetricKnown(), MatIsSymmetric() 9072 @*/ 9073 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9074 { 9075 PetscErrorCode ierr; 9076 9077 PetscFunctionBegin; 9078 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9079 PetscValidBoolPointer(flg,3); 9080 9081 if (!A->hermitian_set) { 9082 if (!A->ops->ishermitian) { 9083 MatType mattype; 9084 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 9085 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9086 } 9087 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 9088 if (!tol) { 9089 ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr); 9090 } 9091 } else if (A->hermitian) { 9092 *flg = PETSC_TRUE; 9093 } else if (!tol) { 9094 *flg = PETSC_FALSE; 9095 } else { 9096 if (!A->ops->ishermitian) { 9097 MatType mattype; 9098 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 9099 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9100 } 9101 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 9102 } 9103 PetscFunctionReturn(0); 9104 } 9105 9106 /*@ 9107 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 9108 9109 Not Collective 9110 9111 Input Parameter: 9112 . A - the matrix to check 9113 9114 Output Parameters: 9115 + set - if the symmetric flag is set (this tells you if the next flag is valid) 9116 - flg - the result 9117 9118 Level: advanced 9119 9120 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9121 if you want it explicitly checked 9122 9123 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 9124 @*/ 9125 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9126 { 9127 PetscFunctionBegin; 9128 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9129 PetscValidPointer(set,2); 9130 PetscValidBoolPointer(flg,3); 9131 if (A->symmetric_set) { 9132 *set = PETSC_TRUE; 9133 *flg = A->symmetric; 9134 } else { 9135 *set = PETSC_FALSE; 9136 } 9137 PetscFunctionReturn(0); 9138 } 9139 9140 /*@ 9141 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 9142 9143 Not Collective 9144 9145 Input Parameter: 9146 . A - the matrix to check 9147 9148 Output Parameters: 9149 + set - if the hermitian flag is set (this tells you if the next flag is valid) 9150 - flg - the result 9151 9152 Level: advanced 9153 9154 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9155 if you want it explicitly checked 9156 9157 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 9158 @*/ 9159 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9160 { 9161 PetscFunctionBegin; 9162 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9163 PetscValidPointer(set,2); 9164 PetscValidBoolPointer(flg,3); 9165 if (A->hermitian_set) { 9166 *set = PETSC_TRUE; 9167 *flg = A->hermitian; 9168 } else { 9169 *set = PETSC_FALSE; 9170 } 9171 PetscFunctionReturn(0); 9172 } 9173 9174 /*@ 9175 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9176 9177 Collective on Mat 9178 9179 Input Parameter: 9180 . A - the matrix to test 9181 9182 Output Parameters: 9183 . flg - the result 9184 9185 Level: intermediate 9186 9187 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 9188 @*/ 9189 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9190 { 9191 PetscErrorCode ierr; 9192 9193 PetscFunctionBegin; 9194 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9195 PetscValidBoolPointer(flg,2); 9196 if (!A->structurally_symmetric_set) { 9197 PetscCheckFalse(!A->ops->isstructurallysymmetric,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetric",((PetscObject)A)->type_name); 9198 ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr); 9199 ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr); 9200 } else *flg = A->structurally_symmetric; 9201 PetscFunctionReturn(0); 9202 } 9203 9204 /*@ 9205 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9206 to be communicated to other processors during the MatAssemblyBegin/End() process 9207 9208 Not collective 9209 9210 Input Parameter: 9211 . vec - the vector 9212 9213 Output Parameters: 9214 + nstash - the size of the stash 9215 . reallocs - the number of additional mallocs incurred. 9216 . bnstash - the size of the block stash 9217 - breallocs - the number of additional mallocs incurred.in the block stash 9218 9219 Level: advanced 9220 9221 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 9222 9223 @*/ 9224 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9225 { 9226 PetscErrorCode ierr; 9227 9228 PetscFunctionBegin; 9229 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 9230 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 9231 PetscFunctionReturn(0); 9232 } 9233 9234 /*@C 9235 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9236 parallel layout 9237 9238 Collective on Mat 9239 9240 Input Parameter: 9241 . mat - the matrix 9242 9243 Output Parameters: 9244 + right - (optional) vector that the matrix can be multiplied against 9245 - left - (optional) vector that the matrix vector product can be stored in 9246 9247 Notes: 9248 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(). 9249 9250 Notes: 9251 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9252 9253 Level: advanced 9254 9255 .seealso: MatCreate(), VecDestroy() 9256 @*/ 9257 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9258 { 9259 PetscErrorCode ierr; 9260 9261 PetscFunctionBegin; 9262 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9263 PetscValidType(mat,1); 9264 if (mat->ops->getvecs) { 9265 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 9266 } else { 9267 PetscInt rbs,cbs; 9268 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 9269 if (right) { 9270 PetscCheckFalse(mat->cmap->n < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9271 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 9272 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 9273 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 9274 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 9275 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9276 if (mat->boundtocpu && mat->bindingpropagates) { 9277 ierr = VecSetBindingPropagates(*right,PETSC_TRUE);CHKERRQ(ierr); 9278 ierr = VecBindToCPU(*right,PETSC_TRUE);CHKERRQ(ierr); 9279 } 9280 #endif 9281 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 9282 } 9283 if (left) { 9284 PetscCheckFalse(mat->rmap->n < 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9285 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 9286 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 9287 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 9288 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 9289 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9290 if (mat->boundtocpu && mat->bindingpropagates) { 9291 ierr = VecSetBindingPropagates(*left,PETSC_TRUE);CHKERRQ(ierr); 9292 ierr = VecBindToCPU(*left,PETSC_TRUE);CHKERRQ(ierr); 9293 } 9294 #endif 9295 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 9296 } 9297 } 9298 PetscFunctionReturn(0); 9299 } 9300 9301 /*@C 9302 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9303 with default values. 9304 9305 Not Collective 9306 9307 Input Parameters: 9308 . info - the MatFactorInfo data structure 9309 9310 Notes: 9311 The solvers are generally used through the KSP and PC objects, for example 9312 PCLU, PCILU, PCCHOLESKY, PCICC 9313 9314 Level: developer 9315 9316 .seealso: MatFactorInfo 9317 9318 Developer Note: fortran interface is not autogenerated as the f90 9319 interface definition cannot be generated correctly [due to MatFactorInfo] 9320 9321 @*/ 9322 9323 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9324 { 9325 PetscErrorCode ierr; 9326 9327 PetscFunctionBegin; 9328 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 9329 PetscFunctionReturn(0); 9330 } 9331 9332 /*@ 9333 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9334 9335 Collective on Mat 9336 9337 Input Parameters: 9338 + mat - the factored matrix 9339 - is - the index set defining the Schur indices (0-based) 9340 9341 Notes: 9342 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9343 9344 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9345 9346 Level: developer 9347 9348 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 9349 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 9350 9351 @*/ 9352 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9353 { 9354 PetscErrorCode ierr,(*f)(Mat,IS); 9355 9356 PetscFunctionBegin; 9357 PetscValidType(mat,1); 9358 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9359 PetscValidType(is,2); 9360 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9361 PetscCheckSameComm(mat,1,is,2); 9362 PetscCheckFalse(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9363 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 9364 PetscCheckFalse(!f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9365 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 9366 ierr = (*f)(mat,is);CHKERRQ(ierr); 9367 PetscCheckFalse(!mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9368 PetscFunctionReturn(0); 9369 } 9370 9371 /*@ 9372 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9373 9374 Logically Collective on Mat 9375 9376 Input Parameters: 9377 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9378 . S - location where to return the Schur complement, can be NULL 9379 - status - the status of the Schur complement matrix, can be NULL 9380 9381 Notes: 9382 You must call MatFactorSetSchurIS() before calling this routine. 9383 9384 The routine provides a copy of the Schur matrix stored within the solver data structures. 9385 The caller must destroy the object when it is no longer needed. 9386 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9387 9388 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) 9389 9390 Developer Notes: 9391 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9392 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9393 9394 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9395 9396 Level: advanced 9397 9398 References: 9399 9400 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 9401 @*/ 9402 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9403 { 9404 PetscErrorCode ierr; 9405 9406 PetscFunctionBegin; 9407 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9408 if (S) PetscValidPointer(S,2); 9409 if (status) PetscValidPointer(status,3); 9410 if (S) { 9411 PetscErrorCode (*f)(Mat,Mat*); 9412 9413 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 9414 if (f) { 9415 ierr = (*f)(F,S);CHKERRQ(ierr); 9416 } else { 9417 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 9418 } 9419 } 9420 if (status) *status = F->schur_status; 9421 PetscFunctionReturn(0); 9422 } 9423 9424 /*@ 9425 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9426 9427 Logically Collective on Mat 9428 9429 Input Parameters: 9430 + F - the factored matrix obtained by calling MatGetFactor() 9431 . *S - location where to return the Schur complement, can be NULL 9432 - status - the status of the Schur complement matrix, can be NULL 9433 9434 Notes: 9435 You must call MatFactorSetSchurIS() before calling this routine. 9436 9437 Schur complement mode is currently implemented for sequential matrices. 9438 The routine returns a the Schur Complement stored within the data strutures of the solver. 9439 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9440 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9441 9442 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9443 9444 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9445 9446 Level: advanced 9447 9448 References: 9449 9450 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9451 @*/ 9452 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9453 { 9454 PetscFunctionBegin; 9455 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9456 if (S) PetscValidPointer(S,2); 9457 if (status) PetscValidPointer(status,3); 9458 if (S) *S = F->schur; 9459 if (status) *status = F->schur_status; 9460 PetscFunctionReturn(0); 9461 } 9462 9463 /*@ 9464 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9465 9466 Logically Collective on Mat 9467 9468 Input Parameters: 9469 + F - the factored matrix obtained by calling MatGetFactor() 9470 . *S - location where the Schur complement is stored 9471 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9472 9473 Notes: 9474 9475 Level: advanced 9476 9477 References: 9478 9479 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 9480 @*/ 9481 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9482 { 9483 PetscErrorCode ierr; 9484 9485 PetscFunctionBegin; 9486 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9487 if (S) { 9488 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9489 *S = NULL; 9490 } 9491 F->schur_status = status; 9492 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 9493 PetscFunctionReturn(0); 9494 } 9495 9496 /*@ 9497 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9498 9499 Logically Collective on Mat 9500 9501 Input Parameters: 9502 + F - the factored matrix obtained by calling MatGetFactor() 9503 . rhs - location where the right hand side of the Schur complement system is stored 9504 - sol - location where the solution of the Schur complement system has to be returned 9505 9506 Notes: 9507 The sizes of the vectors should match the size of the Schur complement 9508 9509 Must be called after MatFactorSetSchurIS() 9510 9511 Level: advanced 9512 9513 References: 9514 9515 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 9516 @*/ 9517 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9518 { 9519 PetscErrorCode ierr; 9520 9521 PetscFunctionBegin; 9522 PetscValidType(F,1); 9523 PetscValidType(rhs,2); 9524 PetscValidType(sol,3); 9525 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9526 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9527 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9528 PetscCheckSameComm(F,1,rhs,2); 9529 PetscCheckSameComm(F,1,sol,3); 9530 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9531 switch (F->schur_status) { 9532 case MAT_FACTOR_SCHUR_FACTORED: 9533 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9534 break; 9535 case MAT_FACTOR_SCHUR_INVERTED: 9536 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9537 break; 9538 default: 9539 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9540 } 9541 PetscFunctionReturn(0); 9542 } 9543 9544 /*@ 9545 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9546 9547 Logically Collective on Mat 9548 9549 Input Parameters: 9550 + F - the factored matrix obtained by calling MatGetFactor() 9551 . rhs - location where the right hand side of the Schur complement system is stored 9552 - sol - location where the solution of the Schur complement system has to be returned 9553 9554 Notes: 9555 The sizes of the vectors should match the size of the Schur complement 9556 9557 Must be called after MatFactorSetSchurIS() 9558 9559 Level: advanced 9560 9561 References: 9562 9563 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9564 @*/ 9565 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9566 { 9567 PetscErrorCode ierr; 9568 9569 PetscFunctionBegin; 9570 PetscValidType(F,1); 9571 PetscValidType(rhs,2); 9572 PetscValidType(sol,3); 9573 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9574 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9575 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9576 PetscCheckSameComm(F,1,rhs,2); 9577 PetscCheckSameComm(F,1,sol,3); 9578 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9579 switch (F->schur_status) { 9580 case MAT_FACTOR_SCHUR_FACTORED: 9581 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9582 break; 9583 case MAT_FACTOR_SCHUR_INVERTED: 9584 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9585 break; 9586 default: 9587 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9588 } 9589 PetscFunctionReturn(0); 9590 } 9591 9592 /*@ 9593 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9594 9595 Logically Collective on Mat 9596 9597 Input Parameters: 9598 . F - the factored matrix obtained by calling MatGetFactor() 9599 9600 Notes: 9601 Must be called after MatFactorSetSchurIS(). 9602 9603 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9604 9605 Level: advanced 9606 9607 References: 9608 9609 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9610 @*/ 9611 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9612 { 9613 PetscErrorCode ierr; 9614 9615 PetscFunctionBegin; 9616 PetscValidType(F,1); 9617 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9618 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9619 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9620 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9621 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9622 PetscFunctionReturn(0); 9623 } 9624 9625 /*@ 9626 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9627 9628 Logically Collective on Mat 9629 9630 Input Parameters: 9631 . F - the factored matrix obtained by calling MatGetFactor() 9632 9633 Notes: 9634 Must be called after MatFactorSetSchurIS(). 9635 9636 Level: advanced 9637 9638 References: 9639 9640 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9641 @*/ 9642 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9643 { 9644 PetscErrorCode ierr; 9645 9646 PetscFunctionBegin; 9647 PetscValidType(F,1); 9648 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9649 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9650 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9651 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9652 PetscFunctionReturn(0); 9653 } 9654 9655 /*@ 9656 MatPtAP - Creates the matrix product C = P^T * A * P 9657 9658 Neighbor-wise Collective on Mat 9659 9660 Input Parameters: 9661 + A - the matrix 9662 . P - the projection matrix 9663 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9664 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9665 if the result is a dense matrix this is irrelevant 9666 9667 Output Parameters: 9668 . C - the product matrix 9669 9670 Notes: 9671 C will be created and must be destroyed by the user with MatDestroy(). 9672 9673 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9674 9675 Level: intermediate 9676 9677 .seealso: MatMatMult(), MatRARt() 9678 @*/ 9679 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9680 { 9681 PetscErrorCode ierr; 9682 9683 PetscFunctionBegin; 9684 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9685 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9686 9687 if (scall == MAT_INITIAL_MATRIX) { 9688 ierr = MatProductCreate(A,P,NULL,C);CHKERRQ(ierr); 9689 ierr = MatProductSetType(*C,MATPRODUCT_PtAP);CHKERRQ(ierr); 9690 ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr); 9691 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr); 9692 9693 (*C)->product->api_user = PETSC_TRUE; 9694 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9695 PetscCheckFalse(!(*C)->ops->productsymbolic,PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and P %s",MatProductTypes[MATPRODUCT_PtAP],((PetscObject)A)->type_name,((PetscObject)P)->type_name); 9696 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9697 } else { /* scall == MAT_REUSE_MATRIX */ 9698 ierr = MatProductReplaceMats(A,P,NULL,*C);CHKERRQ(ierr); 9699 } 9700 9701 ierr = MatProductNumeric(*C);CHKERRQ(ierr); 9702 if (A->symmetric) { 9703 if (A->spd) { 9704 ierr = MatSetOption(*C,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 9705 } else { 9706 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9707 } 9708 } 9709 PetscFunctionReturn(0); 9710 } 9711 9712 /*@ 9713 MatRARt - Creates the matrix product C = R * A * R^T 9714 9715 Neighbor-wise Collective on Mat 9716 9717 Input Parameters: 9718 + A - the matrix 9719 . R - the projection matrix 9720 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9721 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9722 if the result is a dense matrix this is irrelevant 9723 9724 Output Parameters: 9725 . C - the product matrix 9726 9727 Notes: 9728 C will be created and must be destroyed by the user with MatDestroy(). 9729 9730 This routine is currently only implemented for pairs of AIJ matrices and classes 9731 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9732 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9733 We recommend using MatPtAP(). 9734 9735 Level: intermediate 9736 9737 .seealso: MatMatMult(), MatPtAP() 9738 @*/ 9739 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9740 { 9741 PetscErrorCode ierr; 9742 9743 PetscFunctionBegin; 9744 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9745 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9746 9747 if (scall == MAT_INITIAL_MATRIX) { 9748 ierr = MatProductCreate(A,R,NULL,C);CHKERRQ(ierr); 9749 ierr = MatProductSetType(*C,MATPRODUCT_RARt);CHKERRQ(ierr); 9750 ierr = MatProductSetAlgorithm(*C,"default");CHKERRQ(ierr); 9751 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr); 9752 9753 (*C)->product->api_user = PETSC_TRUE; 9754 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9755 PetscCheckFalse(!(*C)->ops->productsymbolic,PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s and R %s",MatProductTypes[MATPRODUCT_RARt],((PetscObject)A)->type_name,((PetscObject)R)->type_name); 9756 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9757 } else { /* scall == MAT_REUSE_MATRIX */ 9758 ierr = MatProductReplaceMats(A,R,NULL,*C);CHKERRQ(ierr); 9759 } 9760 9761 ierr = MatProductNumeric(*C);CHKERRQ(ierr); 9762 if (A->symmetric_set && A->symmetric) { 9763 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9764 } 9765 PetscFunctionReturn(0); 9766 } 9767 9768 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9769 { 9770 PetscErrorCode ierr; 9771 9772 PetscFunctionBegin; 9773 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9774 9775 if (scall == MAT_INITIAL_MATRIX) { 9776 ierr = PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype]);CHKERRQ(ierr); 9777 ierr = MatProductCreate(A,B,NULL,C);CHKERRQ(ierr); 9778 ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr); 9779 ierr = MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 9780 ierr = MatProductSetFill(*C,fill);CHKERRQ(ierr); 9781 9782 (*C)->product->api_user = PETSC_TRUE; 9783 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9784 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9785 } else { /* scall == MAT_REUSE_MATRIX */ 9786 Mat_Product *product = (*C)->product; 9787 PetscBool isdense; 9788 9789 ierr = PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 9790 if (isdense && product && product->type != ptype) { 9791 ierr = MatProductClear(*C);CHKERRQ(ierr); 9792 product = NULL; 9793 } 9794 ierr = PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype]);CHKERRQ(ierr); 9795 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9796 if (isdense) { 9797 ierr = MatProductCreate_Private(A,B,NULL,*C);CHKERRQ(ierr); 9798 product = (*C)->product; 9799 product->fill = fill; 9800 product->api_user = PETSC_TRUE; 9801 product->clear = PETSC_TRUE; 9802 9803 ierr = MatProductSetType(*C,ptype);CHKERRQ(ierr); 9804 ierr = MatProductSetFromOptions(*C);CHKERRQ(ierr); 9805 PetscCheckFalse(!(*C)->ops->productsymbolic,PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"MatProduct %s not supported for %s and %s",MatProductTypes[ptype],((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9806 ierr = MatProductSymbolic(*C);CHKERRQ(ierr); 9807 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9808 } else { /* user may change input matrices A or B when REUSE */ 9809 ierr = MatProductReplaceMats(A,B,NULL,*C);CHKERRQ(ierr); 9810 } 9811 } 9812 ierr = MatProductNumeric(*C);CHKERRQ(ierr); 9813 PetscFunctionReturn(0); 9814 } 9815 9816 /*@ 9817 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9818 9819 Neighbor-wise Collective on Mat 9820 9821 Input Parameters: 9822 + A - the left matrix 9823 . B - the right matrix 9824 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9825 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9826 if the result is a dense matrix this is irrelevant 9827 9828 Output Parameters: 9829 . C - the product matrix 9830 9831 Notes: 9832 Unless scall is MAT_REUSE_MATRIX C will be created. 9833 9834 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 9835 call to this function with MAT_INITIAL_MATRIX. 9836 9837 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9838 9839 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9840 9841 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 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9842 9843 Example of Usage: 9844 .vb 9845 MatProductCreate(A,B,NULL,&C); 9846 MatProductSetType(C,MATPRODUCT_AB); 9847 MatProductSymbolic(C); 9848 MatProductNumeric(C); // compute C=A * B 9849 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9850 MatProductNumeric(C); 9851 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9852 MatProductNumeric(C); 9853 .ve 9854 9855 Level: intermediate 9856 9857 .seealso: MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP(), MatProductCreate(), MatProductSymbolic(), MatProductReplaceMats(), MatProductNumeric() 9858 @*/ 9859 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9860 { 9861 PetscErrorCode ierr; 9862 9863 PetscFunctionBegin; 9864 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C);CHKERRQ(ierr); 9865 PetscFunctionReturn(0); 9866 } 9867 9868 /*@ 9869 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9870 9871 Neighbor-wise Collective on Mat 9872 9873 Input Parameters: 9874 + A - the left matrix 9875 . B - the right matrix 9876 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9877 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9878 9879 Output Parameters: 9880 . C - the product matrix 9881 9882 Notes: 9883 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9884 9885 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9886 9887 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9888 actually needed. 9889 9890 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9891 and for pairs of MPIDense matrices. 9892 9893 Options Database Keys: 9894 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9895 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9896 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9897 9898 Level: intermediate 9899 9900 .seealso: MatMatMult(), MatTransposeMatMult() MatPtAP() 9901 @*/ 9902 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9903 { 9904 PetscErrorCode ierr; 9905 9906 PetscFunctionBegin; 9907 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C);CHKERRQ(ierr); 9908 PetscFunctionReturn(0); 9909 } 9910 9911 /*@ 9912 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9913 9914 Neighbor-wise Collective on Mat 9915 9916 Input Parameters: 9917 + A - the left matrix 9918 . B - the right matrix 9919 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9920 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9921 9922 Output Parameters: 9923 . C - the product matrix 9924 9925 Notes: 9926 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9927 9928 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9929 9930 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9931 actually needed. 9932 9933 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9934 which inherit from SeqAIJ. C will be of same type as the input matrices. 9935 9936 Level: intermediate 9937 9938 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP() 9939 @*/ 9940 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9941 { 9942 PetscErrorCode ierr; 9943 9944 PetscFunctionBegin; 9945 ierr = MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C);CHKERRQ(ierr); 9946 PetscFunctionReturn(0); 9947 } 9948 9949 /*@ 9950 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9951 9952 Neighbor-wise Collective on Mat 9953 9954 Input Parameters: 9955 + A - the left matrix 9956 . B - the middle matrix 9957 . C - the right matrix 9958 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9959 - 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 9960 if the result is a dense matrix this is irrelevant 9961 9962 Output Parameters: 9963 . D - the product matrix 9964 9965 Notes: 9966 Unless scall is MAT_REUSE_MATRIX D will be created. 9967 9968 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9969 9970 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9971 actually needed. 9972 9973 If you have many matrices with the same non-zero structure to multiply, you 9974 should use MAT_REUSE_MATRIX in all calls but the first or 9975 9976 Level: intermediate 9977 9978 .seealso: MatMatMult, MatPtAP() 9979 @*/ 9980 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9981 { 9982 PetscErrorCode ierr; 9983 9984 PetscFunctionBegin; 9985 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 9986 PetscCheckFalse(scall == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9987 9988 if (scall == MAT_INITIAL_MATRIX) { 9989 ierr = MatProductCreate(A,B,C,D);CHKERRQ(ierr); 9990 ierr = MatProductSetType(*D,MATPRODUCT_ABC);CHKERRQ(ierr); 9991 ierr = MatProductSetAlgorithm(*D,"default");CHKERRQ(ierr); 9992 ierr = MatProductSetFill(*D,fill);CHKERRQ(ierr); 9993 9994 (*D)->product->api_user = PETSC_TRUE; 9995 ierr = MatProductSetFromOptions(*D);CHKERRQ(ierr); 9996 PetscCheckFalse(!(*D)->ops->productsymbolic,PetscObjectComm((PetscObject)(*D)),PETSC_ERR_SUP,"MatProduct %s not supported for A %s, B %s and C %s",MatProductTypes[MATPRODUCT_ABC],((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); 9997 ierr = MatProductSymbolic(*D);CHKERRQ(ierr); 9998 } else { /* user may change input matrices when REUSE */ 9999 ierr = MatProductReplaceMats(A,B,C,*D);CHKERRQ(ierr); 10000 } 10001 ierr = MatProductNumeric(*D);CHKERRQ(ierr); 10002 PetscFunctionReturn(0); 10003 } 10004 10005 /*@ 10006 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 10007 10008 Collective on Mat 10009 10010 Input Parameters: 10011 + mat - the matrix 10012 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10013 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10014 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10015 10016 Output Parameter: 10017 . matredundant - redundant matrix 10018 10019 Notes: 10020 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10021 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10022 10023 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10024 calling it. 10025 10026 Level: advanced 10027 10028 .seealso: MatDestroy() 10029 @*/ 10030 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10031 { 10032 PetscErrorCode ierr; 10033 MPI_Comm comm; 10034 PetscMPIInt size; 10035 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10036 Mat_Redundant *redund=NULL; 10037 PetscSubcomm psubcomm=NULL; 10038 MPI_Comm subcomm_in=subcomm; 10039 Mat *matseq; 10040 IS isrow,iscol; 10041 PetscBool newsubcomm=PETSC_FALSE; 10042 10043 PetscFunctionBegin; 10044 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10045 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10046 PetscValidPointer(*matredundant,5); 10047 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10048 } 10049 10050 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 10051 if (size == 1 || nsubcomm == 1) { 10052 if (reuse == MAT_INITIAL_MATRIX) { 10053 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10054 } else { 10055 PetscCheckFalse(*matredundant == mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10056 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10057 } 10058 PetscFunctionReturn(0); 10059 } 10060 10061 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10062 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10063 MatCheckPreallocated(mat,1); 10064 10065 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10066 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10067 /* create psubcomm, then get subcomm */ 10068 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10069 ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 10070 PetscCheckFalse(nsubcomm < 1 || nsubcomm > size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10071 10072 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10073 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10074 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10075 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10076 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10077 newsubcomm = PETSC_TRUE; 10078 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10079 } 10080 10081 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10082 if (reuse == MAT_INITIAL_MATRIX) { 10083 mloc_sub = PETSC_DECIDE; 10084 nloc_sub = PETSC_DECIDE; 10085 if (bs < 1) { 10086 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10087 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10088 } else { 10089 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10090 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10091 } 10092 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRMPI(ierr); 10093 rstart = rend - mloc_sub; 10094 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10095 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10096 } else { /* reuse == MAT_REUSE_MATRIX */ 10097 PetscCheckFalse(*matredundant == mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10098 /* retrieve subcomm */ 10099 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10100 redund = (*matredundant)->redundant; 10101 isrow = redund->isrow; 10102 iscol = redund->iscol; 10103 matseq = redund->matseq; 10104 } 10105 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10106 10107 /* get matredundant over subcomm */ 10108 if (reuse == MAT_INITIAL_MATRIX) { 10109 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10110 10111 /* create a supporting struct and attach it to C for reuse */ 10112 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10113 (*matredundant)->redundant = redund; 10114 redund->isrow = isrow; 10115 redund->iscol = iscol; 10116 redund->matseq = matseq; 10117 if (newsubcomm) { 10118 redund->subcomm = subcomm; 10119 } else { 10120 redund->subcomm = MPI_COMM_NULL; 10121 } 10122 } else { 10123 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10124 } 10125 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10126 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10127 ierr = MatBindToCPU(*matredundant,PETSC_TRUE);CHKERRQ(ierr); 10128 ierr = MatSetBindingPropagates(*matredundant,PETSC_TRUE);CHKERRQ(ierr); 10129 } 10130 #endif 10131 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10132 PetscFunctionReturn(0); 10133 } 10134 10135 /*@C 10136 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10137 a given 'mat' object. Each submatrix can span multiple procs. 10138 10139 Collective on Mat 10140 10141 Input Parameters: 10142 + mat - the matrix 10143 . subcomm - the subcommunicator obtained by com_split(comm) 10144 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10145 10146 Output Parameter: 10147 . subMat - 'parallel submatrices each spans a given subcomm 10148 10149 Notes: 10150 The submatrix partition across processors is dictated by 'subComm' a 10151 communicator obtained by com_split(comm). The comm_split 10152 is not restriced to be grouped with consecutive original ranks. 10153 10154 Due the comm_split() usage, the parallel layout of the submatrices 10155 map directly to the layout of the original matrix [wrt the local 10156 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10157 into the 'DiagonalMat' of the subMat, hence it is used directly from 10158 the subMat. However the offDiagMat looses some columns - and this is 10159 reconstructed with MatSetValues() 10160 10161 Level: advanced 10162 10163 .seealso: MatCreateSubMatrices() 10164 @*/ 10165 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10166 { 10167 PetscErrorCode ierr; 10168 PetscMPIInt commsize,subCommSize; 10169 10170 PetscFunctionBegin; 10171 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRMPI(ierr); 10172 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRMPI(ierr); 10173 PetscCheckFalse(subCommSize > commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10174 10175 PetscCheckFalse(scall == MAT_REUSE_MATRIX && *subMat == mat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10176 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10177 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10178 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10179 PetscFunctionReturn(0); 10180 } 10181 10182 /*@ 10183 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10184 10185 Not Collective 10186 10187 Input Parameters: 10188 + mat - matrix to extract local submatrix from 10189 . isrow - local row indices for submatrix 10190 - iscol - local column indices for submatrix 10191 10192 Output Parameter: 10193 . submat - the submatrix 10194 10195 Level: intermediate 10196 10197 Notes: 10198 The submat should be returned with MatRestoreLocalSubMatrix(). 10199 10200 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10201 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10202 10203 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10204 MatSetValuesBlockedLocal() will also be implemented. 10205 10206 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10207 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10208 10209 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10210 @*/ 10211 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10212 { 10213 PetscErrorCode ierr; 10214 10215 PetscFunctionBegin; 10216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10217 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10218 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10219 PetscCheckSameComm(isrow,2,iscol,3); 10220 PetscValidPointer(submat,4); 10221 PetscCheckFalse(!mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10222 10223 if (mat->ops->getlocalsubmatrix) { 10224 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10225 } else { 10226 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10227 } 10228 PetscFunctionReturn(0); 10229 } 10230 10231 /*@ 10232 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10233 10234 Not Collective 10235 10236 Input Parameters: 10237 + mat - matrix to extract local submatrix from 10238 . isrow - local row indices for submatrix 10239 . iscol - local column indices for submatrix 10240 - submat - the submatrix 10241 10242 Level: intermediate 10243 10244 .seealso: MatGetLocalSubMatrix() 10245 @*/ 10246 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10247 { 10248 PetscErrorCode ierr; 10249 10250 PetscFunctionBegin; 10251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10252 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10253 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10254 PetscCheckSameComm(isrow,2,iscol,3); 10255 PetscValidPointer(submat,4); 10256 if (*submat) { 10257 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10258 } 10259 10260 if (mat->ops->restorelocalsubmatrix) { 10261 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10262 } else { 10263 ierr = MatDestroy(submat);CHKERRQ(ierr); 10264 } 10265 *submat = NULL; 10266 PetscFunctionReturn(0); 10267 } 10268 10269 /* --------------------------------------------------------*/ 10270 /*@ 10271 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10272 10273 Collective on Mat 10274 10275 Input Parameter: 10276 . mat - the matrix 10277 10278 Output Parameter: 10279 . is - if any rows have zero diagonals this contains the list of them 10280 10281 Level: developer 10282 10283 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10284 @*/ 10285 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10286 { 10287 PetscErrorCode ierr; 10288 10289 PetscFunctionBegin; 10290 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10291 PetscValidType(mat,1); 10292 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10293 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10294 10295 if (!mat->ops->findzerodiagonals) { 10296 Vec diag; 10297 const PetscScalar *a; 10298 PetscInt *rows; 10299 PetscInt rStart, rEnd, r, nrow = 0; 10300 10301 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10302 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10303 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10304 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10305 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10306 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10307 nrow = 0; 10308 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10309 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10310 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10311 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10312 } else { 10313 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10314 } 10315 PetscFunctionReturn(0); 10316 } 10317 10318 /*@ 10319 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10320 10321 Collective on Mat 10322 10323 Input Parameter: 10324 . mat - the matrix 10325 10326 Output Parameter: 10327 . is - contains the list of rows with off block diagonal entries 10328 10329 Level: developer 10330 10331 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10332 @*/ 10333 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10334 { 10335 PetscErrorCode ierr; 10336 10337 PetscFunctionBegin; 10338 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10339 PetscValidType(mat,1); 10340 PetscCheckFalse(!mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10341 PetscCheckFalse(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10342 10343 PetscCheckFalse(!mat->ops->findoffblockdiagonalentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name); 10344 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10345 PetscFunctionReturn(0); 10346 } 10347 10348 /*@C 10349 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10350 10351 Collective on Mat 10352 10353 Input Parameters: 10354 . mat - the matrix 10355 10356 Output Parameters: 10357 . values - the block inverses in column major order (FORTRAN-like) 10358 10359 Note: 10360 The size of the blocks is determined by the block size of the matrix. 10361 10362 Fortran Note: 10363 This routine is not available from Fortran. 10364 10365 Level: advanced 10366 10367 .seealso: MatInvertBockDiagonalMat() 10368 @*/ 10369 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10370 { 10371 PetscErrorCode ierr; 10372 10373 PetscFunctionBegin; 10374 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10375 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10376 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10377 PetscCheckFalse(!mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10378 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10379 PetscFunctionReturn(0); 10380 } 10381 10382 /*@C 10383 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10384 10385 Collective on Mat 10386 10387 Input Parameters: 10388 + mat - the matrix 10389 . nblocks - the number of blocks 10390 - bsizes - the size of each block 10391 10392 Output Parameters: 10393 . values - the block inverses in column major order (FORTRAN-like) 10394 10395 Note: 10396 This routine is not available from Fortran. 10397 10398 Level: advanced 10399 10400 .seealso: MatInvertBockDiagonal() 10401 @*/ 10402 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10403 { 10404 PetscErrorCode ierr; 10405 10406 PetscFunctionBegin; 10407 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10408 PetscCheckFalse(!mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10409 PetscCheckFalse(mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10410 PetscCheckFalse(!mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10411 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10412 PetscFunctionReturn(0); 10413 } 10414 10415 /*@ 10416 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10417 10418 Collective on Mat 10419 10420 Input Parameters: 10421 . A - the matrix 10422 10423 Output Parameters: 10424 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10425 10426 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10427 10428 Level: advanced 10429 10430 .seealso: MatInvertBockDiagonal() 10431 @*/ 10432 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10433 { 10434 PetscErrorCode ierr; 10435 const PetscScalar *vals; 10436 PetscInt *dnnz; 10437 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10438 10439 PetscFunctionBegin; 10440 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10441 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10442 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10443 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10444 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10445 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10446 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10447 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10448 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10449 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10450 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10451 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10452 for (i = rstart/bs; i < rend/bs; i++) { 10453 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10454 } 10455 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10456 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10457 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10458 PetscFunctionReturn(0); 10459 } 10460 10461 /*@C 10462 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10463 via MatTransposeColoringCreate(). 10464 10465 Collective on MatTransposeColoring 10466 10467 Input Parameter: 10468 . c - coloring context 10469 10470 Level: intermediate 10471 10472 .seealso: MatTransposeColoringCreate() 10473 @*/ 10474 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10475 { 10476 PetscErrorCode ierr; 10477 MatTransposeColoring matcolor=*c; 10478 10479 PetscFunctionBegin; 10480 if (!matcolor) PetscFunctionReturn(0); 10481 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10482 10483 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10484 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10485 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10486 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10487 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10488 if (matcolor->brows>0) { 10489 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10490 } 10491 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10492 PetscFunctionReturn(0); 10493 } 10494 10495 /*@C 10496 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10497 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10498 MatTransposeColoring to sparse B. 10499 10500 Collective on MatTransposeColoring 10501 10502 Input Parameters: 10503 + B - sparse matrix B 10504 . Btdense - symbolic dense matrix B^T 10505 - coloring - coloring context created with MatTransposeColoringCreate() 10506 10507 Output Parameter: 10508 . Btdense - dense matrix B^T 10509 10510 Level: advanced 10511 10512 Notes: 10513 These are used internally for some implementations of MatRARt() 10514 10515 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10516 10517 @*/ 10518 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10519 { 10520 PetscErrorCode ierr; 10521 10522 PetscFunctionBegin; 10523 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10524 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10525 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10526 10527 PetscCheckFalse(!B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10528 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10529 PetscFunctionReturn(0); 10530 } 10531 10532 /*@C 10533 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10534 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10535 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10536 Csp from Cden. 10537 10538 Collective on MatTransposeColoring 10539 10540 Input Parameters: 10541 + coloring - coloring context created with MatTransposeColoringCreate() 10542 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10543 10544 Output Parameter: 10545 . Csp - sparse matrix 10546 10547 Level: advanced 10548 10549 Notes: 10550 These are used internally for some implementations of MatRARt() 10551 10552 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10553 10554 @*/ 10555 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10556 { 10557 PetscErrorCode ierr; 10558 10559 PetscFunctionBegin; 10560 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10561 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10562 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10563 10564 PetscCheckFalse(!Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10565 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10566 ierr = MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10567 ierr = MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10568 PetscFunctionReturn(0); 10569 } 10570 10571 /*@C 10572 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10573 10574 Collective on Mat 10575 10576 Input Parameters: 10577 + mat - the matrix product C 10578 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10579 10580 Output Parameter: 10581 . color - the new coloring context 10582 10583 Level: intermediate 10584 10585 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10586 MatTransColoringApplyDenToSp() 10587 @*/ 10588 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10589 { 10590 MatTransposeColoring c; 10591 MPI_Comm comm; 10592 PetscErrorCode ierr; 10593 10594 PetscFunctionBegin; 10595 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10596 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10597 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10598 10599 c->ctype = iscoloring->ctype; 10600 if (mat->ops->transposecoloringcreate) { 10601 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10602 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10603 10604 *color = c; 10605 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10606 PetscFunctionReturn(0); 10607 } 10608 10609 /*@ 10610 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10611 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10612 same, otherwise it will be larger 10613 10614 Not Collective 10615 10616 Input Parameter: 10617 . A - the matrix 10618 10619 Output Parameter: 10620 . state - the current state 10621 10622 Notes: 10623 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10624 different matrices 10625 10626 Level: intermediate 10627 10628 @*/ 10629 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10630 { 10631 PetscFunctionBegin; 10632 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10633 *state = mat->nonzerostate; 10634 PetscFunctionReturn(0); 10635 } 10636 10637 /*@ 10638 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10639 matrices from each processor 10640 10641 Collective 10642 10643 Input Parameters: 10644 + comm - the communicators the parallel matrix will live on 10645 . seqmat - the input sequential matrices 10646 . n - number of local columns (or PETSC_DECIDE) 10647 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10648 10649 Output Parameter: 10650 . mpimat - the parallel matrix generated 10651 10652 Level: advanced 10653 10654 Notes: 10655 The number of columns of the matrix in EACH processor MUST be the same. 10656 10657 @*/ 10658 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10659 { 10660 PetscErrorCode ierr; 10661 10662 PetscFunctionBegin; 10663 PetscCheckFalse(!seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10664 PetscCheckFalse(reuse == MAT_REUSE_MATRIX && seqmat == *mpimat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10665 10666 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10667 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10668 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10669 PetscFunctionReturn(0); 10670 } 10671 10672 /*@ 10673 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10674 ranks' ownership ranges. 10675 10676 Collective on A 10677 10678 Input Parameters: 10679 + A - the matrix to create subdomains from 10680 - N - requested number of subdomains 10681 10682 Output Parameters: 10683 + n - number of subdomains resulting on this rank 10684 - iss - IS list with indices of subdomains on this rank 10685 10686 Level: advanced 10687 10688 Notes: 10689 number of subdomains must be smaller than the communicator size 10690 @*/ 10691 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10692 { 10693 MPI_Comm comm,subcomm; 10694 PetscMPIInt size,rank,color; 10695 PetscInt rstart,rend,k; 10696 PetscErrorCode ierr; 10697 10698 PetscFunctionBegin; 10699 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10700 ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 10701 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 10702 PetscCheck(N >= 1 && N < (PetscInt)size,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %d, got N = %" PetscInt_FMT,size,N); 10703 *n = 1; 10704 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10705 color = rank/k; 10706 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRMPI(ierr); 10707 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10708 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10709 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10710 ierr = MPI_Comm_free(&subcomm);CHKERRMPI(ierr); 10711 PetscFunctionReturn(0); 10712 } 10713 10714 /*@ 10715 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10716 10717 If the interpolation and restriction operators are the same, uses MatPtAP. 10718 If they are not the same, use MatMatMatMult. 10719 10720 Once the coarse grid problem is constructed, correct for interpolation operators 10721 that are not of full rank, which can legitimately happen in the case of non-nested 10722 geometric multigrid. 10723 10724 Input Parameters: 10725 + restrct - restriction operator 10726 . dA - fine grid matrix 10727 . interpolate - interpolation operator 10728 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10729 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10730 10731 Output Parameters: 10732 . A - the Galerkin coarse matrix 10733 10734 Options Database Key: 10735 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10736 10737 Level: developer 10738 10739 .seealso: MatPtAP(), MatMatMatMult() 10740 @*/ 10741 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10742 { 10743 PetscErrorCode ierr; 10744 IS zerorows; 10745 Vec diag; 10746 10747 PetscFunctionBegin; 10748 PetscCheckFalse(reuse == MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10749 /* Construct the coarse grid matrix */ 10750 if (interpolate == restrct) { 10751 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10752 } else { 10753 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10754 } 10755 10756 /* If the interpolation matrix is not of full rank, A will have zero rows. 10757 This can legitimately happen in the case of non-nested geometric multigrid. 10758 In that event, we set the rows of the matrix to the rows of the identity, 10759 ignoring the equations (as the RHS will also be zero). */ 10760 10761 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10762 10763 if (zerorows != NULL) { /* if there are any zero rows */ 10764 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10765 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10766 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10767 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10768 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10769 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10770 } 10771 PetscFunctionReturn(0); 10772 } 10773 10774 /*@C 10775 MatSetOperation - Allows user to set a matrix operation for any matrix type 10776 10777 Logically Collective on Mat 10778 10779 Input Parameters: 10780 + mat - the matrix 10781 . op - the name of the operation 10782 - f - the function that provides the operation 10783 10784 Level: developer 10785 10786 Usage: 10787 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10788 $ ierr = MatCreateXXX(comm,...&A); 10789 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10790 10791 Notes: 10792 See the file include/petscmat.h for a complete list of matrix 10793 operations, which all have the form MATOP_<OPERATION>, where 10794 <OPERATION> is the name (in all capital letters) of the 10795 user interface routine (e.g., MatMult() -> MATOP_MULT). 10796 10797 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10798 sequence as the usual matrix interface routines, since they 10799 are intended to be accessed via the usual matrix interface 10800 routines, e.g., 10801 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10802 10803 In particular each function MUST return an error code of 0 on success and 10804 nonzero on failure. 10805 10806 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10807 10808 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10809 @*/ 10810 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10811 { 10812 PetscFunctionBegin; 10813 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10814 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10815 mat->ops->viewnative = mat->ops->view; 10816 } 10817 (((void(**)(void))mat->ops)[op]) = f; 10818 PetscFunctionReturn(0); 10819 } 10820 10821 /*@C 10822 MatGetOperation - Gets a matrix operation for any matrix type. 10823 10824 Not Collective 10825 10826 Input Parameters: 10827 + mat - the matrix 10828 - op - the name of the operation 10829 10830 Output Parameter: 10831 . f - the function that provides the operation 10832 10833 Level: developer 10834 10835 Usage: 10836 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10837 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10838 10839 Notes: 10840 See the file include/petscmat.h for a complete list of matrix 10841 operations, which all have the form MATOP_<OPERATION>, where 10842 <OPERATION> is the name (in all capital letters) of the 10843 user interface routine (e.g., MatMult() -> MATOP_MULT). 10844 10845 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10846 10847 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10848 @*/ 10849 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10850 { 10851 PetscFunctionBegin; 10852 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10853 *f = (((void (**)(void))mat->ops)[op]); 10854 PetscFunctionReturn(0); 10855 } 10856 10857 /*@ 10858 MatHasOperation - Determines whether the given matrix supports the particular 10859 operation. 10860 10861 Not Collective 10862 10863 Input Parameters: 10864 + mat - the matrix 10865 - op - the operation, for example, MATOP_GET_DIAGONAL 10866 10867 Output Parameter: 10868 . has - either PETSC_TRUE or PETSC_FALSE 10869 10870 Level: advanced 10871 10872 Notes: 10873 See the file include/petscmat.h for a complete list of matrix 10874 operations, which all have the form MATOP_<OPERATION>, where 10875 <OPERATION> is the name (in all capital letters) of the 10876 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10877 10878 .seealso: MatCreateShell() 10879 @*/ 10880 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10881 { 10882 PetscErrorCode ierr; 10883 10884 PetscFunctionBegin; 10885 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10886 PetscValidPointer(has,3); 10887 if (mat->ops->hasoperation) { 10888 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10889 } else { 10890 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10891 else { 10892 *has = PETSC_FALSE; 10893 if (op == MATOP_CREATE_SUBMATRIX) { 10894 PetscMPIInt size; 10895 10896 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 10897 if (size == 1) { 10898 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10899 } 10900 } 10901 } 10902 } 10903 PetscFunctionReturn(0); 10904 } 10905 10906 /*@ 10907 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10908 of the matrix are congruent 10909 10910 Collective on mat 10911 10912 Input Parameters: 10913 . mat - the matrix 10914 10915 Output Parameter: 10916 . cong - either PETSC_TRUE or PETSC_FALSE 10917 10918 Level: beginner 10919 10920 Notes: 10921 10922 .seealso: MatCreate(), MatSetSizes() 10923 @*/ 10924 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10925 { 10926 PetscErrorCode ierr; 10927 10928 PetscFunctionBegin; 10929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10930 PetscValidType(mat,1); 10931 PetscValidPointer(cong,2); 10932 if (!mat->rmap || !mat->cmap) { 10933 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10934 PetscFunctionReturn(0); 10935 } 10936 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10937 ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 10938 ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 10939 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10940 if (*cong) mat->congruentlayouts = 1; 10941 else mat->congruentlayouts = 0; 10942 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10943 PetscFunctionReturn(0); 10944 } 10945 10946 PetscErrorCode MatSetInf(Mat A) 10947 { 10948 PetscErrorCode ierr; 10949 10950 PetscFunctionBegin; 10951 PetscCheckFalse(!A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10952 ierr = (*A->ops->setinf)(A);CHKERRQ(ierr); 10953 PetscFunctionReturn(0); 10954 } 10955