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