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