1 #define PETSCMAT_DLL 2 3 /* 4 Defines the basic matrix operations for sequential dense. 5 */ 6 7 #include "src/mat/impls/dense/seq/dense.h" 8 #include "petscblaslapack.h" 9 10 #undef __FUNCT__ 11 #define __FUNCT__ "MatAXPY_SeqDense" 12 PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str) 13 { 14 Mat_SeqDense *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data; 15 PetscScalar oalpha = alpha; 16 PetscInt j; 17 PetscBLASInt N,m,ldax,lday,one = 1; 18 PetscErrorCode ierr; 19 20 PetscFunctionBegin; 21 N = PetscBLASIntCast(X->rmap->n*X->cmap->n); 22 m = PetscBLASIntCast(X->rmap->n); 23 ldax = PetscBLASIntCast(x->lda); 24 lday = PetscBLASIntCast(y->lda); 25 if (ldax>m || lday>m) { 26 for (j=0; j<X->cmap->n; j++) { 27 BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one); 28 } 29 } else { 30 BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one); 31 } 32 ierr = PetscLogFlops(2*N-1);CHKERRQ(ierr); 33 PetscFunctionReturn(0); 34 } 35 36 #undef __FUNCT__ 37 #define __FUNCT__ "MatGetInfo_SeqDense" 38 PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info) 39 { 40 PetscInt N = A->rmap->n*A->cmap->n; 41 42 PetscFunctionBegin; 43 info->rows_global = (double)A->rmap->n; 44 info->columns_global = (double)A->cmap->n; 45 info->rows_local = (double)A->rmap->n; 46 info->columns_local = (double)A->cmap->n; 47 info->block_size = 1.0; 48 info->nz_allocated = (double)N; 49 info->nz_used = (double)N; 50 info->nz_unneeded = (double)0; 51 info->assemblies = (double)A->num_ass; 52 info->mallocs = 0; 53 info->memory = ((PetscObject)A)->mem; 54 info->fill_ratio_given = 0; 55 info->fill_ratio_needed = 0; 56 info->factor_mallocs = 0; 57 PetscFunctionReturn(0); 58 } 59 60 #undef __FUNCT__ 61 #define __FUNCT__ "MatScale_SeqDense" 62 PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha) 63 { 64 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 65 PetscScalar oalpha = alpha; 66 PetscErrorCode ierr; 67 PetscBLASInt one = 1,j,nz,lda = PetscBLASIntCast(a->lda); 68 69 PetscFunctionBegin; 70 if (lda>A->rmap->n) { 71 nz = PetscBLASIntCast(A->rmap->n); 72 for (j=0; j<A->cmap->n; j++) { 73 BLASscal_(&nz,&oalpha,a->v+j*lda,&one); 74 } 75 } else { 76 nz = PetscBLASIntCast(A->rmap->n*A->cmap->n); 77 BLASscal_(&nz,&oalpha,a->v,&one); 78 } 79 ierr = PetscLogFlops(nz);CHKERRQ(ierr); 80 PetscFunctionReturn(0); 81 } 82 83 #undef __FUNCT__ 84 #define __FUNCT__ "MatIsHermitian_SeqDense" 85 PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscTruth *fl) 86 { 87 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 88 PetscInt i,j,m = A->rmap->n,N; 89 PetscScalar *v = a->v; 90 91 PetscFunctionBegin; 92 *fl = PETSC_FALSE; 93 if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 94 N = a->lda; 95 96 for (i=0; i<m; i++) { 97 for (j=i+1; j<m; j++) { 98 if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0); 99 } 100 } 101 *fl = PETSC_TRUE; 102 PetscFunctionReturn(0); 103 } 104 105 #undef __FUNCT__ 106 #define __FUNCT__ "MatDuplicateNoCreate_SeqDense" 107 PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues) 108 { 109 Mat_SeqDense *mat = (Mat_SeqDense*)A->data,*l; 110 PetscErrorCode ierr; 111 PetscInt lda = (PetscInt)mat->lda,j,m; 112 113 PetscFunctionBegin; 114 ierr = MatSeqDenseSetPreallocation(newi,PETSC_NULL);CHKERRQ(ierr); 115 if (cpvalues == MAT_COPY_VALUES) { 116 l = (Mat_SeqDense*)newi->data; 117 if (lda>A->rmap->n) { 118 m = A->rmap->n; 119 for (j=0; j<A->cmap->n; j++) { 120 ierr = PetscMemcpy(l->v+j*m,mat->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr); 121 } 122 } else { 123 ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 124 } 125 } 126 newi->assembled = PETSC_TRUE; 127 PetscFunctionReturn(0); 128 } 129 130 #undef __FUNCT__ 131 #define __FUNCT__ "MatDuplicate_SeqDense" 132 PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat) 133 { 134 PetscErrorCode ierr; 135 136 PetscFunctionBegin; 137 ierr = MatCreate(((PetscObject)A)->comm,newmat);CHKERRQ(ierr); 138 ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 139 ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 140 ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr); 141 PetscFunctionReturn(0); 142 } 143 144 145 extern PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,MatFactorInfo*); 146 147 #undef __FUNCT__ 148 #define __FUNCT__ "MatLUFactorNumeric_SeqDense" 149 PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,MatFactorInfo *info_dummy) 150 { 151 Mat_SeqDense *mat = (Mat_SeqDense*)A->data,*l = (Mat_SeqDense*)fact->data; 152 PetscErrorCode ierr; 153 MatFactorInfo info; 154 155 PetscFunctionBegin; 156 /* copy the numerical values */ 157 if (lda1>m || lda2>m ) { 158 for (j=0; j<n; j++) { 159 ierr = PetscMemcpy(l->v+j*lda2,mat->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr); 160 } 161 } else { 162 ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 163 } 164 ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr); 165 PetscFunctionReturn(0); 166 } 167 168 #undef __FUNCT__ 169 #define __FUNCT__ "MatSolve_SeqDense" 170 PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy) 171 { 172 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 173 PetscErrorCode ierr; 174 PetscScalar *x,*y; 175 PetscBLASInt one = 1,info,m = PetscBLASIntCast(A->rmap->n); 176 177 PetscFunctionBegin; 178 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 179 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 180 ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 181 if (A->factor == MAT_FACTOR_LU) { 182 #if defined(PETSC_MISSING_LAPACK_GETRS) 183 SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 184 #else 185 LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info); 186 if (info) SETERRQ(PETSC_ERR_LIB,"GETRS - Bad solve"); 187 #endif 188 } else if (A->factor == MAT_FACTOR_CHOLESKY){ 189 #if defined(PETSC_MISSING_LAPACK_POTRS) 190 SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 191 #else 192 LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info); 193 if (info) SETERRQ(PETSC_ERR_LIB,"POTRS Bad solve"); 194 #endif 195 } 196 else SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 197 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 198 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 199 ierr = PetscLogFlops(2*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 200 PetscFunctionReturn(0); 201 } 202 203 #undef __FUNCT__ 204 #define __FUNCT__ "MatSolveTranspose_SeqDense" 205 PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy) 206 { 207 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 208 PetscErrorCode ierr; 209 PetscScalar *x,*y; 210 PetscBLASInt one = 1,info,m = PetscBLASIntCast(A->rmap->n); 211 212 PetscFunctionBegin; 213 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 214 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 215 ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 216 /* assume if pivots exist then use LU; else Cholesky */ 217 if (mat->pivots) { 218 #if defined(PETSC_MISSING_LAPACK_GETRS) 219 SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 220 #else 221 LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info); 222 if (info) SETERRQ(PETSC_ERR_LIB,"POTRS - Bad solve"); 223 #endif 224 } else { 225 #if defined(PETSC_MISSING_LAPACK_POTRS) 226 SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 227 #else 228 LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info); 229 if (info) SETERRQ(PETSC_ERR_LIB,"POTRS - Bad solve"); 230 #endif 231 } 232 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 233 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 234 ierr = PetscLogFlops(2*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 235 PetscFunctionReturn(0); 236 } 237 238 #undef __FUNCT__ 239 #define __FUNCT__ "MatSolveAdd_SeqDense" 240 PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 241 { 242 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 243 PetscErrorCode ierr; 244 PetscScalar *x,*y,sone = 1.0; 245 Vec tmp = 0; 246 PetscBLASInt one = 1,info,m = PetscBLASIntCast(A->rmap->n); 247 248 PetscFunctionBegin; 249 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 250 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 251 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 252 if (yy == zz) { 253 ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 254 ierr = PetscLogObjectParent(A,tmp);CHKERRQ(ierr); 255 ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 256 } 257 ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 258 /* assume if pivots exist then use LU; else Cholesky */ 259 if (mat->pivots) { 260 #if defined(PETSC_MISSING_LAPACK_GETRS) 261 SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 262 #else 263 LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info); 264 if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve"); 265 #endif 266 } else { 267 #if defined(PETSC_MISSING_LAPACK_POTRS) 268 SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 269 #else 270 LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info); 271 if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve"); 272 #endif 273 } 274 if (tmp) {ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr); ierr = VecDestroy(tmp);CHKERRQ(ierr);} 275 else {ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);} 276 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 277 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 278 ierr = PetscLogFlops(2*A->cmap->n*A->cmap->n);CHKERRQ(ierr); 279 PetscFunctionReturn(0); 280 } 281 282 #undef __FUNCT__ 283 #define __FUNCT__ "MatSolveTransposeAdd_SeqDense" 284 PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 285 { 286 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 287 PetscErrorCode ierr; 288 PetscScalar *x,*y,sone = 1.0; 289 Vec tmp; 290 PetscBLASInt one = 1,info,m = PetscBLASIntCast(A->rmap->n); 291 292 PetscFunctionBegin; 293 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 294 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 295 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 296 if (yy == zz) { 297 ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 298 ierr = PetscLogObjectParent(A,tmp);CHKERRQ(ierr); 299 ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 300 } 301 ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 302 /* assume if pivots exist then use LU; else Cholesky */ 303 if (mat->pivots) { 304 #if defined(PETSC_MISSING_LAPACK_GETRS) 305 SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 306 #else 307 LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info); 308 if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve"); 309 #endif 310 } else { 311 #if defined(PETSC_MISSING_LAPACK_POTRS) 312 SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 313 #else 314 LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info); 315 if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve"); 316 #endif 317 } 318 if (tmp) { 319 ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr); 320 ierr = VecDestroy(tmp);CHKERRQ(ierr); 321 } else { 322 ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr); 323 } 324 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 325 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 326 ierr = PetscLogFlops(2*A->cmap->n*A->cmap->n);CHKERRQ(ierr); 327 PetscFunctionReturn(0); 328 } 329 330 /* ---------------------------------------------------------------*/ 331 /* COMMENT: I have chosen to hide row permutation in the pivots, 332 rather than put it in the Mat->row slot.*/ 333 #undef __FUNCT__ 334 #define __FUNCT__ "MatLUFactor_SeqDense" 335 PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,MatFactorInfo *minfo) 336 { 337 #if defined(PETSC_MISSING_LAPACK_GETRF) 338 PetscFunctionBegin; 339 SETERRQ(PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable."); 340 #else 341 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 342 PetscErrorCode ierr; 343 PetscBLASInt n,m,info; 344 345 PetscFunctionBegin; 346 n = PetscBLASIntCast(A->cmap->n); 347 m = PetscBLASIntCast(A->rmap->n); 348 if (!mat->pivots) { 349 ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscBLASInt),&mat->pivots);CHKERRQ(ierr); 350 ierr = PetscLogObjectMemory(A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr); 351 } 352 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 353 LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info); 354 if (info<0) SETERRQ(PETSC_ERR_LIB,"Bad argument to LU factorization"); 355 if (info>0) SETERRQ(PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization"); 356 A->ops->solve = MatSolve_SeqDense; 357 A->ops->solvetranspose = MatSolveTranspose_SeqDense; 358 A->ops->solveadd = MatSolveAdd_SeqDense; 359 A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 360 A->factor = MAT_FACTOR_LU; 361 362 ierr = PetscLogFlops((2*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr); 363 #endif 364 PetscFunctionReturn(0); 365 } 366 367 #undef __FUNCT__ 368 #define __FUNCT__ "MatCholeskyFactor_SeqDense" 369 PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,MatFactorInfo *factinfo) 370 { 371 #if defined(PETSC_MISSING_LAPACK_POTRF) 372 PetscFunctionBegin; 373 SETERRQ(PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable."); 374 #else 375 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 376 PetscErrorCode ierr; 377 PetscBLASInt info,n = PetscBLASIntCast(A->cmap->n); 378 379 PetscFunctionBegin; 380 ierr = PetscFree(mat->pivots);CHKERRQ(ierr); 381 mat->pivots = 0; 382 383 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 384 LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info); 385 if (info) SETERRQ1(PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1); 386 A->ops->solve = MatSolve_SeqDense; 387 A->ops->solvetranspose = MatSolveTranspose_SeqDense; 388 A->ops->solveadd = MatSolveAdd_SeqDense; 389 A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 390 A->factor = MAT_FACTOR_CHOLESKY; 391 ierr = PetscLogFlops((A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr); 392 #endif 393 PetscFunctionReturn(0); 394 } 395 396 397 #undef __FUNCT__ 398 #define __FUNCT__ "MatCholeskyFactorNumeric_SeqDense" 399 PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,MatFactorInfo *info_dummy) 400 { 401 PetscErrorCode ierr; 402 MatFactorInfo info; 403 404 PetscFunctionBegin; 405 info.fill = 1.0; 406 ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr); 407 PetscFunctionReturn(0); 408 } 409 410 #undef __FUNCT__ 411 #define __FUNCT__ "MatCholeskyFactorSymbolic_SeqDense" 412 PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,MatFactorInfo *info) 413 { 414 PetscFunctionBegin; 415 ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr); 416 fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 417 PetscFunctionReturn(0); 418 } 419 420 #undef __FUNCT__ 421 #define __FUNCT__ "MatLUFactorSymbolic_SeqDense" 422 PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,MatFactorInfo *info) 423 { 424 PetscFunctionBegin; 425 ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_DO_NOT_COPY_VALUES);CHKERRQ(ierr); 426 fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 427 PetscFunctionReturn(0); 428 } 429 430 #undef __FUNCT__ 431 #define __FUNCT__ "MatGetFactor_seqdense_petsc" 432 PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact) 433 { 434 PetscErrorCode ierr; 435 436 PetscFunctionBegin; 437 ierr = MatCreate(((PetscObject)A)->comm,fact);CHKERRQ(ierr); 438 ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 439 ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr); 440 if (ftype == MAT_FACTOR_LU){ 441 (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 442 } else { 443 (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 444 } 445 (*fact)->factor = ftype; 446 PetscFunctionReturn(0); 447 } 448 449 /* ------------------------------------------------------------------*/ 450 #undef __FUNCT__ 451 #define __FUNCT__ "MatRelax_SeqDense" 452 PetscErrorCode MatRelax_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx) 453 { 454 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 455 PetscScalar *x,*b,*v = mat->v,zero = 0.0,xt; 456 PetscErrorCode ierr; 457 PetscInt m = A->rmap->n,i; 458 #if !defined(PETSC_USE_COMPLEX) 459 PetscBLASInt o = 1,bm = PetscBLASIntCast(m); 460 #endif 461 462 PetscFunctionBegin; 463 if (flag & SOR_ZERO_INITIAL_GUESS) { 464 /* this is a hack fix, should have another version without the second BLASdot */ 465 ierr = VecSet(xx,zero);CHKERRQ(ierr); 466 } 467 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 468 ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 469 its = its*lits; 470 if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 471 while (its--) { 472 if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 473 for (i=0; i<m; i++) { 474 #if defined(PETSC_USE_COMPLEX) 475 /* cannot use BLAS dot for complex because compiler/linker is 476 not happy about returning a double complex */ 477 PetscInt _i; 478 PetscScalar sum = b[i]; 479 for (_i=0; _i<m; _i++) { 480 sum -= PetscConj(v[i+_i*m])*x[_i]; 481 } 482 xt = sum; 483 #else 484 xt = b[i] - BLASdot_(&bm,v+i,&bm,x,&o); 485 #endif 486 x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 487 } 488 } 489 if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 490 for (i=m-1; i>=0; i--) { 491 #if defined(PETSC_USE_COMPLEX) 492 /* cannot use BLAS dot for complex because compiler/linker is 493 not happy about returning a double complex */ 494 PetscInt _i; 495 PetscScalar sum = b[i]; 496 for (_i=0; _i<m; _i++) { 497 sum -= PetscConj(v[i+_i*m])*x[_i]; 498 } 499 xt = sum; 500 #else 501 xt = b[i] - BLASdot_(&bm,v+i,&bm,x,&o); 502 #endif 503 x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 504 } 505 } 506 } 507 ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr); 508 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 509 PetscFunctionReturn(0); 510 } 511 512 /* -----------------------------------------------------------------*/ 513 #undef __FUNCT__ 514 #define __FUNCT__ "MatMultTranspose_SeqDense" 515 PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy) 516 { 517 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 518 PetscScalar *v = mat->v,*x,*y; 519 PetscErrorCode ierr; 520 PetscBLASInt m, n,_One=1; 521 PetscScalar _DOne=1.0,_DZero=0.0; 522 523 PetscFunctionBegin; 524 m = PetscBLASIntCast(A->rmap->n); 525 n = PetscBLASIntCast(A->cmap->n); 526 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 527 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 528 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 529 BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One); 530 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 531 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 532 ierr = PetscLogFlops(2*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 533 PetscFunctionReturn(0); 534 } 535 536 #undef __FUNCT__ 537 #define __FUNCT__ "MatMult_SeqDense" 538 PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy) 539 { 540 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 541 PetscScalar *v = mat->v,*x,*y,_DOne=1.0,_DZero=0.0; 542 PetscErrorCode ierr; 543 PetscBLASInt m, n, _One=1; 544 545 PetscFunctionBegin; 546 m = PetscBLASIntCast(A->rmap->n); 547 n = PetscBLASIntCast(A->cmap->n); 548 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 549 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 550 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 551 BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One); 552 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 553 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 554 ierr = PetscLogFlops(2*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr); 555 PetscFunctionReturn(0); 556 } 557 558 #undef __FUNCT__ 559 #define __FUNCT__ "MatMultAdd_SeqDense" 560 PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 561 { 562 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 563 PetscScalar *v = mat->v,*x,*y,_DOne=1.0; 564 PetscErrorCode ierr; 565 PetscBLASInt m, n, _One=1; 566 567 PetscFunctionBegin; 568 m = PetscBLASIntCast(A->rmap->n); 569 n = PetscBLASIntCast(A->cmap->n); 570 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 571 if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 572 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 573 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 574 BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One); 575 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 576 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 577 ierr = PetscLogFlops(2*A->rmap->n*A->cmap->n);CHKERRQ(ierr); 578 PetscFunctionReturn(0); 579 } 580 581 #undef __FUNCT__ 582 #define __FUNCT__ "MatMultTransposeAdd_SeqDense" 583 PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 584 { 585 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 586 PetscScalar *v = mat->v,*x,*y; 587 PetscErrorCode ierr; 588 PetscBLASInt m, n, _One=1; 589 PetscScalar _DOne=1.0; 590 591 PetscFunctionBegin; 592 m = PetscBLASIntCast(A->rmap->n); 593 n = PetscBLASIntCast(A->cmap->n); 594 if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 595 if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 596 ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 597 ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 598 BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One); 599 ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 600 ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 601 ierr = PetscLogFlops(2*A->rmap->n*A->cmap->n);CHKERRQ(ierr); 602 PetscFunctionReturn(0); 603 } 604 605 /* -----------------------------------------------------------------*/ 606 #undef __FUNCT__ 607 #define __FUNCT__ "MatGetRow_SeqDense" 608 PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 609 { 610 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 611 PetscScalar *v; 612 PetscErrorCode ierr; 613 PetscInt i; 614 615 PetscFunctionBegin; 616 *ncols = A->cmap->n; 617 if (cols) { 618 ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscInt),cols);CHKERRQ(ierr); 619 for (i=0; i<A->cmap->n; i++) (*cols)[i] = i; 620 } 621 if (vals) { 622 ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscScalar),vals);CHKERRQ(ierr); 623 v = mat->v + row; 624 for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;} 625 } 626 PetscFunctionReturn(0); 627 } 628 629 #undef __FUNCT__ 630 #define __FUNCT__ "MatRestoreRow_SeqDense" 631 PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 632 { 633 PetscErrorCode ierr; 634 PetscFunctionBegin; 635 if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);} 636 if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); } 637 PetscFunctionReturn(0); 638 } 639 /* ----------------------------------------------------------------*/ 640 #undef __FUNCT__ 641 #define __FUNCT__ "MatSetValues_SeqDense" 642 PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv) 643 { 644 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 645 PetscInt i,j,idx=0; 646 647 PetscFunctionBegin; 648 if (!mat->roworiented) { 649 if (addv == INSERT_VALUES) { 650 for (j=0; j<n; j++) { 651 if (indexn[j] < 0) {idx += m; continue;} 652 #if defined(PETSC_USE_DEBUG) 653 if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 654 #endif 655 for (i=0; i<m; i++) { 656 if (indexm[i] < 0) {idx++; continue;} 657 #if defined(PETSC_USE_DEBUG) 658 if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 659 #endif 660 mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++]; 661 } 662 } 663 } else { 664 for (j=0; j<n; j++) { 665 if (indexn[j] < 0) {idx += m; continue;} 666 #if defined(PETSC_USE_DEBUG) 667 if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 668 #endif 669 for (i=0; i<m; i++) { 670 if (indexm[i] < 0) {idx++; continue;} 671 #if defined(PETSC_USE_DEBUG) 672 if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 673 #endif 674 mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 675 } 676 } 677 } 678 } else { 679 if (addv == INSERT_VALUES) { 680 for (i=0; i<m; i++) { 681 if (indexm[i] < 0) { idx += n; continue;} 682 #if defined(PETSC_USE_DEBUG) 683 if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 684 #endif 685 for (j=0; j<n; j++) { 686 if (indexn[j] < 0) { idx++; continue;} 687 #if defined(PETSC_USE_DEBUG) 688 if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 689 #endif 690 mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++]; 691 } 692 } 693 } else { 694 for (i=0; i<m; i++) { 695 if (indexm[i] < 0) { idx += n; continue;} 696 #if defined(PETSC_USE_DEBUG) 697 if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 698 #endif 699 for (j=0; j<n; j++) { 700 if (indexn[j] < 0) { idx++; continue;} 701 #if defined(PETSC_USE_DEBUG) 702 if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 703 #endif 704 mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 705 } 706 } 707 } 708 } 709 PetscFunctionReturn(0); 710 } 711 712 #undef __FUNCT__ 713 #define __FUNCT__ "MatGetValues_SeqDense" 714 PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[]) 715 { 716 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 717 PetscInt i,j; 718 719 PetscFunctionBegin; 720 /* row-oriented output */ 721 for (i=0; i<m; i++) { 722 if (indexm[i] < 0) {v += n;continue;} 723 if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested larger than number rows %D",indexm[i],A->rmap->n); 724 for (j=0; j<n; j++) { 725 if (indexn[j] < 0) {v++; continue;} 726 if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column %D requested larger than number columns %D",indexn[j],A->cmap->n); 727 *v++ = mat->v[indexn[j]*mat->lda + indexm[i]]; 728 } 729 } 730 PetscFunctionReturn(0); 731 } 732 733 /* -----------------------------------------------------------------*/ 734 735 #include "petscsys.h" 736 737 #undef __FUNCT__ 738 #define __FUNCT__ "MatLoad_SeqDense" 739 PetscErrorCode MatLoad_SeqDense(PetscViewer viewer, const MatType type,Mat *A) 740 { 741 Mat_SeqDense *a; 742 Mat B; 743 PetscErrorCode ierr; 744 PetscInt *scols,i,j,nz,header[4]; 745 int fd; 746 PetscMPIInt size; 747 PetscInt *rowlengths = 0,M,N,*cols; 748 PetscScalar *vals,*svals,*v,*w; 749 MPI_Comm comm = ((PetscObject)viewer)->comm; 750 751 PetscFunctionBegin; 752 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 753 if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor"); 754 ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 755 ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 756 if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Not matrix object"); 757 M = header[1]; N = header[2]; nz = header[3]; 758 759 if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */ 760 ierr = MatCreate(comm,A);CHKERRQ(ierr); 761 ierr = MatSetSizes(*A,M,N,M,N);CHKERRQ(ierr); 762 ierr = MatSetType(*A,type);CHKERRQ(ierr); 763 ierr = MatSeqDenseSetPreallocation(*A,PETSC_NULL);CHKERRQ(ierr); 764 B = *A; 765 a = (Mat_SeqDense*)B->data; 766 v = a->v; 767 /* Allocate some temp space to read in the values and then flip them 768 from row major to column major */ 769 ierr = PetscMalloc((M*N > 0 ? M*N : 1)*sizeof(PetscScalar),&w);CHKERRQ(ierr); 770 /* read in nonzero values */ 771 ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr); 772 /* now flip the values and store them in the matrix*/ 773 for (j=0; j<N; j++) { 774 for (i=0; i<M; i++) { 775 *v++ =w[i*N+j]; 776 } 777 } 778 ierr = PetscFree(w);CHKERRQ(ierr); 779 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 780 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 781 } else { 782 /* read row lengths */ 783 ierr = PetscMalloc((M+1)*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 784 ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 785 786 /* create our matrix */ 787 ierr = MatCreate(comm,A);CHKERRQ(ierr); 788 ierr = MatSetSizes(*A,M,N,M,N);CHKERRQ(ierr); 789 ierr = MatSetType(*A,type);CHKERRQ(ierr); 790 ierr = MatSeqDenseSetPreallocation(*A,PETSC_NULL);CHKERRQ(ierr); 791 B = *A; 792 a = (Mat_SeqDense*)B->data; 793 v = a->v; 794 795 /* read column indices and nonzeros */ 796 ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&scols);CHKERRQ(ierr); 797 cols = scols; 798 ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr); 799 ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&svals);CHKERRQ(ierr); 800 vals = svals; 801 ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr); 802 803 /* insert into matrix */ 804 for (i=0; i<M; i++) { 805 for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j]; 806 svals += rowlengths[i]; scols += rowlengths[i]; 807 } 808 ierr = PetscFree(vals);CHKERRQ(ierr); 809 ierr = PetscFree(cols);CHKERRQ(ierr); 810 ierr = PetscFree(rowlengths);CHKERRQ(ierr); 811 812 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 813 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 814 } 815 PetscFunctionReturn(0); 816 } 817 818 #include "petscsys.h" 819 820 #undef __FUNCT__ 821 #define __FUNCT__ "MatView_SeqDense_ASCII" 822 static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer) 823 { 824 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 825 PetscErrorCode ierr; 826 PetscInt i,j; 827 const char *name; 828 PetscScalar *v; 829 PetscViewerFormat format; 830 #if defined(PETSC_USE_COMPLEX) 831 PetscTruth allreal = PETSC_TRUE; 832 #endif 833 834 PetscFunctionBegin; 835 ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 836 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 837 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 838 PetscFunctionReturn(0); /* do nothing for now */ 839 } else if (format == PETSC_VIEWER_ASCII_COMMON) { 840 ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 841 for (i=0; i<A->rmap->n; i++) { 842 v = a->v + i; 843 ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 844 for (j=0; j<A->cmap->n; j++) { 845 #if defined(PETSC_USE_COMPLEX) 846 if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 847 ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i) ",j,PetscRealPart(*v),PetscImaginaryPart(*v));CHKERRQ(ierr); 848 } else if (PetscRealPart(*v)) { 849 ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",j,PetscRealPart(*v));CHKERRQ(ierr); 850 } 851 #else 852 if (*v) { 853 ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",j,*v);CHKERRQ(ierr); 854 } 855 #endif 856 v += a->lda; 857 } 858 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 859 } 860 ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 861 } else { 862 ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 863 #if defined(PETSC_USE_COMPLEX) 864 /* determine if matrix has all real values */ 865 v = a->v; 866 for (i=0; i<A->rmap->n*A->cmap->n; i++) { 867 if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break ;} 868 } 869 #endif 870 if (format == PETSC_VIEWER_ASCII_MATLAB) { 871 ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 872 ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr); 873 ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 874 ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr); 875 } 876 877 for (i=0; i<A->rmap->n; i++) { 878 v = a->v + i; 879 for (j=0; j<A->cmap->n; j++) { 880 #if defined(PETSC_USE_COMPLEX) 881 if (allreal) { 882 ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",PetscRealPart(*v));CHKERRQ(ierr); 883 } else { 884 ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16e i ",PetscRealPart(*v),PetscImaginaryPart(*v));CHKERRQ(ierr); 885 } 886 #else 887 ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",*v);CHKERRQ(ierr); 888 #endif 889 v += a->lda; 890 } 891 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 892 } 893 if (format == PETSC_VIEWER_ASCII_MATLAB) { 894 ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr); 895 } 896 ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 897 } 898 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 899 PetscFunctionReturn(0); 900 } 901 902 #undef __FUNCT__ 903 #define __FUNCT__ "MatView_SeqDense_Binary" 904 static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer) 905 { 906 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 907 PetscErrorCode ierr; 908 int fd; 909 PetscInt ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n; 910 PetscScalar *v,*anonz,*vals; 911 PetscViewerFormat format; 912 913 PetscFunctionBegin; 914 ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 915 916 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 917 if (format == PETSC_VIEWER_BINARY_NATIVE) { 918 /* store the matrix as a dense matrix */ 919 ierr = PetscMalloc(4*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 920 col_lens[0] = MAT_FILE_COOKIE; 921 col_lens[1] = m; 922 col_lens[2] = n; 923 col_lens[3] = MATRIX_BINARY_FORMAT_DENSE; 924 ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 925 ierr = PetscFree(col_lens);CHKERRQ(ierr); 926 927 /* write out matrix, by rows */ 928 ierr = PetscMalloc((m*n+1)*sizeof(PetscScalar),&vals);CHKERRQ(ierr); 929 v = a->v; 930 for (j=0; j<n; j++) { 931 for (i=0; i<m; i++) { 932 vals[j + i*n] = *v++; 933 } 934 } 935 ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 936 ierr = PetscFree(vals);CHKERRQ(ierr); 937 } else { 938 ierr = PetscMalloc((4+nz)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 939 col_lens[0] = MAT_FILE_COOKIE; 940 col_lens[1] = m; 941 col_lens[2] = n; 942 col_lens[3] = nz; 943 944 /* store lengths of each row and write (including header) to file */ 945 for (i=0; i<m; i++) col_lens[4+i] = n; 946 ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 947 948 /* Possibly should write in smaller increments, not whole matrix at once? */ 949 /* store column indices (zero start index) */ 950 ict = 0; 951 for (i=0; i<m; i++) { 952 for (j=0; j<n; j++) col_lens[ict++] = j; 953 } 954 ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 955 ierr = PetscFree(col_lens);CHKERRQ(ierr); 956 957 /* store nonzero values */ 958 ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&anonz);CHKERRQ(ierr); 959 ict = 0; 960 for (i=0; i<m; i++) { 961 v = a->v + i; 962 for (j=0; j<n; j++) { 963 anonz[ict++] = *v; v += a->lda; 964 } 965 } 966 ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 967 ierr = PetscFree(anonz);CHKERRQ(ierr); 968 } 969 PetscFunctionReturn(0); 970 } 971 972 #undef __FUNCT__ 973 #define __FUNCT__ "MatView_SeqDense_Draw_Zoom" 974 PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa) 975 { 976 Mat A = (Mat) Aa; 977 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 978 PetscErrorCode ierr; 979 PetscInt m = A->rmap->n,n = A->cmap->n,color,i,j; 980 PetscScalar *v = a->v; 981 PetscViewer viewer; 982 PetscDraw popup; 983 PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,scale,maxv = 0.0; 984 PetscViewerFormat format; 985 986 PetscFunctionBegin; 987 988 ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 989 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 990 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 991 992 /* Loop over matrix elements drawing boxes */ 993 if (format != PETSC_VIEWER_DRAW_CONTOUR) { 994 /* Blue for negative and Red for positive */ 995 color = PETSC_DRAW_BLUE; 996 for(j = 0; j < n; j++) { 997 x_l = j; 998 x_r = x_l + 1.0; 999 for(i = 0; i < m; i++) { 1000 y_l = m - i - 1.0; 1001 y_r = y_l + 1.0; 1002 #if defined(PETSC_USE_COMPLEX) 1003 if (PetscRealPart(v[j*m+i]) > 0.) { 1004 color = PETSC_DRAW_RED; 1005 } else if (PetscRealPart(v[j*m+i]) < 0.) { 1006 color = PETSC_DRAW_BLUE; 1007 } else { 1008 continue; 1009 } 1010 #else 1011 if (v[j*m+i] > 0.) { 1012 color = PETSC_DRAW_RED; 1013 } else if (v[j*m+i] < 0.) { 1014 color = PETSC_DRAW_BLUE; 1015 } else { 1016 continue; 1017 } 1018 #endif 1019 ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1020 } 1021 } 1022 } else { 1023 /* use contour shading to indicate magnitude of values */ 1024 /* first determine max of all nonzero values */ 1025 for(i = 0; i < m*n; i++) { 1026 if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1027 } 1028 scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 1029 ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 1030 if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 1031 for(j = 0; j < n; j++) { 1032 x_l = j; 1033 x_r = x_l + 1.0; 1034 for(i = 0; i < m; i++) { 1035 y_l = m - i - 1.0; 1036 y_r = y_l + 1.0; 1037 color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(v[j*m+i])); 1038 ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1039 } 1040 } 1041 } 1042 PetscFunctionReturn(0); 1043 } 1044 1045 #undef __FUNCT__ 1046 #define __FUNCT__ "MatView_SeqDense_Draw" 1047 PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer) 1048 { 1049 PetscDraw draw; 1050 PetscTruth isnull; 1051 PetscReal xr,yr,xl,yl,h,w; 1052 PetscErrorCode ierr; 1053 1054 PetscFunctionBegin; 1055 ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1056 ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1057 if (isnull) PetscFunctionReturn(0); 1058 1059 ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1060 xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1061 xr += w; yr += h; xl = -w; yl = -h; 1062 ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1063 ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr); 1064 ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 1065 PetscFunctionReturn(0); 1066 } 1067 1068 #undef __FUNCT__ 1069 #define __FUNCT__ "MatView_SeqDense" 1070 PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer) 1071 { 1072 PetscErrorCode ierr; 1073 PetscTruth iascii,isbinary,isdraw; 1074 1075 PetscFunctionBegin; 1076 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 1077 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 1078 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 1079 1080 if (iascii) { 1081 ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr); 1082 } else if (isbinary) { 1083 ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr); 1084 } else if (isdraw) { 1085 ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr); 1086 } else { 1087 SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by dense matrix",((PetscObject)viewer)->type_name); 1088 } 1089 PetscFunctionReturn(0); 1090 } 1091 1092 #undef __FUNCT__ 1093 #define __FUNCT__ "MatDestroy_SeqDense" 1094 PetscErrorCode MatDestroy_SeqDense(Mat mat) 1095 { 1096 Mat_SeqDense *l = (Mat_SeqDense*)mat->data; 1097 PetscErrorCode ierr; 1098 1099 PetscFunctionBegin; 1100 #if defined(PETSC_USE_LOG) 1101 PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n); 1102 #endif 1103 ierr = PetscFree(l->pivots);CHKERRQ(ierr); 1104 if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);} 1105 ierr = PetscFree(l);CHKERRQ(ierr); 1106 1107 ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr); 1108 ierr = PetscObjectComposeFunctionDynamic((PetscObject)mat,"MatSeqDenseSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 1109 ierr = PetscObjectComposeFunctionDynamic((PetscObject)mat,"MatMatMult_seqaij_seqdense_C","",PETSC_NULL);CHKERRQ(ierr); 1110 ierr = PetscObjectComposeFunctionDynamic((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C","",PETSC_NULL);CHKERRQ(ierr); 1111 ierr = PetscObjectComposeFunctionDynamic((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C","",PETSC_NULL);CHKERRQ(ierr); 1112 PetscFunctionReturn(0); 1113 } 1114 1115 #undef __FUNCT__ 1116 #define __FUNCT__ "MatTranspose_SeqDense" 1117 PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout) 1118 { 1119 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1120 PetscErrorCode ierr; 1121 PetscInt k,j,m,n,M; 1122 PetscScalar *v,tmp; 1123 1124 PetscFunctionBegin; 1125 v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n; 1126 if (reuse == MAT_REUSE_MATRIX && *matout == A) { /* in place transpose */ 1127 if (m != n) { 1128 SETERRQ(PETSC_ERR_SUP,"Can not transpose non-square matrix in place"); 1129 } else { 1130 for (j=0; j<m; j++) { 1131 for (k=0; k<j; k++) { 1132 tmp = v[j + k*M]; 1133 v[j + k*M] = v[k + j*M]; 1134 v[k + j*M] = tmp; 1135 } 1136 } 1137 } 1138 } else { /* out-of-place transpose */ 1139 Mat tmat; 1140 Mat_SeqDense *tmatd; 1141 PetscScalar *v2; 1142 1143 if (reuse == MAT_INITIAL_MATRIX) { 1144 ierr = MatCreate(((PetscObject)A)->comm,&tmat);CHKERRQ(ierr); 1145 ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr); 1146 ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 1147 ierr = MatSeqDenseSetPreallocation(tmat,PETSC_NULL);CHKERRQ(ierr); 1148 } else { 1149 tmat = *matout; 1150 } 1151 tmatd = (Mat_SeqDense*)tmat->data; 1152 v = mat->v; v2 = tmatd->v; 1153 for (j=0; j<n; j++) { 1154 for (k=0; k<m; k++) v2[j + k*n] = v[k + j*M]; 1155 } 1156 ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1157 ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1158 *matout = tmat; 1159 } 1160 PetscFunctionReturn(0); 1161 } 1162 1163 #undef __FUNCT__ 1164 #define __FUNCT__ "MatEqual_SeqDense" 1165 PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscTruth *flg) 1166 { 1167 Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data; 1168 Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data; 1169 PetscInt i,j; 1170 PetscScalar *v1 = mat1->v,*v2 = mat2->v; 1171 1172 PetscFunctionBegin; 1173 if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1174 if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1175 for (i=0; i<A1->rmap->n; i++) { 1176 v1 = mat1->v+i; v2 = mat2->v+i; 1177 for (j=0; j<A1->cmap->n; j++) { 1178 if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1179 v1 += mat1->lda; v2 += mat2->lda; 1180 } 1181 } 1182 *flg = PETSC_TRUE; 1183 PetscFunctionReturn(0); 1184 } 1185 1186 #undef __FUNCT__ 1187 #define __FUNCT__ "MatGetDiagonal_SeqDense" 1188 PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v) 1189 { 1190 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1191 PetscErrorCode ierr; 1192 PetscInt i,n,len; 1193 PetscScalar *x,zero = 0.0; 1194 1195 PetscFunctionBegin; 1196 ierr = VecSet(v,zero);CHKERRQ(ierr); 1197 ierr = VecGetSize(v,&n);CHKERRQ(ierr); 1198 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1199 len = PetscMin(A->rmap->n,A->cmap->n); 1200 if (n != A->rmap->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec"); 1201 for (i=0; i<len; i++) { 1202 x[i] = mat->v[i*mat->lda + i]; 1203 } 1204 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1205 PetscFunctionReturn(0); 1206 } 1207 1208 #undef __FUNCT__ 1209 #define __FUNCT__ "MatDiagonalScale_SeqDense" 1210 PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr) 1211 { 1212 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1213 PetscScalar *l,*r,x,*v; 1214 PetscErrorCode ierr; 1215 PetscInt i,j,m = A->rmap->n,n = A->cmap->n; 1216 1217 PetscFunctionBegin; 1218 if (ll) { 1219 ierr = VecGetSize(ll,&m);CHKERRQ(ierr); 1220 ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1221 if (m != A->rmap->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size"); 1222 for (i=0; i<m; i++) { 1223 x = l[i]; 1224 v = mat->v + i; 1225 for (j=0; j<n; j++) { (*v) *= x; v+= m;} 1226 } 1227 ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1228 ierr = PetscLogFlops(n*m);CHKERRQ(ierr); 1229 } 1230 if (rr) { 1231 ierr = VecGetSize(rr,&n);CHKERRQ(ierr); 1232 ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1233 if (n != A->cmap->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size"); 1234 for (i=0; i<n; i++) { 1235 x = r[i]; 1236 v = mat->v + i*m; 1237 for (j=0; j<m; j++) { (*v++) *= x;} 1238 } 1239 ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1240 ierr = PetscLogFlops(n*m);CHKERRQ(ierr); 1241 } 1242 PetscFunctionReturn(0); 1243 } 1244 1245 #undef __FUNCT__ 1246 #define __FUNCT__ "MatNorm_SeqDense" 1247 PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm) 1248 { 1249 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1250 PetscScalar *v = mat->v; 1251 PetscReal sum = 0.0; 1252 PetscInt lda=mat->lda,m=A->rmap->n,i,j; 1253 PetscErrorCode ierr; 1254 1255 PetscFunctionBegin; 1256 if (type == NORM_FROBENIUS) { 1257 if (lda>m) { 1258 for (j=0; j<A->cmap->n; j++) { 1259 v = mat->v+j*lda; 1260 for (i=0; i<m; i++) { 1261 #if defined(PETSC_USE_COMPLEX) 1262 sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1263 #else 1264 sum += (*v)*(*v); v++; 1265 #endif 1266 } 1267 } 1268 } else { 1269 for (i=0; i<A->cmap->n*A->rmap->n; i++) { 1270 #if defined(PETSC_USE_COMPLEX) 1271 sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1272 #else 1273 sum += (*v)*(*v); v++; 1274 #endif 1275 } 1276 } 1277 *nrm = sqrt(sum); 1278 ierr = PetscLogFlops(2*A->cmap->n*A->rmap->n);CHKERRQ(ierr); 1279 } else if (type == NORM_1) { 1280 *nrm = 0.0; 1281 for (j=0; j<A->cmap->n; j++) { 1282 v = mat->v + j*mat->lda; 1283 sum = 0.0; 1284 for (i=0; i<A->rmap->n; i++) { 1285 sum += PetscAbsScalar(*v); v++; 1286 } 1287 if (sum > *nrm) *nrm = sum; 1288 } 1289 ierr = PetscLogFlops(A->cmap->n*A->rmap->n);CHKERRQ(ierr); 1290 } else if (type == NORM_INFINITY) { 1291 *nrm = 0.0; 1292 for (j=0; j<A->rmap->n; j++) { 1293 v = mat->v + j; 1294 sum = 0.0; 1295 for (i=0; i<A->cmap->n; i++) { 1296 sum += PetscAbsScalar(*v); v += mat->lda; 1297 } 1298 if (sum > *nrm) *nrm = sum; 1299 } 1300 ierr = PetscLogFlops(A->cmap->n*A->rmap->n);CHKERRQ(ierr); 1301 } else { 1302 SETERRQ(PETSC_ERR_SUP,"No two norm"); 1303 } 1304 PetscFunctionReturn(0); 1305 } 1306 1307 #undef __FUNCT__ 1308 #define __FUNCT__ "MatSetOption_SeqDense" 1309 PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscTruth flg) 1310 { 1311 Mat_SeqDense *aij = (Mat_SeqDense*)A->data; 1312 PetscErrorCode ierr; 1313 1314 PetscFunctionBegin; 1315 switch (op) { 1316 case MAT_ROW_ORIENTED: 1317 aij->roworiented = flg; 1318 break; 1319 case MAT_NEW_NONZERO_LOCATIONS: 1320 case MAT_NEW_NONZERO_LOCATION_ERR: 1321 case MAT_NEW_NONZERO_ALLOCATION_ERR: 1322 case MAT_NEW_DIAGONALS: 1323 case MAT_IGNORE_OFF_PROC_ENTRIES: 1324 case MAT_USE_HASH_TABLE: 1325 case MAT_SYMMETRIC: 1326 case MAT_STRUCTURALLY_SYMMETRIC: 1327 case MAT_HERMITIAN: 1328 case MAT_SYMMETRY_ETERNAL: 1329 case MAT_IGNORE_LOWER_TRIANGULAR: 1330 ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1331 break; 1332 default: 1333 SETERRQ1(PETSC_ERR_SUP,"unknown option %s",MatOptions[op]); 1334 } 1335 PetscFunctionReturn(0); 1336 } 1337 1338 #undef __FUNCT__ 1339 #define __FUNCT__ "MatZeroEntries_SeqDense" 1340 PetscErrorCode MatZeroEntries_SeqDense(Mat A) 1341 { 1342 Mat_SeqDense *l = (Mat_SeqDense*)A->data; 1343 PetscErrorCode ierr; 1344 PetscInt lda=l->lda,m=A->rmap->n,j; 1345 1346 PetscFunctionBegin; 1347 if (lda>m) { 1348 for (j=0; j<A->cmap->n; j++) { 1349 ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr); 1350 } 1351 } else { 1352 ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 1353 } 1354 PetscFunctionReturn(0); 1355 } 1356 1357 #undef __FUNCT__ 1358 #define __FUNCT__ "MatZeroRows_SeqDense" 1359 PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag) 1360 { 1361 Mat_SeqDense *l = (Mat_SeqDense*)A->data; 1362 PetscInt n = A->cmap->n,i,j; 1363 PetscScalar *slot; 1364 1365 PetscFunctionBegin; 1366 for (i=0; i<N; i++) { 1367 slot = l->v + rows[i]; 1368 for (j=0; j<n; j++) { *slot = 0.0; slot += n;} 1369 } 1370 if (diag != 0.0) { 1371 for (i=0; i<N; i++) { 1372 slot = l->v + (n+1)*rows[i]; 1373 *slot = diag; 1374 } 1375 } 1376 PetscFunctionReturn(0); 1377 } 1378 1379 #undef __FUNCT__ 1380 #define __FUNCT__ "MatGetArray_SeqDense" 1381 PetscErrorCode MatGetArray_SeqDense(Mat A,PetscScalar *array[]) 1382 { 1383 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1384 1385 PetscFunctionBegin; 1386 if (mat->lda != A->rmap->n) SETERRQ(PETSC_ERR_SUP,"Cannot get array for Dense matrices with LDA different from number of rows"); 1387 *array = mat->v; 1388 PetscFunctionReturn(0); 1389 } 1390 1391 #undef __FUNCT__ 1392 #define __FUNCT__ "MatRestoreArray_SeqDense" 1393 PetscErrorCode MatRestoreArray_SeqDense(Mat A,PetscScalar *array[]) 1394 { 1395 PetscFunctionBegin; 1396 *array = 0; /* user cannot accidently use the array later */ 1397 PetscFunctionReturn(0); 1398 } 1399 1400 #undef __FUNCT__ 1401 #define __FUNCT__ "MatGetSubMatrix_SeqDense" 1402 static PetscErrorCode MatGetSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B) 1403 { 1404 Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1405 PetscErrorCode ierr; 1406 PetscInt i,j,*irow,*icol,nrows,ncols; 1407 PetscScalar *av,*bv,*v = mat->v; 1408 Mat newmat; 1409 1410 PetscFunctionBegin; 1411 ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1412 ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1413 ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1414 ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 1415 1416 /* Check submatrixcall */ 1417 if (scall == MAT_REUSE_MATRIX) { 1418 PetscInt n_cols,n_rows; 1419 ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1420 if (n_rows != nrows || n_cols != ncols) { 1421 /* resize the result result matrix to match number of requested rows/columns */ 1422 ierr = MatSetSizes(*B,nrows,nrows,nrows,nrows);CHKERRQ(ierr); 1423 } 1424 newmat = *B; 1425 } else { 1426 /* Create and fill new matrix */ 1427 ierr = MatCreate(((PetscObject)A)->comm,&newmat);CHKERRQ(ierr); 1428 ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr); 1429 ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 1430 ierr = MatSeqDenseSetPreallocation(newmat,PETSC_NULL);CHKERRQ(ierr); 1431 } 1432 1433 /* Now extract the data pointers and do the copy,column at a time */ 1434 bv = ((Mat_SeqDense*)newmat->data)->v; 1435 1436 for (i=0; i<ncols; i++) { 1437 av = v + mat->lda*icol[i]; 1438 for (j=0; j<nrows; j++) { 1439 *bv++ = av[irow[j]]; 1440 } 1441 } 1442 1443 /* Assemble the matrices so that the correct flags are set */ 1444 ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1445 ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1446 1447 /* Free work space */ 1448 ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1449 ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1450 *B = newmat; 1451 PetscFunctionReturn(0); 1452 } 1453 1454 #undef __FUNCT__ 1455 #define __FUNCT__ "MatGetSubMatrices_SeqDense" 1456 PetscErrorCode MatGetSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1457 { 1458 PetscErrorCode ierr; 1459 PetscInt i; 1460 1461 PetscFunctionBegin; 1462 if (scall == MAT_INITIAL_MATRIX) { 1463 ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1464 } 1465 1466 for (i=0; i<n; i++) { 1467 ierr = MatGetSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1468 } 1469 PetscFunctionReturn(0); 1470 } 1471 1472 #undef __FUNCT__ 1473 #define __FUNCT__ "MatAssemblyBegin_SeqDense" 1474 PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode) 1475 { 1476 PetscFunctionBegin; 1477 PetscFunctionReturn(0); 1478 } 1479 1480 #undef __FUNCT__ 1481 #define __FUNCT__ "MatAssemblyEnd_SeqDense" 1482 PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode) 1483 { 1484 PetscFunctionBegin; 1485 PetscFunctionReturn(0); 1486 } 1487 1488 #undef __FUNCT__ 1489 #define __FUNCT__ "MatCopy_SeqDense" 1490 PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str) 1491 { 1492 Mat_SeqDense *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense *)B->data; 1493 PetscErrorCode ierr; 1494 PetscInt lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j; 1495 1496 PetscFunctionBegin; 1497 /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 1498 if (A->ops->copy != B->ops->copy) { 1499 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1500 PetscFunctionReturn(0); 1501 } 1502 if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_ERR_ARG_SIZ,"size(B) != size(A)"); 1503 if (lda1>m || lda2>m) { 1504 for (j=0; j<n; j++) { 1505 ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr); 1506 } 1507 } else { 1508 ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 1509 } 1510 PetscFunctionReturn(0); 1511 } 1512 1513 #undef __FUNCT__ 1514 #define __FUNCT__ "MatSetUpPreallocation_SeqDense" 1515 PetscErrorCode MatSetUpPreallocation_SeqDense(Mat A) 1516 { 1517 PetscErrorCode ierr; 1518 1519 PetscFunctionBegin; 1520 ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr); 1521 PetscFunctionReturn(0); 1522 } 1523 1524 #undef __FUNCT__ 1525 #define __FUNCT__ "MatSetSizes_SeqDense" 1526 PetscErrorCode MatSetSizes_SeqDense(Mat A,PetscInt m,PetscInt n,PetscInt M,PetscInt N) 1527 { 1528 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1529 PetscErrorCode ierr; 1530 PetscFunctionBegin; 1531 /* this will not be called before lda, Mmax, and Nmax have been set */ 1532 m = PetscMax(m,M); 1533 n = PetscMax(n,N); 1534 if (m > a->Mmax) SETERRQ2(PETSC_ERR_SUP,"Cannot yet resize number rows of dense matrix larger then its initial size %d, requested %d",a->lda,(int)m); 1535 if (n > a->Nmax) SETERRQ2(PETSC_ERR_SUP,"Cannot yet resize number columns of dense matrix larger then its initial size %d, requested %d",a->Nmax,(int)n); 1536 A->rmap->n = A->rmap->n = m; 1537 A->cmap->n = A->cmap->N = n; 1538 if (a->changelda) a->lda = m; 1539 ierr = PetscMemzero(a->v,m*n*sizeof(PetscScalar));CHKERRQ(ierr); 1540 PetscFunctionReturn(0); 1541 } 1542 1543 1544 /* ----------------------------------------------------------------*/ 1545 #undef __FUNCT__ 1546 #define __FUNCT__ "MatMatMult_SeqDense_SeqDense" 1547 PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 1548 { 1549 PetscErrorCode ierr; 1550 1551 PetscFunctionBegin; 1552 if (scall == MAT_INITIAL_MATRIX){ 1553 ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr); 1554 } 1555 ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr); 1556 PetscFunctionReturn(0); 1557 } 1558 1559 #undef __FUNCT__ 1560 #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqDense" 1561 PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C) 1562 { 1563 PetscErrorCode ierr; 1564 PetscInt m=A->rmap->n,n=B->cmap->n; 1565 Mat Cmat; 1566 1567 PetscFunctionBegin; 1568 if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n); 1569 ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr); 1570 ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 1571 ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 1572 ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr); 1573 Cmat->assembled = PETSC_TRUE; 1574 *C = Cmat; 1575 PetscFunctionReturn(0); 1576 } 1577 1578 #undef __FUNCT__ 1579 #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqDense" 1580 PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 1581 { 1582 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1583 Mat_SeqDense *b = (Mat_SeqDense*)B->data; 1584 Mat_SeqDense *c = (Mat_SeqDense*)C->data; 1585 PetscBLASInt m,n,k; 1586 PetscScalar _DOne=1.0,_DZero=0.0; 1587 1588 PetscFunctionBegin; 1589 m = PetscBLASIntCast(A->rmap->n); 1590 n = PetscBLASIntCast(B->cmap->n); 1591 k = PetscBLASIntCast(A->cmap->n); 1592 BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda); 1593 PetscFunctionReturn(0); 1594 } 1595 1596 #undef __FUNCT__ 1597 #define __FUNCT__ "MatMatMultTranspose_SeqDense_SeqDense" 1598 PetscErrorCode MatMatMultTranspose_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 1599 { 1600 PetscErrorCode ierr; 1601 1602 PetscFunctionBegin; 1603 if (scall == MAT_INITIAL_MATRIX){ 1604 ierr = MatMatMultTransposeSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr); 1605 } 1606 ierr = MatMatMultTransposeNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr); 1607 PetscFunctionReturn(0); 1608 } 1609 1610 #undef __FUNCT__ 1611 #define __FUNCT__ "MatMatMultTransposeSymbolic_SeqDense_SeqDense" 1612 PetscErrorCode MatMatMultTransposeSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C) 1613 { 1614 PetscErrorCode ierr; 1615 PetscInt m=A->cmap->n,n=B->cmap->n; 1616 Mat Cmat; 1617 1618 PetscFunctionBegin; 1619 if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"A->rmap->n %d != B->rmap->n %d\n",A->rmap->n,B->rmap->n); 1620 ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr); 1621 ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 1622 ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 1623 ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr); 1624 Cmat->assembled = PETSC_TRUE; 1625 *C = Cmat; 1626 PetscFunctionReturn(0); 1627 } 1628 1629 #undef __FUNCT__ 1630 #define __FUNCT__ "MatMatMultTransposeNumeric_SeqDense_SeqDense" 1631 PetscErrorCode MatMatMultTransposeNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 1632 { 1633 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1634 Mat_SeqDense *b = (Mat_SeqDense*)B->data; 1635 Mat_SeqDense *c = (Mat_SeqDense*)C->data; 1636 PetscBLASInt m,n,k; 1637 PetscScalar _DOne=1.0,_DZero=0.0; 1638 1639 PetscFunctionBegin; 1640 m = PetscBLASIntCast(A->cmap->n); 1641 n = PetscBLASIntCast(B->cmap->n); 1642 k = PetscBLASIntCast(A->rmap->n); 1643 /* 1644 Note the m and n arguments below are the number rows and columns of A', not A! 1645 */ 1646 BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda); 1647 PetscFunctionReturn(0); 1648 } 1649 1650 #undef __FUNCT__ 1651 #define __FUNCT__ "MatGetRowMax_SeqDense" 1652 PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[]) 1653 { 1654 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1655 PetscErrorCode ierr; 1656 PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 1657 PetscScalar *x; 1658 MatScalar *aa = a->v; 1659 1660 PetscFunctionBegin; 1661 if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1662 1663 ierr = VecSet(v,0.0);CHKERRQ(ierr); 1664 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1665 ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 1666 if (p != A->rmap->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1667 for (i=0; i<m; i++) { 1668 x[i] = aa[i]; if (idx) idx[i] = 0; 1669 for (j=1; j<n; j++){ 1670 if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;} 1671 } 1672 } 1673 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1674 PetscFunctionReturn(0); 1675 } 1676 1677 #undef __FUNCT__ 1678 #define __FUNCT__ "MatGetRowMaxAbs_SeqDense" 1679 PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[]) 1680 { 1681 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1682 PetscErrorCode ierr; 1683 PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 1684 PetscScalar *x; 1685 PetscReal atmp; 1686 MatScalar *aa = a->v; 1687 1688 PetscFunctionBegin; 1689 if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1690 1691 ierr = VecSet(v,0.0);CHKERRQ(ierr); 1692 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1693 ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 1694 if (p != A->rmap->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1695 for (i=0; i<m; i++) { 1696 x[i] = PetscAbsScalar(aa[i]); 1697 for (j=1; j<n; j++){ 1698 atmp = PetscAbsScalar(aa[i+m*j]); 1699 if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;} 1700 } 1701 } 1702 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1703 PetscFunctionReturn(0); 1704 } 1705 1706 #undef __FUNCT__ 1707 #define __FUNCT__ "MatGetRowMin_SeqDense" 1708 PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[]) 1709 { 1710 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1711 PetscErrorCode ierr; 1712 PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 1713 PetscScalar *x; 1714 MatScalar *aa = a->v; 1715 1716 PetscFunctionBegin; 1717 if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1718 1719 ierr = VecSet(v,0.0);CHKERRQ(ierr); 1720 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1721 ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 1722 if (p != A->rmap->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1723 for (i=0; i<m; i++) { 1724 x[i] = aa[i]; if (idx) idx[i] = 0; 1725 for (j=1; j<n; j++){ 1726 if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;} 1727 } 1728 } 1729 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1730 PetscFunctionReturn(0); 1731 } 1732 1733 #undef __FUNCT__ 1734 #define __FUNCT__ "MatGetColumnVector_SeqDense" 1735 PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col) 1736 { 1737 Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1738 PetscErrorCode ierr; 1739 PetscScalar *x; 1740 1741 PetscFunctionBegin; 1742 if (A->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1743 1744 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1745 ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 1746 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1747 PetscFunctionReturn(0); 1748 } 1749 1750 /* -------------------------------------------------------------------*/ 1751 static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 1752 MatGetRow_SeqDense, 1753 MatRestoreRow_SeqDense, 1754 MatMult_SeqDense, 1755 /* 4*/ MatMultAdd_SeqDense, 1756 MatMultTranspose_SeqDense, 1757 MatMultTransposeAdd_SeqDense, 1758 0, 1759 0, 1760 0, 1761 /*10*/ 0, 1762 MatLUFactor_SeqDense, 1763 MatCholeskyFactor_SeqDense, 1764 MatRelax_SeqDense, 1765 MatTranspose_SeqDense, 1766 /*15*/ MatGetInfo_SeqDense, 1767 MatEqual_SeqDense, 1768 MatGetDiagonal_SeqDense, 1769 MatDiagonalScale_SeqDense, 1770 MatNorm_SeqDense, 1771 /*20*/ MatAssemblyBegin_SeqDense, 1772 MatAssemblyEnd_SeqDense, 1773 0, 1774 MatSetOption_SeqDense, 1775 MatZeroEntries_SeqDense, 1776 /*25*/ MatZeroRows_SeqDense, 1777 0, 1778 0, 1779 0, 1780 0, 1781 /*30*/ MatSetUpPreallocation_SeqDense, 1782 0, 1783 0, 1784 MatGetArray_SeqDense, 1785 MatRestoreArray_SeqDense, 1786 /*35*/ MatDuplicate_SeqDense, 1787 0, 1788 0, 1789 0, 1790 0, 1791 /*40*/ MatAXPY_SeqDense, 1792 MatGetSubMatrices_SeqDense, 1793 0, 1794 MatGetValues_SeqDense, 1795 MatCopy_SeqDense, 1796 /*45*/ MatGetRowMax_SeqDense, 1797 MatScale_SeqDense, 1798 0, 1799 0, 1800 0, 1801 /*50*/ 0, 1802 0, 1803 0, 1804 0, 1805 0, 1806 /*55*/ 0, 1807 0, 1808 0, 1809 0, 1810 0, 1811 /*60*/ 0, 1812 MatDestroy_SeqDense, 1813 MatView_SeqDense, 1814 0, 1815 0, 1816 /*65*/ 0, 1817 0, 1818 0, 1819 0, 1820 0, 1821 /*70*/ MatGetRowMaxAbs_SeqDense, 1822 0, 1823 0, 1824 0, 1825 0, 1826 /*75*/ 0, 1827 0, 1828 0, 1829 0, 1830 0, 1831 /*80*/ 0, 1832 0, 1833 0, 1834 0, 1835 /*84*/ MatLoad_SeqDense, 1836 0, 1837 MatIsHermitian_SeqDense, 1838 0, 1839 0, 1840 0, 1841 /*90*/ MatMatMult_SeqDense_SeqDense, 1842 MatMatMultSymbolic_SeqDense_SeqDense, 1843 MatMatMultNumeric_SeqDense_SeqDense, 1844 0, 1845 0, 1846 /*95*/ 0, 1847 MatMatMultTranspose_SeqDense_SeqDense, 1848 MatMatMultTransposeSymbolic_SeqDense_SeqDense, 1849 MatMatMultTransposeNumeric_SeqDense_SeqDense, 1850 0, 1851 /*100*/0, 1852 0, 1853 0, 1854 0, 1855 MatSetSizes_SeqDense, 1856 0, 1857 0, 1858 0, 1859 0, 1860 0, 1861 /*110*/0, 1862 0, 1863 MatGetRowMin_SeqDense, 1864 MatGetColumnVector_SeqDense 1865 }; 1866 1867 #undef __FUNCT__ 1868 #define __FUNCT__ "MatCreateSeqDense" 1869 /*@C 1870 MatCreateSeqDense - Creates a sequential dense matrix that 1871 is stored in column major order (the usual Fortran 77 manner). Many 1872 of the matrix operations use the BLAS and LAPACK routines. 1873 1874 Collective on MPI_Comm 1875 1876 Input Parameters: 1877 + comm - MPI communicator, set to PETSC_COMM_SELF 1878 . m - number of rows 1879 . n - number of columns 1880 - data - optional location of matrix data. Set data=PETSC_NULL for PETSc 1881 to control all matrix memory allocation. 1882 1883 Output Parameter: 1884 . A - the matrix 1885 1886 Notes: 1887 The data input variable is intended primarily for Fortran programmers 1888 who wish to allocate their own matrix memory space. Most users should 1889 set data=PETSC_NULL. 1890 1891 Level: intermediate 1892 1893 .keywords: dense, matrix, LAPACK, BLAS 1894 1895 .seealso: MatCreate(), MatCreateMPIDense(), MatSetValues() 1896 @*/ 1897 PetscErrorCode PETSCMAT_DLLEXPORT MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A) 1898 { 1899 PetscErrorCode ierr; 1900 1901 PetscFunctionBegin; 1902 ierr = MatCreate(comm,A);CHKERRQ(ierr); 1903 ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 1904 ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr); 1905 ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr); 1906 PetscFunctionReturn(0); 1907 } 1908 1909 #undef __FUNCT__ 1910 #define __FUNCT__ "MatSeqDenseSetPreallocation" 1911 /*@C 1912 MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements 1913 1914 Collective on MPI_Comm 1915 1916 Input Parameters: 1917 + A - the matrix 1918 - data - the array (or PETSC_NULL) 1919 1920 Notes: 1921 The data input variable is intended primarily for Fortran programmers 1922 who wish to allocate their own matrix memory space. Most users should 1923 need not call this routine. 1924 1925 Level: intermediate 1926 1927 .keywords: dense, matrix, LAPACK, BLAS 1928 1929 .seealso: MatCreate(), MatCreateMPIDense(), MatSetValues() 1930 @*/ 1931 PetscErrorCode PETSCMAT_DLLEXPORT MatSeqDenseSetPreallocation(Mat B,PetscScalar data[]) 1932 { 1933 PetscErrorCode ierr,(*f)(Mat,PetscScalar[]); 1934 1935 PetscFunctionBegin; 1936 ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 1937 if (f) { 1938 ierr = (*f)(B,data);CHKERRQ(ierr); 1939 } 1940 PetscFunctionReturn(0); 1941 } 1942 1943 EXTERN_C_BEGIN 1944 #undef __FUNCT__ 1945 #define __FUNCT__ "MatSeqDenseSetPreallocation_SeqDense" 1946 PetscErrorCode PETSCMAT_DLLEXPORT MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data) 1947 { 1948 Mat_SeqDense *b; 1949 PetscErrorCode ierr; 1950 1951 PetscFunctionBegin; 1952 B->preallocated = PETSC_TRUE; 1953 b = (Mat_SeqDense*)B->data; 1954 if (b->lda <= 0) b->lda = B->rmap->n; 1955 if (!data) { /* petsc-allocated storage */ 1956 if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); } 1957 ierr = PetscMalloc(b->lda*b->Nmax*sizeof(PetscScalar),&b->v);CHKERRQ(ierr); 1958 ierr = PetscMemzero(b->v,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr); 1959 ierr = PetscLogObjectMemory(B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr); 1960 b->user_alloc = PETSC_FALSE; 1961 } else { /* user-allocated storage */ 1962 if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); } 1963 b->v = data; 1964 b->user_alloc = PETSC_TRUE; 1965 } 1966 PetscFunctionReturn(0); 1967 } 1968 EXTERN_C_END 1969 1970 #undef __FUNCT__ 1971 #define __FUNCT__ "MatSeqDenseSetLDA" 1972 /*@C 1973 MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array 1974 1975 Input parameter: 1976 + A - the matrix 1977 - lda - the leading dimension 1978 1979 Notes: 1980 This routine is to be used in conjunction with MatSeqDenseSetPreallocation; 1981 it asserts that the preallocation has a leading dimension (the LDA parameter 1982 of Blas and Lapack fame) larger than M, the first dimension of the matrix. 1983 1984 Level: intermediate 1985 1986 .keywords: dense, matrix, LAPACK, BLAS 1987 1988 .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize() 1989 @*/ 1990 PetscErrorCode PETSCMAT_DLLEXPORT MatSeqDenseSetLDA(Mat B,PetscInt lda) 1991 { 1992 Mat_SeqDense *b = (Mat_SeqDense*)B->data; 1993 1994 PetscFunctionBegin; 1995 if (lda < B->rmap->n) SETERRQ2(PETSC_ERR_ARG_SIZ,"LDA %D must be at least matrix dimension %D",lda,B->rmap->n); 1996 b->lda = lda; 1997 b->changelda = PETSC_FALSE; 1998 b->Mmax = PetscMax(b->Mmax,lda); 1999 PetscFunctionReturn(0); 2000 } 2001 2002 /*MC 2003 MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 2004 2005 Options Database Keys: 2006 . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions() 2007 2008 Level: beginner 2009 2010 .seealso: MatCreateSeqDense() 2011 2012 M*/ 2013 2014 EXTERN_C_BEGIN 2015 #undef __FUNCT__ 2016 #define __FUNCT__ "MatCreate_SeqDense" 2017 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_SeqDense(Mat B) 2018 { 2019 Mat_SeqDense *b; 2020 PetscErrorCode ierr; 2021 PetscMPIInt size; 2022 2023 PetscFunctionBegin; 2024 ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 2025 if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 2026 2027 B->rmap->bs = B->cmap->bs = 1; 2028 ierr = PetscMapSetUp(B->rmap);CHKERRQ(ierr); 2029 ierr = PetscMapSetUp(B->cmap);CHKERRQ(ierr); 2030 2031 ierr = PetscNewLog(B,Mat_SeqDense,&b);CHKERRQ(ierr); 2032 ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2033 B->mapping = 0; 2034 B->data = (void*)b; 2035 2036 2037 b->pivots = 0; 2038 b->roworiented = PETSC_TRUE; 2039 b->v = 0; 2040 b->lda = B->rmap->n; 2041 b->changelda = PETSC_FALSE; 2042 b->Mmax = B->rmap->n; 2043 b->Nmax = B->cmap->n; 2044 2045 2046 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_seqdense_petsc_C", 2047 "MatGetFactor_seqdense_petsc", 2048 MatGetFactor_seqdense_petsc);CHKERRQ(ierr); 2049 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqDenseSetPreallocation_C", 2050 "MatSeqDenseSetPreallocation_SeqDense", 2051 MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr); 2052 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqaij_seqdense_C", 2053 "MatMatMult_SeqAIJ_SeqDense", 2054 MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr); 2055 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C", 2056 "MatMatMultSymbolic_SeqAIJ_SeqDense", 2057 MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr); 2058 ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C", 2059 "MatMatMultNumeric_SeqAIJ_SeqDense", 2060 MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr); 2061 ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr); 2062 PetscFunctionReturn(0); 2063 } 2064 2065 2066 EXTERN_C_END 2067