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