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