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