1be1d678aSKris Buschelman 267e560aaSBarry Smith /* 367e560aaSBarry Smith Defines the basic matrix operations for sequential dense. 467e560aaSBarry Smith */ 5289bc588SBarry Smith 6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/ 7c6db04a5SJed Brown #include <petscblaslapack.h> 8289bc588SBarry Smith 96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h> 10b2573a8aSBarry Smith 113f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 123f49a652SStefano Zampini { 133f49a652SStefano Zampini PetscErrorCode ierr; 143f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense*)A->data; 153f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n,r = A->rmap->n, i,j; 163f49a652SStefano Zampini PetscScalar *slot,*bb; 173f49a652SStefano Zampini const PetscScalar *xx; 183f49a652SStefano Zampini 193f49a652SStefano Zampini PetscFunctionBegin; 203f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG) 213f49a652SStefano Zampini for (i=0; i<N; i++) { 223f49a652SStefano Zampini if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed"); 233f49a652SStefano Zampini if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n); 243f49a652SStefano Zampini if (rows[i] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %D requested to be zeroed greater than or equal number of cols %D",rows[i],A->cmap->n); 253f49a652SStefano Zampini } 263f49a652SStefano Zampini #endif 273f49a652SStefano Zampini 283f49a652SStefano Zampini /* fix right hand side if needed */ 293f49a652SStefano Zampini if (x && b) { 303f49a652SStefano Zampini ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 313f49a652SStefano Zampini ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 323f49a652SStefano Zampini for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]]; 333f49a652SStefano Zampini ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 343f49a652SStefano Zampini ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 353f49a652SStefano Zampini } 363f49a652SStefano Zampini 373f49a652SStefano Zampini for (i=0; i<N; i++) { 383f49a652SStefano Zampini slot = l->v + rows[i]*m; 393f49a652SStefano Zampini ierr = PetscMemzero(slot,r*sizeof(PetscScalar));CHKERRQ(ierr); 403f49a652SStefano Zampini } 413f49a652SStefano Zampini for (i=0; i<N; i++) { 423f49a652SStefano Zampini slot = l->v + rows[i]; 433f49a652SStefano Zampini for (j=0; j<n; j++) { *slot = 0.0; slot += m;} 443f49a652SStefano Zampini } 453f49a652SStefano Zampini if (diag != 0.0) { 463f49a652SStefano Zampini if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices"); 473f49a652SStefano Zampini for (i=0; i<N; i++) { 483f49a652SStefano Zampini slot = l->v + (m+1)*rows[i]; 493f49a652SStefano Zampini *slot = diag; 503f49a652SStefano Zampini } 513f49a652SStefano Zampini } 523f49a652SStefano Zampini PetscFunctionReturn(0); 533f49a652SStefano Zampini } 543f49a652SStefano Zampini 55abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C) 56abc3b08eSStefano Zampini { 57abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense*)(C->data); 58abc3b08eSStefano Zampini PetscErrorCode ierr; 59abc3b08eSStefano Zampini 60abc3b08eSStefano Zampini PetscFunctionBegin; 61abc3b08eSStefano Zampini ierr = MatMatMultNumeric_SeqDense_SeqDense(A,P,c->ptapwork);CHKERRQ(ierr); 62abc3b08eSStefano Zampini ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(P,c->ptapwork,C);CHKERRQ(ierr); 63abc3b08eSStefano Zampini PetscFunctionReturn(0); 64abc3b08eSStefano Zampini } 65abc3b08eSStefano Zampini 66abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C) 67abc3b08eSStefano Zampini { 68abc3b08eSStefano Zampini Mat_SeqDense *c; 69abc3b08eSStefano Zampini PetscErrorCode ierr; 70abc3b08eSStefano Zampini 71abc3b08eSStefano Zampini PetscFunctionBegin; 72abc3b08eSStefano Zampini ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),P->cmap->N,P->cmap->N,NULL,C);CHKERRQ(ierr); 73abc3b08eSStefano Zampini c = (Mat_SeqDense*)((*C)->data); 74abc3b08eSStefano Zampini ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),A->rmap->N,P->cmap->N,NULL,&c->ptapwork);CHKERRQ(ierr); 75abc3b08eSStefano Zampini PetscFunctionReturn(0); 76abc3b08eSStefano Zampini } 77abc3b08eSStefano Zampini 78150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C) 79abc3b08eSStefano Zampini { 80abc3b08eSStefano Zampini PetscErrorCode ierr; 81abc3b08eSStefano Zampini 82abc3b08eSStefano Zampini PetscFunctionBegin; 83abc3b08eSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 84abc3b08eSStefano Zampini ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr); 85abc3b08eSStefano Zampini } 86abc3b08eSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 87abc3b08eSStefano Zampini ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 88abc3b08eSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 89abc3b08eSStefano Zampini PetscFunctionReturn(0); 90abc3b08eSStefano Zampini } 91abc3b08eSStefano Zampini 92cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat) 93b49cda9fSStefano Zampini { 94a13144ffSStefano Zampini Mat B = NULL; 95b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 96b49cda9fSStefano Zampini Mat_SeqDense *b; 97b49cda9fSStefano Zampini PetscErrorCode ierr; 98b49cda9fSStefano Zampini PetscInt *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i; 99b49cda9fSStefano Zampini MatScalar *av=a->a; 100a13144ffSStefano Zampini PetscBool isseqdense; 101b49cda9fSStefano Zampini 102b49cda9fSStefano Zampini PetscFunctionBegin; 103a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 104a13144ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 105a13144ffSStefano Zampini if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 106a13144ffSStefano Zampini } 107a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 108b49cda9fSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 109b49cda9fSStefano Zampini ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr); 110b49cda9fSStefano Zampini ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr); 111b49cda9fSStefano Zampini ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr); 112b49cda9fSStefano Zampini b = (Mat_SeqDense*)(B->data); 113a13144ffSStefano Zampini } else { 114a13144ffSStefano Zampini b = (Mat_SeqDense*)((*newmat)->data); 115a13144ffSStefano Zampini ierr = PetscMemzero(b->v,m*n*sizeof(PetscScalar));CHKERRQ(ierr); 116a13144ffSStefano Zampini } 117b49cda9fSStefano Zampini for (i=0; i<m; i++) { 118b49cda9fSStefano Zampini PetscInt j; 119b49cda9fSStefano Zampini for (j=0;j<ai[1]-ai[0];j++) { 120b49cda9fSStefano Zampini b->v[*aj*m+i] = *av; 121b49cda9fSStefano Zampini aj++; 122b49cda9fSStefano Zampini av++; 123b49cda9fSStefano Zampini } 124b49cda9fSStefano Zampini ai++; 125b49cda9fSStefano Zampini } 126b49cda9fSStefano Zampini 127511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 128a13144ffSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 129a13144ffSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13028be2f97SBarry Smith ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 131b49cda9fSStefano Zampini } else { 132a13144ffSStefano Zampini if (B) *newmat = B; 133a13144ffSStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 134a13144ffSStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 135b49cda9fSStefano Zampini } 136b49cda9fSStefano Zampini PetscFunctionReturn(0); 137b49cda9fSStefano Zampini } 138b49cda9fSStefano Zampini 139cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 1406a63e612SBarry Smith { 1416a63e612SBarry Smith Mat B; 1426a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1436a63e612SBarry Smith PetscErrorCode ierr; 1449399e1b8SMatthew G. Knepley PetscInt i, j; 1459399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 1469399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 1476a63e612SBarry Smith 1486a63e612SBarry Smith PetscFunctionBegin; 149ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 1506a63e612SBarry Smith ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 1516a63e612SBarry Smith ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 1529399e1b8SMatthew G. Knepley ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr); 1539399e1b8SMatthew G. Knepley for (j=0; j<A->cmap->n; j++) { 1549399e1b8SMatthew G. Knepley for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i]; 1556a63e612SBarry Smith aa += a->lda; 1566a63e612SBarry Smith } 1579399e1b8SMatthew G. Knepley ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr); 1589399e1b8SMatthew G. Knepley aa = a->v; 1599399e1b8SMatthew G. Knepley for (j=0; j<A->cmap->n; j++) { 1609399e1b8SMatthew G. Knepley PetscInt numRows = 0; 1619399e1b8SMatthew G. Knepley for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];} 1629399e1b8SMatthew G. Knepley ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr); 1639399e1b8SMatthew G. Knepley aa += a->lda; 1649399e1b8SMatthew G. Knepley } 1659399e1b8SMatthew G. Knepley ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr); 1666a63e612SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1676a63e612SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1686a63e612SBarry Smith 169511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 17028be2f97SBarry Smith ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 1716a63e612SBarry Smith } else { 1726a63e612SBarry Smith *newmat = B; 1736a63e612SBarry Smith } 1746a63e612SBarry Smith PetscFunctionReturn(0); 1756a63e612SBarry Smith } 1766a63e612SBarry Smith 177e0877f53SBarry Smith static PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str) 1781987afe7SBarry Smith { 1791987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data; 180f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 18113f74950SBarry Smith PetscInt j; 1820805154bSBarry Smith PetscBLASInt N,m,ldax,lday,one = 1; 183efee365bSSatish Balay PetscErrorCode ierr; 1843a40ed3dSBarry Smith 1853a40ed3dSBarry Smith PetscFunctionBegin; 186c5df96a5SBarry Smith ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr); 187c5df96a5SBarry Smith ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr); 188c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr); 189c5df96a5SBarry Smith ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr); 190a5ce6ee0Svictorle if (ldax>m || lday>m) { 191d0f46423SBarry Smith for (j=0; j<X->cmap->n; j++) { 1928b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one)); 193a5ce6ee0Svictorle } 194a5ce6ee0Svictorle } else { 1958b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one)); 196a5ce6ee0Svictorle } 197a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 1980450473dSBarry Smith ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr); 1993a40ed3dSBarry Smith PetscFunctionReturn(0); 2001987afe7SBarry Smith } 2011987afe7SBarry Smith 202e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info) 203289bc588SBarry Smith { 204d0f46423SBarry Smith PetscInt N = A->rmap->n*A->cmap->n; 2053a40ed3dSBarry Smith 2063a40ed3dSBarry Smith PetscFunctionBegin; 2074e220ebcSLois Curfman McInnes info->block_size = 1.0; 2084e220ebcSLois Curfman McInnes info->nz_allocated = (double)N; 2096de62eeeSBarry Smith info->nz_used = (double)N; 2106de62eeeSBarry Smith info->nz_unneeded = (double)0; 2114e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 2124e220ebcSLois Curfman McInnes info->mallocs = 0; 2137adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2144e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 2154e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 2164e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 2173a40ed3dSBarry Smith PetscFunctionReturn(0); 218289bc588SBarry Smith } 219289bc588SBarry Smith 220e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha) 22180cd9d93SLois Curfman McInnes { 222273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 223f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 224efee365bSSatish Balay PetscErrorCode ierr; 225c5df96a5SBarry Smith PetscBLASInt one = 1,j,nz,lda; 22680cd9d93SLois Curfman McInnes 2273a40ed3dSBarry Smith PetscFunctionBegin; 228c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr); 229d0f46423SBarry Smith if (lda>A->rmap->n) { 230c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr); 231d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2328b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v+j*lda,&one)); 233a5ce6ee0Svictorle } 234a5ce6ee0Svictorle } else { 235c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr); 2368b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v,&one)); 237a5ce6ee0Svictorle } 238efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 2393a40ed3dSBarry Smith PetscFunctionReturn(0); 24080cd9d93SLois Curfman McInnes } 24180cd9d93SLois Curfman McInnes 242e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool *fl) 2431cbb95d3SBarry Smith { 2441cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 245d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,N; 2461cbb95d3SBarry Smith PetscScalar *v = a->v; 2471cbb95d3SBarry Smith 2481cbb95d3SBarry Smith PetscFunctionBegin; 2491cbb95d3SBarry Smith *fl = PETSC_FALSE; 250d0f46423SBarry Smith if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 2511cbb95d3SBarry Smith N = a->lda; 2521cbb95d3SBarry Smith 2531cbb95d3SBarry Smith for (i=0; i<m; i++) { 2541cbb95d3SBarry Smith for (j=i+1; j<m; j++) { 2551cbb95d3SBarry Smith if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0); 2561cbb95d3SBarry Smith } 2571cbb95d3SBarry Smith } 2581cbb95d3SBarry Smith *fl = PETSC_TRUE; 2591cbb95d3SBarry Smith PetscFunctionReturn(0); 2601cbb95d3SBarry Smith } 2611cbb95d3SBarry Smith 262e0877f53SBarry Smith static PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues) 263b24902e0SBarry Smith { 264b24902e0SBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data,*l; 265b24902e0SBarry Smith PetscErrorCode ierr; 266b24902e0SBarry Smith PetscInt lda = (PetscInt)mat->lda,j,m; 267b24902e0SBarry Smith 268b24902e0SBarry Smith PetscFunctionBegin; 269aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr); 270aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr); 2710298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr); 272b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 273b24902e0SBarry Smith l = (Mat_SeqDense*)newi->data; 274d0f46423SBarry Smith if (lda>A->rmap->n) { 275d0f46423SBarry Smith m = A->rmap->n; 276d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 277b24902e0SBarry Smith ierr = PetscMemcpy(l->v+j*m,mat->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr); 278b24902e0SBarry Smith } 279b24902e0SBarry Smith } else { 280d0f46423SBarry Smith ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 281b24902e0SBarry Smith } 282b24902e0SBarry Smith } 283b24902e0SBarry Smith newi->assembled = PETSC_TRUE; 284b24902e0SBarry Smith PetscFunctionReturn(0); 285b24902e0SBarry Smith } 286b24902e0SBarry Smith 287e0877f53SBarry Smith static PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat) 28802cad45dSBarry Smith { 2896849ba73SBarry Smith PetscErrorCode ierr; 29002cad45dSBarry Smith 2913a40ed3dSBarry Smith PetscFunctionBegin; 292ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr); 293d0f46423SBarry Smith ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 2945c9eb25fSBarry Smith ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 295719d5645SBarry Smith ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr); 296b24902e0SBarry Smith PetscFunctionReturn(0); 297b24902e0SBarry Smith } 298b24902e0SBarry Smith 2996ee01492SSatish Balay 300e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,const MatFactorInfo*); 301719d5645SBarry Smith 302e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy) 303289bc588SBarry Smith { 3044482741eSBarry Smith MatFactorInfo info; 305a093e273SMatthew Knepley PetscErrorCode ierr; 3063a40ed3dSBarry Smith 3073a40ed3dSBarry Smith PetscFunctionBegin; 308c3ef05f6SHong Zhang ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr); 309719d5645SBarry Smith ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr); 3103a40ed3dSBarry Smith PetscFunctionReturn(0); 311289bc588SBarry Smith } 3126ee01492SSatish Balay 313e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy) 314289bc588SBarry Smith { 315c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 3166849ba73SBarry Smith PetscErrorCode ierr; 317f1ceaac6SMatthew G. Knepley const PetscScalar *x; 318f1ceaac6SMatthew G. Knepley PetscScalar *y; 319c5df96a5SBarry Smith PetscBLASInt one = 1,info,m; 32067e560aaSBarry Smith 3213a40ed3dSBarry Smith PetscFunctionBegin; 322c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 323f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 3241ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 325d0f46423SBarry Smith ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 326d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_LU) { 327ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS) 328e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 329ae7cfcebSSatish Balay #else 3308b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info)); 331e32f2f54SBarry Smith if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve"); 332ae7cfcebSSatish Balay #endif 333d5f3da31SBarry Smith } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 334ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS) 335e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 336ae7cfcebSSatish Balay #else 3378b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info)); 338e32f2f54SBarry Smith if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve"); 339ae7cfcebSSatish Balay #endif 3402205254eSKarl Rupp } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 341f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 3421ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 343dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 3443a40ed3dSBarry Smith PetscFunctionReturn(0); 345289bc588SBarry Smith } 3466ee01492SSatish Balay 347e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X) 34885e2c93fSHong Zhang { 34985e2c93fSHong Zhang Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 35085e2c93fSHong Zhang PetscErrorCode ierr; 35185e2c93fSHong Zhang PetscScalar *b,*x; 352efb80c78SLisandro Dalcin PetscInt n; 353783b601eSJed Brown PetscBLASInt nrhs,info,m; 354bda8bf91SBarry Smith PetscBool flg; 35585e2c93fSHong Zhang 35685e2c93fSHong Zhang PetscFunctionBegin; 357c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 3580298fd71SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 359ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3600298fd71SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 361ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 362bda8bf91SBarry Smith 3630298fd71SBarry Smith ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr); 364c5df96a5SBarry Smith ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr); 3658c778c55SBarry Smith ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr); 3668c778c55SBarry Smith ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr); 36785e2c93fSHong Zhang 368f272c775SHong Zhang ierr = PetscMemcpy(x,b,m*nrhs*sizeof(PetscScalar));CHKERRQ(ierr); 36985e2c93fSHong Zhang 37085e2c93fSHong Zhang if (A->factortype == MAT_FACTOR_LU) { 37185e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS) 37285e2c93fSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 37385e2c93fSHong Zhang #else 3748b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info)); 37585e2c93fSHong Zhang if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve"); 37685e2c93fSHong Zhang #endif 37785e2c93fSHong Zhang } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 37885e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS) 37985e2c93fSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 38085e2c93fSHong Zhang #else 3818b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info)); 38285e2c93fSHong Zhang if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve"); 38385e2c93fSHong Zhang #endif 3842205254eSKarl Rupp } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 38585e2c93fSHong Zhang 3868c778c55SBarry Smith ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr); 3878c778c55SBarry Smith ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr); 38885e2c93fSHong Zhang ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr); 38985e2c93fSHong Zhang PetscFunctionReturn(0); 39085e2c93fSHong Zhang } 39185e2c93fSHong Zhang 392e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy) 393da3a660dSBarry Smith { 394c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 395dfbe8321SBarry Smith PetscErrorCode ierr; 396f1ceaac6SMatthew G. Knepley const PetscScalar *x; 397f1ceaac6SMatthew G. Knepley PetscScalar *y; 398c5df96a5SBarry Smith PetscBLASInt one = 1,info,m; 39967e560aaSBarry Smith 4003a40ed3dSBarry Smith PetscFunctionBegin; 401c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 402f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 4031ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 404d0f46423SBarry Smith ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 405*8208b9aeSStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 406ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS) 407e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 408ae7cfcebSSatish Balay #else 4098b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info)); 410e32f2f54SBarry Smith if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve"); 411ae7cfcebSSatish Balay #endif 412*8208b9aeSStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 413ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS) 414e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 415ae7cfcebSSatish Balay #else 4168b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info)); 417e32f2f54SBarry Smith if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve"); 418ae7cfcebSSatish Balay #endif 419da3a660dSBarry Smith } 420f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 4211ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 422dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 4233a40ed3dSBarry Smith PetscFunctionReturn(0); 424da3a660dSBarry Smith } 4256ee01492SSatish Balay 426e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 427da3a660dSBarry Smith { 428dfbe8321SBarry Smith PetscErrorCode ierr; 429f1ceaac6SMatthew G. Knepley const PetscScalar *x; 430f1ceaac6SMatthew G. Knepley PetscScalar *y,sone = 1.0; 431da3a660dSBarry Smith Vec tmp = 0; 43267e560aaSBarry Smith 4333a40ed3dSBarry Smith PetscFunctionBegin; 434f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 4351ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 436d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 437da3a660dSBarry Smith if (yy == zz) { 43878b31e54SBarry Smith ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 4393bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr); 44078b31e54SBarry Smith ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 441da3a660dSBarry Smith } 442*8208b9aeSStefano Zampini ierr = MatSolve_SeqDense(A,xx,yy);CHKERRQ(ierr); 4436bf464f9SBarry Smith if (tmp) { 4446bf464f9SBarry Smith ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr); 4456bf464f9SBarry Smith ierr = VecDestroy(&tmp);CHKERRQ(ierr); 4466bf464f9SBarry Smith } else { 4476bf464f9SBarry Smith ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr); 4486bf464f9SBarry Smith } 449f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 4501ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 451*8208b9aeSStefano Zampini ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr); 4523a40ed3dSBarry Smith PetscFunctionReturn(0); 453da3a660dSBarry Smith } 45467e560aaSBarry Smith 455e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 456da3a660dSBarry Smith { 4576849ba73SBarry Smith PetscErrorCode ierr; 458f1ceaac6SMatthew G. Knepley const PetscScalar *x; 459f1ceaac6SMatthew G. Knepley PetscScalar *y,sone = 1.0; 46089ae1891SBarry Smith Vec tmp = NULL; 46167e560aaSBarry Smith 4623a40ed3dSBarry Smith PetscFunctionBegin; 463d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 464f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 4651ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 466da3a660dSBarry Smith if (yy == zz) { 46778b31e54SBarry Smith ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 4683bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr); 46978b31e54SBarry Smith ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 470da3a660dSBarry Smith } 471*8208b9aeSStefano Zampini ierr = MatSolveTranspose_SeqDense(A,xx,yy);CHKERRQ(ierr); 47290f02eecSBarry Smith if (tmp) { 4732dcb1b2aSMatthew Knepley ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr); 4746bf464f9SBarry Smith ierr = VecDestroy(&tmp);CHKERRQ(ierr); 4753a40ed3dSBarry Smith } else { 4762dcb1b2aSMatthew Knepley ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr); 47790f02eecSBarry Smith } 478f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 4791ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 480*8208b9aeSStefano Zampini ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr); 4813a40ed3dSBarry Smith PetscFunctionReturn(0); 482da3a660dSBarry Smith } 483db4efbfdSBarry Smith 484db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 485db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 486db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 487e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo) 488db4efbfdSBarry Smith { 489db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF) 490db4efbfdSBarry Smith PetscFunctionBegin; 491e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable."); 492db4efbfdSBarry Smith #else 493db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 494db4efbfdSBarry Smith PetscErrorCode ierr; 495db4efbfdSBarry Smith PetscBLASInt n,m,info; 496db4efbfdSBarry Smith 497db4efbfdSBarry Smith PetscFunctionBegin; 498c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 499c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 500db4efbfdSBarry Smith if (!mat->pivots) { 501*8208b9aeSStefano Zampini ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr); 5023bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr); 503db4efbfdSBarry Smith } 504db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 5058e57ea43SSatish Balay ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5068b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info)); 5078e57ea43SSatish Balay ierr = PetscFPTrapPop();CHKERRQ(ierr); 5088e57ea43SSatish Balay 509e32f2f54SBarry Smith if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization"); 510e32f2f54SBarry Smith if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization"); 511*8208b9aeSStefano Zampini 512db4efbfdSBarry Smith A->ops->solve = MatSolve_SeqDense; 513*8208b9aeSStefano Zampini A->ops->matsolve = MatMatSolve_SeqDense; 514db4efbfdSBarry Smith A->ops->solvetranspose = MatSolveTranspose_SeqDense; 515db4efbfdSBarry Smith A->ops->solveadd = MatSolveAdd_SeqDense; 516db4efbfdSBarry Smith A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 517d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 518db4efbfdSBarry Smith 519f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 520f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr); 521f6224b95SHong Zhang 522dc0b31edSSatish Balay ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr); 523db4efbfdSBarry Smith #endif 524db4efbfdSBarry Smith PetscFunctionReturn(0); 525db4efbfdSBarry Smith } 526db4efbfdSBarry Smith 527e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo) 528db4efbfdSBarry Smith { 529db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF) 530db4efbfdSBarry Smith PetscFunctionBegin; 531e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable."); 532db4efbfdSBarry Smith #else 533db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 534db4efbfdSBarry Smith PetscErrorCode ierr; 535c5df96a5SBarry Smith PetscBLASInt info,n; 536db4efbfdSBarry Smith 537db4efbfdSBarry Smith PetscFunctionBegin; 538c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 539db4efbfdSBarry Smith ierr = PetscFree(mat->pivots);CHKERRQ(ierr); 540db4efbfdSBarry Smith 541db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 5428b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info)); 543e32f2f54SBarry Smith if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1); 544*8208b9aeSStefano Zampini 545db4efbfdSBarry Smith A->ops->solve = MatSolve_SeqDense; 546*8208b9aeSStefano Zampini A->ops->matsolve = MatMatSolve_SeqDense; 547db4efbfdSBarry Smith A->ops->solvetranspose = MatSolveTranspose_SeqDense; 548db4efbfdSBarry Smith A->ops->solveadd = MatSolveAdd_SeqDense; 549db4efbfdSBarry Smith A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 550d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 5512205254eSKarl Rupp 552f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 553f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr); 554f6224b95SHong Zhang 555eb3f19e4SBarry Smith ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); 556db4efbfdSBarry Smith #endif 557db4efbfdSBarry Smith PetscFunctionReturn(0); 558db4efbfdSBarry Smith } 559db4efbfdSBarry Smith 560db4efbfdSBarry Smith 5610481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy) 562db4efbfdSBarry Smith { 563db4efbfdSBarry Smith PetscErrorCode ierr; 564db4efbfdSBarry Smith MatFactorInfo info; 565db4efbfdSBarry Smith 566db4efbfdSBarry Smith PetscFunctionBegin; 567db4efbfdSBarry Smith info.fill = 1.0; 5682205254eSKarl Rupp 569c3ef05f6SHong Zhang ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr); 570719d5645SBarry Smith ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr); 571db4efbfdSBarry Smith PetscFunctionReturn(0); 572db4efbfdSBarry Smith } 573db4efbfdSBarry Smith 574e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info) 575db4efbfdSBarry Smith { 576db4efbfdSBarry Smith PetscFunctionBegin; 577c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 5781bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 579719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 580db4efbfdSBarry Smith PetscFunctionReturn(0); 581db4efbfdSBarry Smith } 582db4efbfdSBarry Smith 583e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info) 584db4efbfdSBarry Smith { 585db4efbfdSBarry Smith PetscFunctionBegin; 586b66fe19dSMatthew G Knepley fact->preallocated = PETSC_TRUE; 587c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 588719d5645SBarry Smith fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 589db4efbfdSBarry Smith PetscFunctionReturn(0); 590db4efbfdSBarry Smith } 591db4efbfdSBarry Smith 592cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact) 593db4efbfdSBarry Smith { 594db4efbfdSBarry Smith PetscErrorCode ierr; 595db4efbfdSBarry Smith 596db4efbfdSBarry Smith PetscFunctionBegin; 597ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr); 598db4efbfdSBarry Smith ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 599db4efbfdSBarry Smith ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr); 600db4efbfdSBarry Smith if (ftype == MAT_FACTOR_LU) { 601db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 602db4efbfdSBarry Smith } else { 603db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 604db4efbfdSBarry Smith } 605d5f3da31SBarry Smith (*fact)->factortype = ftype; 60600c67f3bSHong Zhang 60700c67f3bSHong Zhang ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr); 60800c67f3bSHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr); 609db4efbfdSBarry Smith PetscFunctionReturn(0); 610db4efbfdSBarry Smith } 611db4efbfdSBarry Smith 612289bc588SBarry Smith /* ------------------------------------------------------------------*/ 613e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx) 614289bc588SBarry Smith { 615c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 616d9ca1df4SBarry Smith PetscScalar *x,*v = mat->v,zero = 0.0,xt; 617d9ca1df4SBarry Smith const PetscScalar *b; 618dfbe8321SBarry Smith PetscErrorCode ierr; 619d0f46423SBarry Smith PetscInt m = A->rmap->n,i; 620c5df96a5SBarry Smith PetscBLASInt o = 1,bm; 621289bc588SBarry Smith 6223a40ed3dSBarry Smith PetscFunctionBegin; 623422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 624c5df96a5SBarry Smith ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr); 625289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 62671044d3cSBarry Smith /* this is a hack fix, should have another version without the second BLASdot */ 6272dcb1b2aSMatthew Knepley ierr = VecSet(xx,zero);CHKERRQ(ierr); 628289bc588SBarry Smith } 6291ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 630d9ca1df4SBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 631b965ef7fSBarry Smith its = its*lits; 632e32f2f54SBarry Smith if (its <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 633289bc588SBarry Smith while (its--) { 634fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 635289bc588SBarry Smith for (i=0; i<m; i++) { 6368b83055fSJed Brown PetscStackCallBLAS("BLASdot",xt = b[i] - BLASdot_(&bm,v+i,&bm,x,&o)); 63755a1b374SBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 638289bc588SBarry Smith } 639289bc588SBarry Smith } 640fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 641289bc588SBarry Smith for (i=m-1; i>=0; i--) { 6428b83055fSJed Brown PetscStackCallBLAS("BLASdot",xt = b[i] - BLASdot_(&bm,v+i,&bm,x,&o)); 64355a1b374SBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 644289bc588SBarry Smith } 645289bc588SBarry Smith } 646289bc588SBarry Smith } 647d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 6481ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 6493a40ed3dSBarry Smith PetscFunctionReturn(0); 650289bc588SBarry Smith } 651289bc588SBarry Smith 652289bc588SBarry Smith /* -----------------------------------------------------------------*/ 653cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy) 654289bc588SBarry Smith { 655c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 656d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 657d9ca1df4SBarry Smith PetscScalar *y; 658dfbe8321SBarry Smith PetscErrorCode ierr; 6590805154bSBarry Smith PetscBLASInt m, n,_One=1; 660ea709b57SSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 6613a40ed3dSBarry Smith 6623a40ed3dSBarry Smith PetscFunctionBegin; 663c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 664c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 665d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 666d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 6671ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 6688b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One)); 669d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 6701ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 671dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 6723a40ed3dSBarry Smith PetscFunctionReturn(0); 673289bc588SBarry Smith } 674800995b7SMatthew Knepley 675cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy) 676289bc588SBarry Smith { 677c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 678d9ca1df4SBarry Smith PetscScalar *y,_DOne=1.0,_DZero=0.0; 679dfbe8321SBarry Smith PetscErrorCode ierr; 6800805154bSBarry Smith PetscBLASInt m, n, _One=1; 681d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 6823a40ed3dSBarry Smith 6833a40ed3dSBarry Smith PetscFunctionBegin; 684c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 685c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 686d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 687d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 6881ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 6898b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One)); 690d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 6911ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 692dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr); 6933a40ed3dSBarry Smith PetscFunctionReturn(0); 694289bc588SBarry Smith } 6956ee01492SSatish Balay 696cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 697289bc588SBarry Smith { 698c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 699d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 700d9ca1df4SBarry Smith PetscScalar *y,_DOne=1.0; 701dfbe8321SBarry Smith PetscErrorCode ierr; 7020805154bSBarry Smith PetscBLASInt m, n, _One=1; 7033a40ed3dSBarry Smith 7043a40ed3dSBarry Smith PetscFunctionBegin; 705c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 706c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 707d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 708600d6d0bSBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 709d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 7101ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 7118b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One)); 712d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 7131ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 714dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr); 7153a40ed3dSBarry Smith PetscFunctionReturn(0); 716289bc588SBarry Smith } 7176ee01492SSatish Balay 718e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 719289bc588SBarry Smith { 720c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 721d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 722d9ca1df4SBarry Smith PetscScalar *y; 723dfbe8321SBarry Smith PetscErrorCode ierr; 7240805154bSBarry Smith PetscBLASInt m, n, _One=1; 72587828ca2SBarry Smith PetscScalar _DOne=1.0; 7263a40ed3dSBarry Smith 7273a40ed3dSBarry Smith PetscFunctionBegin; 728c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 729c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 730d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 731600d6d0bSBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 732d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 7331ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 7348b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One)); 735d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 7361ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 737dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr); 7383a40ed3dSBarry Smith PetscFunctionReturn(0); 739289bc588SBarry Smith } 740289bc588SBarry Smith 741289bc588SBarry Smith /* -----------------------------------------------------------------*/ 742e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 743289bc588SBarry Smith { 744c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 74587828ca2SBarry Smith PetscScalar *v; 7466849ba73SBarry Smith PetscErrorCode ierr; 74713f74950SBarry Smith PetscInt i; 74867e560aaSBarry Smith 7493a40ed3dSBarry Smith PetscFunctionBegin; 750d0f46423SBarry Smith *ncols = A->cmap->n; 751289bc588SBarry Smith if (cols) { 752854ce69bSBarry Smith ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr); 753d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) (*cols)[i] = i; 754289bc588SBarry Smith } 755289bc588SBarry Smith if (vals) { 756854ce69bSBarry Smith ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr); 757289bc588SBarry Smith v = mat->v + row; 758d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;} 759289bc588SBarry Smith } 7603a40ed3dSBarry Smith PetscFunctionReturn(0); 761289bc588SBarry Smith } 7626ee01492SSatish Balay 763e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 764289bc588SBarry Smith { 765dfbe8321SBarry Smith PetscErrorCode ierr; 7666e111a19SKarl Rupp 767606d414cSSatish Balay PetscFunctionBegin; 768606d414cSSatish Balay if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);} 769606d414cSSatish Balay if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); } 7703a40ed3dSBarry Smith PetscFunctionReturn(0); 771289bc588SBarry Smith } 772289bc588SBarry Smith /* ----------------------------------------------------------------*/ 773e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv) 774289bc588SBarry Smith { 775c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 77613f74950SBarry Smith PetscInt i,j,idx=0; 777d6dfbf8fSBarry Smith 7783a40ed3dSBarry Smith PetscFunctionBegin; 779289bc588SBarry Smith if (!mat->roworiented) { 780dbb450caSBarry Smith if (addv == INSERT_VALUES) { 781289bc588SBarry Smith for (j=0; j<n; j++) { 782cddbea37SSatish Balay if (indexn[j] < 0) {idx += m; continue;} 7832515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 784e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 78558804f6dSBarry Smith #endif 786289bc588SBarry Smith for (i=0; i<m; i++) { 787cddbea37SSatish Balay if (indexm[i] < 0) {idx++; continue;} 7882515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 789e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 79058804f6dSBarry Smith #endif 791cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++]; 792289bc588SBarry Smith } 793289bc588SBarry Smith } 7943a40ed3dSBarry Smith } else { 795289bc588SBarry Smith for (j=0; j<n; j++) { 796cddbea37SSatish Balay if (indexn[j] < 0) {idx += m; continue;} 7972515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 798e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 79958804f6dSBarry Smith #endif 800289bc588SBarry Smith for (i=0; i<m; i++) { 801cddbea37SSatish Balay if (indexm[i] < 0) {idx++; continue;} 8022515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 803e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 80458804f6dSBarry Smith #endif 805cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 806289bc588SBarry Smith } 807289bc588SBarry Smith } 808289bc588SBarry Smith } 8093a40ed3dSBarry Smith } else { 810dbb450caSBarry Smith if (addv == INSERT_VALUES) { 811e8d4e0b9SBarry Smith for (i=0; i<m; i++) { 812cddbea37SSatish Balay if (indexm[i] < 0) { idx += n; continue;} 8132515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 814e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 81558804f6dSBarry Smith #endif 816e8d4e0b9SBarry Smith for (j=0; j<n; j++) { 817cddbea37SSatish Balay if (indexn[j] < 0) { idx++; continue;} 8182515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 819e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 82058804f6dSBarry Smith #endif 821cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++]; 822e8d4e0b9SBarry Smith } 823e8d4e0b9SBarry Smith } 8243a40ed3dSBarry Smith } else { 825289bc588SBarry Smith for (i=0; i<m; i++) { 826cddbea37SSatish Balay if (indexm[i] < 0) { idx += n; continue;} 8272515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 828e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 82958804f6dSBarry Smith #endif 830289bc588SBarry Smith for (j=0; j<n; j++) { 831cddbea37SSatish Balay if (indexn[j] < 0) { idx++; continue;} 8322515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 833e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 83458804f6dSBarry Smith #endif 835cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 836289bc588SBarry Smith } 837289bc588SBarry Smith } 838289bc588SBarry Smith } 839e8d4e0b9SBarry Smith } 8403a40ed3dSBarry Smith PetscFunctionReturn(0); 841289bc588SBarry Smith } 842e8d4e0b9SBarry Smith 843e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[]) 844ae80bb75SLois Curfman McInnes { 845ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 84613f74950SBarry Smith PetscInt i,j; 847ae80bb75SLois Curfman McInnes 8483a40ed3dSBarry Smith PetscFunctionBegin; 849ae80bb75SLois Curfman McInnes /* row-oriented output */ 850ae80bb75SLois Curfman McInnes for (i=0; i<m; i++) { 85197e567efSBarry Smith if (indexm[i] < 0) {v += n;continue;} 852e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested larger than number rows %D",indexm[i],A->rmap->n); 853ae80bb75SLois Curfman McInnes for (j=0; j<n; j++) { 8546f31f424SBarry Smith if (indexn[j] < 0) {v++; continue;} 855e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %D requested larger than number columns %D",indexn[j],A->cmap->n); 85697e567efSBarry Smith *v++ = mat->v[indexn[j]*mat->lda + indexm[i]]; 857ae80bb75SLois Curfman McInnes } 858ae80bb75SLois Curfman McInnes } 8593a40ed3dSBarry Smith PetscFunctionReturn(0); 860ae80bb75SLois Curfman McInnes } 861ae80bb75SLois Curfman McInnes 862289bc588SBarry Smith /* -----------------------------------------------------------------*/ 863289bc588SBarry Smith 864e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer) 865aabbc4fbSShri Abhyankar { 866aabbc4fbSShri Abhyankar Mat_SeqDense *a; 867aabbc4fbSShri Abhyankar PetscErrorCode ierr; 868aabbc4fbSShri Abhyankar PetscInt *scols,i,j,nz,header[4]; 869aabbc4fbSShri Abhyankar int fd; 870aabbc4fbSShri Abhyankar PetscMPIInt size; 871aabbc4fbSShri Abhyankar PetscInt *rowlengths = 0,M,N,*cols,grows,gcols; 872aabbc4fbSShri Abhyankar PetscScalar *vals,*svals,*v,*w; 873ce94432eSBarry Smith MPI_Comm comm; 874aabbc4fbSShri Abhyankar 875aabbc4fbSShri Abhyankar PetscFunctionBegin; 876c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 877c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 878ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 879aabbc4fbSShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 880aabbc4fbSShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor"); 881aabbc4fbSShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 882aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 883aabbc4fbSShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object"); 884aabbc4fbSShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 885aabbc4fbSShri Abhyankar 886aabbc4fbSShri Abhyankar /* set global size if not set already*/ 887aabbc4fbSShri Abhyankar if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) { 888aabbc4fbSShri Abhyankar ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr); 889aabbc4fbSShri Abhyankar } else { 890aabbc4fbSShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 891aabbc4fbSShri Abhyankar ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr); 892aabbc4fbSShri Abhyankar if (M != grows || N != gcols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,grows,gcols); 893aabbc4fbSShri Abhyankar } 894e6324fbbSBarry Smith a = (Mat_SeqDense*)newmat->data; 895e6324fbbSBarry Smith if (!a->user_alloc) { 8960298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr); 897e6324fbbSBarry Smith } 898aabbc4fbSShri Abhyankar 899aabbc4fbSShri Abhyankar if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */ 900aabbc4fbSShri Abhyankar a = (Mat_SeqDense*)newmat->data; 901aabbc4fbSShri Abhyankar v = a->v; 902aabbc4fbSShri Abhyankar /* Allocate some temp space to read in the values and then flip them 903aabbc4fbSShri Abhyankar from row major to column major */ 904854ce69bSBarry Smith ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr); 905aabbc4fbSShri Abhyankar /* read in nonzero values */ 906aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr); 907aabbc4fbSShri Abhyankar /* now flip the values and store them in the matrix*/ 908aabbc4fbSShri Abhyankar for (j=0; j<N; j++) { 909aabbc4fbSShri Abhyankar for (i=0; i<M; i++) { 910aabbc4fbSShri Abhyankar *v++ =w[i*N+j]; 911aabbc4fbSShri Abhyankar } 912aabbc4fbSShri Abhyankar } 913aabbc4fbSShri Abhyankar ierr = PetscFree(w);CHKERRQ(ierr); 914aabbc4fbSShri Abhyankar } else { 915aabbc4fbSShri Abhyankar /* read row lengths */ 916854ce69bSBarry Smith ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr); 917aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 918aabbc4fbSShri Abhyankar 919aabbc4fbSShri Abhyankar a = (Mat_SeqDense*)newmat->data; 920aabbc4fbSShri Abhyankar v = a->v; 921aabbc4fbSShri Abhyankar 922aabbc4fbSShri Abhyankar /* read column indices and nonzeros */ 923854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr); 924aabbc4fbSShri Abhyankar cols = scols; 925aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr); 926854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr); 927aabbc4fbSShri Abhyankar vals = svals; 928aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr); 929aabbc4fbSShri Abhyankar 930aabbc4fbSShri Abhyankar /* insert into matrix */ 931aabbc4fbSShri Abhyankar for (i=0; i<M; i++) { 932aabbc4fbSShri Abhyankar for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j]; 933aabbc4fbSShri Abhyankar svals += rowlengths[i]; scols += rowlengths[i]; 934aabbc4fbSShri Abhyankar } 935aabbc4fbSShri Abhyankar ierr = PetscFree(vals);CHKERRQ(ierr); 936aabbc4fbSShri Abhyankar ierr = PetscFree(cols);CHKERRQ(ierr); 937aabbc4fbSShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 938aabbc4fbSShri Abhyankar } 939aabbc4fbSShri Abhyankar ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 940aabbc4fbSShri Abhyankar ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 941aabbc4fbSShri Abhyankar PetscFunctionReturn(0); 942aabbc4fbSShri Abhyankar } 943aabbc4fbSShri Abhyankar 9446849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer) 945289bc588SBarry Smith { 946932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense*)A->data; 947dfbe8321SBarry Smith PetscErrorCode ierr; 94813f74950SBarry Smith PetscInt i,j; 9492dcb1b2aSMatthew Knepley const char *name; 95087828ca2SBarry Smith PetscScalar *v; 951f3ef73ceSBarry Smith PetscViewerFormat format; 9525f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 953ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 9545f481a85SSatish Balay #endif 955932b0c3eSLois Curfman McInnes 9563a40ed3dSBarry Smith PetscFunctionBegin; 957b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 958456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 9593a40ed3dSBarry Smith PetscFunctionReturn(0); /* do nothing for now */ 960fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 961d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 962d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 96344cd7ae7SLois Curfman McInnes v = a->v + i; 96477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 965d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 966aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 967329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 96857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr); 969329f5518SBarry Smith } else if (PetscRealPart(*v)) { 97057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr); 9716831982aSBarry Smith } 97280cd9d93SLois Curfman McInnes #else 9736831982aSBarry Smith if (*v) { 97457622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr); 9756831982aSBarry Smith } 97680cd9d93SLois Curfman McInnes #endif 9771b807ce4Svictorle v += a->lda; 97880cd9d93SLois Curfman McInnes } 979b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 98080cd9d93SLois Curfman McInnes } 981d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9823a40ed3dSBarry Smith } else { 983d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 984aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 98547989497SBarry Smith /* determine if matrix has all real values */ 98647989497SBarry Smith v = a->v; 987d0f46423SBarry Smith for (i=0; i<A->rmap->n*A->cmap->n; i++) { 988ffac6cdbSBarry Smith if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;} 98947989497SBarry Smith } 99047989497SBarry Smith #endif 991fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 9923a7fca6bSBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 993d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr); 994d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 995fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr); 996ffac6cdbSBarry Smith } 997ffac6cdbSBarry Smith 998d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 999932b0c3eSLois Curfman McInnes v = a->v + i; 1000d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1001aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 100247989497SBarry Smith if (allreal) { 1003c61cd2faSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr); 100447989497SBarry Smith } else { 1005c61cd2faSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr); 100647989497SBarry Smith } 1007289bc588SBarry Smith #else 1008c61cd2faSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr); 1009289bc588SBarry Smith #endif 10101b807ce4Svictorle v += a->lda; 1011289bc588SBarry Smith } 1012b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 1013289bc588SBarry Smith } 1014fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 1015b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr); 1016ffac6cdbSBarry Smith } 1017d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 1018da3a660dSBarry Smith } 1019b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10203a40ed3dSBarry Smith PetscFunctionReturn(0); 1021289bc588SBarry Smith } 1022289bc588SBarry Smith 10236849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer) 1024932b0c3eSLois Curfman McInnes { 1025932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense*)A->data; 10266849ba73SBarry Smith PetscErrorCode ierr; 102713f74950SBarry Smith int fd; 1028d0f46423SBarry Smith PetscInt ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n; 1029f4403165SShri Abhyankar PetscScalar *v,*anonz,*vals; 1030f4403165SShri Abhyankar PetscViewerFormat format; 1031932b0c3eSLois Curfman McInnes 10323a40ed3dSBarry Smith PetscFunctionBegin; 1033b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 103490ace30eSBarry Smith 1035f4403165SShri Abhyankar ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1036f4403165SShri Abhyankar if (format == PETSC_VIEWER_NATIVE) { 1037f4403165SShri Abhyankar /* store the matrix as a dense matrix */ 1038785e854fSJed Brown ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr); 10392205254eSKarl Rupp 1040f4403165SShri Abhyankar col_lens[0] = MAT_FILE_CLASSID; 1041f4403165SShri Abhyankar col_lens[1] = m; 1042f4403165SShri Abhyankar col_lens[2] = n; 1043f4403165SShri Abhyankar col_lens[3] = MATRIX_BINARY_FORMAT_DENSE; 10442205254eSKarl Rupp 1045f4403165SShri Abhyankar ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 1046f4403165SShri Abhyankar ierr = PetscFree(col_lens);CHKERRQ(ierr); 1047f4403165SShri Abhyankar 1048f4403165SShri Abhyankar /* write out matrix, by rows */ 1049854ce69bSBarry Smith ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr); 1050f4403165SShri Abhyankar v = a->v; 1051f4403165SShri Abhyankar for (j=0; j<n; j++) { 1052f4403165SShri Abhyankar for (i=0; i<m; i++) { 1053f4403165SShri Abhyankar vals[j + i*n] = *v++; 1054f4403165SShri Abhyankar } 1055f4403165SShri Abhyankar } 1056f4403165SShri Abhyankar ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 1057f4403165SShri Abhyankar ierr = PetscFree(vals);CHKERRQ(ierr); 1058f4403165SShri Abhyankar } else { 1059854ce69bSBarry Smith ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr); 10602205254eSKarl Rupp 10610700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 1062932b0c3eSLois Curfman McInnes col_lens[1] = m; 1063932b0c3eSLois Curfman McInnes col_lens[2] = n; 1064932b0c3eSLois Curfman McInnes col_lens[3] = nz; 1065932b0c3eSLois Curfman McInnes 1066932b0c3eSLois Curfman McInnes /* store lengths of each row and write (including header) to file */ 1067932b0c3eSLois Curfman McInnes for (i=0; i<m; i++) col_lens[4+i] = n; 10686f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 1069932b0c3eSLois Curfman McInnes 1070932b0c3eSLois Curfman McInnes /* Possibly should write in smaller increments, not whole matrix at once? */ 1071932b0c3eSLois Curfman McInnes /* store column indices (zero start index) */ 1072932b0c3eSLois Curfman McInnes ict = 0; 1073932b0c3eSLois Curfman McInnes for (i=0; i<m; i++) { 1074932b0c3eSLois Curfman McInnes for (j=0; j<n; j++) col_lens[ict++] = j; 1075932b0c3eSLois Curfman McInnes } 10766f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 1077606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 1078932b0c3eSLois Curfman McInnes 1079932b0c3eSLois Curfman McInnes /* store nonzero values */ 1080854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr); 1081932b0c3eSLois Curfman McInnes ict = 0; 1082932b0c3eSLois Curfman McInnes for (i=0; i<m; i++) { 1083932b0c3eSLois Curfman McInnes v = a->v + i; 1084932b0c3eSLois Curfman McInnes for (j=0; j<n; j++) { 10851b807ce4Svictorle anonz[ict++] = *v; v += a->lda; 1086932b0c3eSLois Curfman McInnes } 1087932b0c3eSLois Curfman McInnes } 10886f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 1089606d414cSSatish Balay ierr = PetscFree(anonz);CHKERRQ(ierr); 1090f4403165SShri Abhyankar } 10913a40ed3dSBarry Smith PetscFunctionReturn(0); 1092932b0c3eSLois Curfman McInnes } 1093932b0c3eSLois Curfman McInnes 10949804daf3SBarry Smith #include <petscdraw.h> 1095e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa) 1096f1af5d2fSBarry Smith { 1097f1af5d2fSBarry Smith Mat A = (Mat) Aa; 1098f1af5d2fSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 10996849ba73SBarry Smith PetscErrorCode ierr; 1100383922c3SLisandro Dalcin PetscInt m = A->rmap->n,n = A->cmap->n,i,j; 1101383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 110287828ca2SBarry Smith PetscScalar *v = a->v; 1103b0a32e0cSBarry Smith PetscViewer viewer; 1104b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1105f3ef73ceSBarry Smith PetscViewerFormat format; 1106f1af5d2fSBarry Smith 1107f1af5d2fSBarry Smith PetscFunctionBegin; 1108f1af5d2fSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1109b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1110b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1111f1af5d2fSBarry Smith 1112f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 1113383922c3SLisandro Dalcin 1114fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1115383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 1116f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1117f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1118383922c3SLisandro Dalcin x_l = j; x_r = x_l + 1.0; 1119f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1120f1af5d2fSBarry Smith y_l = m - i - 1.0; 1121f1af5d2fSBarry Smith y_r = y_l + 1.0; 1122329f5518SBarry Smith if (PetscRealPart(v[j*m+i]) > 0.) { 1123b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1124329f5518SBarry Smith } else if (PetscRealPart(v[j*m+i]) < 0.) { 1125b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1126f1af5d2fSBarry Smith } else { 1127f1af5d2fSBarry Smith continue; 1128f1af5d2fSBarry Smith } 1129b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1130f1af5d2fSBarry Smith } 1131f1af5d2fSBarry Smith } 1132383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 1133f1af5d2fSBarry Smith } else { 1134f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1135f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1136b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1137b05fc000SLisandro Dalcin PetscDraw popup; 1138b05fc000SLisandro Dalcin 1139f1af5d2fSBarry Smith for (i=0; i < m*n; i++) { 1140f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1141f1af5d2fSBarry Smith } 1142383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1143b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 114445f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1145383922c3SLisandro Dalcin 1146383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 1147f1af5d2fSBarry Smith for (j=0; j<n; j++) { 1148f1af5d2fSBarry Smith x_l = j; 1149f1af5d2fSBarry Smith x_r = x_l + 1.0; 1150f1af5d2fSBarry Smith for (i=0; i<m; i++) { 1151f1af5d2fSBarry Smith y_l = m - i - 1.0; 1152f1af5d2fSBarry Smith y_r = y_l + 1.0; 1153b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv); 1154b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1155f1af5d2fSBarry Smith } 1156f1af5d2fSBarry Smith } 1157383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 1158f1af5d2fSBarry Smith } 1159f1af5d2fSBarry Smith PetscFunctionReturn(0); 1160f1af5d2fSBarry Smith } 1161f1af5d2fSBarry Smith 1162e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer) 1163f1af5d2fSBarry Smith { 1164b0a32e0cSBarry Smith PetscDraw draw; 1165ace3abfcSBarry Smith PetscBool isnull; 1166329f5518SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1167dfbe8321SBarry Smith PetscErrorCode ierr; 1168f1af5d2fSBarry Smith 1169f1af5d2fSBarry Smith PetscFunctionBegin; 1170b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1171b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1172abc0a331SBarry Smith if (isnull) PetscFunctionReturn(0); 1173f1af5d2fSBarry Smith 1174d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1175f1af5d2fSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1176b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1177832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1178b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr); 11790298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1180832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1181f1af5d2fSBarry Smith PetscFunctionReturn(0); 1182f1af5d2fSBarry Smith } 1183f1af5d2fSBarry Smith 1184dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer) 1185932b0c3eSLois Curfman McInnes { 1186dfbe8321SBarry Smith PetscErrorCode ierr; 1187ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1188932b0c3eSLois Curfman McInnes 11893a40ed3dSBarry Smith PetscFunctionBegin; 1190251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1191251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1192251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 11930f5bd95cSBarry Smith 1194c45a1595SBarry Smith if (iascii) { 1195c45a1595SBarry Smith ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr); 11960f5bd95cSBarry Smith } else if (isbinary) { 11973a40ed3dSBarry Smith ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr); 1198f1af5d2fSBarry Smith } else if (isdraw) { 1199f1af5d2fSBarry Smith ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr); 1200932b0c3eSLois Curfman McInnes } 12013a40ed3dSBarry Smith PetscFunctionReturn(0); 1202932b0c3eSLois Curfman McInnes } 1203289bc588SBarry Smith 1204e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat) 1205289bc588SBarry Smith { 1206ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)mat->data; 1207dfbe8321SBarry Smith PetscErrorCode ierr; 120890f02eecSBarry Smith 12093a40ed3dSBarry Smith PetscFunctionBegin; 1210aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1211d0f46423SBarry Smith PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n); 1212a5a9c739SBarry Smith #endif 121305b42c5fSBarry Smith ierr = PetscFree(l->pivots);CHKERRQ(ierr); 1214abc3b08eSStefano Zampini ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr); 12156857c123SSatish Balay if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);} 1216bf0cc555SLisandro Dalcin ierr = PetscFree(mat->data);CHKERRQ(ierr); 1217dbd8c25aSHong Zhang 1218dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr); 1219bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr); 1220bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr); 12218baccfbdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 12228baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 12238baccfbdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr); 12248baccfbdSHong Zhang #endif 1225bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr); 1226bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1227bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1228bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1229abc3b08eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 12303bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 12313bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 12323bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 12333a40ed3dSBarry Smith PetscFunctionReturn(0); 1234289bc588SBarry Smith } 1235289bc588SBarry Smith 1236e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout) 1237289bc588SBarry Smith { 1238c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 12396849ba73SBarry Smith PetscErrorCode ierr; 124013f74950SBarry Smith PetscInt k,j,m,n,M; 124187828ca2SBarry Smith PetscScalar *v,tmp; 124248b35521SBarry Smith 12433a40ed3dSBarry Smith PetscFunctionBegin; 1244d0f46423SBarry Smith v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n; 1245cf37664fSBarry Smith if (reuse == MAT_INPLACE_MATRIX) { /* in place transpose */ 1246e7e72b3dSBarry Smith if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can not transpose non-square matrix in place"); 1247e7e72b3dSBarry Smith else { 1248d3e5ee88SLois Curfman McInnes for (j=0; j<m; j++) { 1249289bc588SBarry Smith for (k=0; k<j; k++) { 12501b807ce4Svictorle tmp = v[j + k*M]; 12511b807ce4Svictorle v[j + k*M] = v[k + j*M]; 12521b807ce4Svictorle v[k + j*M] = tmp; 1253289bc588SBarry Smith } 1254289bc588SBarry Smith } 1255d64ed03dSBarry Smith } 12563a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1257d3e5ee88SLois Curfman McInnes Mat tmat; 1258ec8511deSBarry Smith Mat_SeqDense *tmatd; 125987828ca2SBarry Smith PetscScalar *v2; 1260af36a384SStefano Zampini PetscInt M2; 1261ea709b57SSatish Balay 1262fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX) { 1263ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr); 1264d0f46423SBarry Smith ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr); 12657adad957SLisandro Dalcin ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 12660298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr); 1267fc4dec0aSBarry Smith } else { 1268fc4dec0aSBarry Smith tmat = *matout; 1269fc4dec0aSBarry Smith } 1270ec8511deSBarry Smith tmatd = (Mat_SeqDense*)tmat->data; 1271af36a384SStefano Zampini v = mat->v; v2 = tmatd->v; M2 = tmatd->lda; 1272d3e5ee88SLois Curfman McInnes for (j=0; j<n; j++) { 1273af36a384SStefano Zampini for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M]; 1274d3e5ee88SLois Curfman McInnes } 12756d4a8577SBarry Smith ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12766d4a8577SBarry Smith ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1277d3e5ee88SLois Curfman McInnes *matout = tmat; 127848b35521SBarry Smith } 12793a40ed3dSBarry Smith PetscFunctionReturn(0); 1280289bc588SBarry Smith } 1281289bc588SBarry Smith 1282e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool *flg) 1283289bc588SBarry Smith { 1284c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data; 1285c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data; 128613f74950SBarry Smith PetscInt i,j; 1287a2ea699eSBarry Smith PetscScalar *v1,*v2; 12889ea5d5aeSSatish Balay 12893a40ed3dSBarry Smith PetscFunctionBegin; 1290d0f46423SBarry Smith if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1291d0f46423SBarry Smith if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1292d0f46423SBarry Smith for (i=0; i<A1->rmap->n; i++) { 12931b807ce4Svictorle v1 = mat1->v+i; v2 = mat2->v+i; 1294d0f46423SBarry Smith for (j=0; j<A1->cmap->n; j++) { 12953a40ed3dSBarry Smith if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 12961b807ce4Svictorle v1 += mat1->lda; v2 += mat2->lda; 12971b807ce4Svictorle } 1298289bc588SBarry Smith } 129977c4ece6SBarry Smith *flg = PETSC_TRUE; 13003a40ed3dSBarry Smith PetscFunctionReturn(0); 1301289bc588SBarry Smith } 1302289bc588SBarry Smith 1303e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v) 1304289bc588SBarry Smith { 1305c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1306dfbe8321SBarry Smith PetscErrorCode ierr; 130713f74950SBarry Smith PetscInt i,n,len; 130887828ca2SBarry Smith PetscScalar *x,zero = 0.0; 130944cd7ae7SLois Curfman McInnes 13103a40ed3dSBarry Smith PetscFunctionBegin; 13112dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 13127a97a34bSBarry Smith ierr = VecGetSize(v,&n);CHKERRQ(ierr); 13131ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1314d0f46423SBarry Smith len = PetscMin(A->rmap->n,A->cmap->n); 1315e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec"); 131644cd7ae7SLois Curfman McInnes for (i=0; i<len; i++) { 13171b807ce4Svictorle x[i] = mat->v[i*mat->lda + i]; 1318289bc588SBarry Smith } 13191ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 13203a40ed3dSBarry Smith PetscFunctionReturn(0); 1321289bc588SBarry Smith } 1322289bc588SBarry Smith 1323e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr) 1324289bc588SBarry Smith { 1325c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1326f1ceaac6SMatthew G. Knepley const PetscScalar *l,*r; 1327f1ceaac6SMatthew G. Knepley PetscScalar x,*v; 1328dfbe8321SBarry Smith PetscErrorCode ierr; 1329d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n; 133055659b69SBarry Smith 13313a40ed3dSBarry Smith PetscFunctionBegin; 133228988994SBarry Smith if (ll) { 13337a97a34bSBarry Smith ierr = VecGetSize(ll,&m);CHKERRQ(ierr); 1334f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 1335e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size"); 1336da3a660dSBarry Smith for (i=0; i<m; i++) { 1337da3a660dSBarry Smith x = l[i]; 1338da3a660dSBarry Smith v = mat->v + i; 1339b43bac26SStefano Zampini for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;} 1340da3a660dSBarry Smith } 1341f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 1342eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr); 1343da3a660dSBarry Smith } 134428988994SBarry Smith if (rr) { 13457a97a34bSBarry Smith ierr = VecGetSize(rr,&n);CHKERRQ(ierr); 1346f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 1347e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size"); 1348da3a660dSBarry Smith for (i=0; i<n; i++) { 1349da3a660dSBarry Smith x = r[i]; 1350b43bac26SStefano Zampini v = mat->v + i*mat->lda; 13512205254eSKarl Rupp for (j=0; j<m; j++) (*v++) *= x; 1352da3a660dSBarry Smith } 1353f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 1354eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr); 1355da3a660dSBarry Smith } 13563a40ed3dSBarry Smith PetscFunctionReturn(0); 1357289bc588SBarry Smith } 1358289bc588SBarry Smith 1359e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm) 1360289bc588SBarry Smith { 1361c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 136287828ca2SBarry Smith PetscScalar *v = mat->v; 1363329f5518SBarry Smith PetscReal sum = 0.0; 1364d0f46423SBarry Smith PetscInt lda =mat->lda,m=A->rmap->n,i,j; 1365efee365bSSatish Balay PetscErrorCode ierr; 136655659b69SBarry Smith 13673a40ed3dSBarry Smith PetscFunctionBegin; 1368289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1369a5ce6ee0Svictorle if (lda>m) { 1370d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1371a5ce6ee0Svictorle v = mat->v+j*lda; 1372a5ce6ee0Svictorle for (i=0; i<m; i++) { 1373a5ce6ee0Svictorle sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1374a5ce6ee0Svictorle } 1375a5ce6ee0Svictorle } 1376a5ce6ee0Svictorle } else { 1377570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1378570b7f6dSBarry Smith PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n; 1379570b7f6dSBarry Smith *nrm = BLASnrm2_(&cnt,v,&one); 1380570b7f6dSBarry Smith } 1381570b7f6dSBarry Smith #else 1382d0f46423SBarry Smith for (i=0; i<A->cmap->n*A->rmap->n; i++) { 1383329f5518SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1384289bc588SBarry Smith } 1385a5ce6ee0Svictorle } 13868f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1387570b7f6dSBarry Smith #endif 1388dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr); 13893a40ed3dSBarry Smith } else if (type == NORM_1) { 1390064f8208SBarry Smith *nrm = 0.0; 1391d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 13921b807ce4Svictorle v = mat->v + j*mat->lda; 1393289bc588SBarry Smith sum = 0.0; 1394d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 139533a8263dSBarry Smith sum += PetscAbsScalar(*v); v++; 1396289bc588SBarry Smith } 1397064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1398289bc588SBarry Smith } 1399eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr); 14003a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1401064f8208SBarry Smith *nrm = 0.0; 1402d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1403289bc588SBarry Smith v = mat->v + j; 1404289bc588SBarry Smith sum = 0.0; 1405d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 14061b807ce4Svictorle sum += PetscAbsScalar(*v); v += mat->lda; 1407289bc588SBarry Smith } 1408064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1409289bc588SBarry Smith } 1410eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr); 1411e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm"); 14123a40ed3dSBarry Smith PetscFunctionReturn(0); 1413289bc588SBarry Smith } 1414289bc588SBarry Smith 1415e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg) 1416289bc588SBarry Smith { 1417c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense*)A->data; 141863ba0a88SBarry Smith PetscErrorCode ierr; 141967e560aaSBarry Smith 14203a40ed3dSBarry Smith PetscFunctionBegin; 1421b5a2b587SKris Buschelman switch (op) { 1422b5a2b587SKris Buschelman case MAT_ROW_ORIENTED: 14234e0d8c25SBarry Smith aij->roworiented = flg; 1424b5a2b587SKris Buschelman break; 1425512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1426b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 14273971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 14284e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 142913fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1430b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1431b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 14325021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 14335021d80fSJed Brown ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 14345021d80fSJed Brown break; 14355021d80fSJed Brown case MAT_SPD: 143677e54ba9SKris Buschelman case MAT_SYMMETRIC: 143777e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 14389a4540c5SBarry Smith case MAT_HERMITIAN: 14399a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 14405021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 144177e54ba9SKris Buschelman break; 1442b5a2b587SKris Buschelman default: 1443e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]); 14443a40ed3dSBarry Smith } 14453a40ed3dSBarry Smith PetscFunctionReturn(0); 1446289bc588SBarry Smith } 1447289bc588SBarry Smith 1448e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A) 14496f0a148fSBarry Smith { 1450ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)A->data; 14516849ba73SBarry Smith PetscErrorCode ierr; 1452d0f46423SBarry Smith PetscInt lda=l->lda,m=A->rmap->n,j; 14533a40ed3dSBarry Smith 14543a40ed3dSBarry Smith PetscFunctionBegin; 1455a5ce6ee0Svictorle if (lda>m) { 1456d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1457a5ce6ee0Svictorle ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr); 1458a5ce6ee0Svictorle } 1459a5ce6ee0Svictorle } else { 1460d0f46423SBarry Smith ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 1461a5ce6ee0Svictorle } 14623a40ed3dSBarry Smith PetscFunctionReturn(0); 14636f0a148fSBarry Smith } 14646f0a148fSBarry Smith 1465e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 14666f0a148fSBarry Smith { 146797b48c8fSBarry Smith PetscErrorCode ierr; 1468ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)A->data; 1469b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i,j; 147097b48c8fSBarry Smith PetscScalar *slot,*bb; 147197b48c8fSBarry Smith const PetscScalar *xx; 147255659b69SBarry Smith 14733a40ed3dSBarry Smith PetscFunctionBegin; 1474b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG) 1475b9679d65SBarry Smith for (i=0; i<N; i++) { 1476b9679d65SBarry Smith if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed"); 1477b9679d65SBarry Smith if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n); 1478b9679d65SBarry Smith } 1479b9679d65SBarry Smith #endif 1480b9679d65SBarry Smith 148197b48c8fSBarry Smith /* fix right hand side if needed */ 148297b48c8fSBarry Smith if (x && b) { 148397b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 148497b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 14852205254eSKarl Rupp for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]]; 148697b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 148797b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 148897b48c8fSBarry Smith } 148997b48c8fSBarry Smith 14906f0a148fSBarry Smith for (i=0; i<N; i++) { 14916f0a148fSBarry Smith slot = l->v + rows[i]; 1492b9679d65SBarry Smith for (j=0; j<n; j++) { *slot = 0.0; slot += m;} 14936f0a148fSBarry Smith } 1494f4df32b1SMatthew Knepley if (diag != 0.0) { 1495b9679d65SBarry Smith if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices"); 14966f0a148fSBarry Smith for (i=0; i<N; i++) { 1497b9679d65SBarry Smith slot = l->v + (m+1)*rows[i]; 1498f4df32b1SMatthew Knepley *slot = diag; 14996f0a148fSBarry Smith } 15006f0a148fSBarry Smith } 15013a40ed3dSBarry Smith PetscFunctionReturn(0); 15026f0a148fSBarry Smith } 1503557bce09SLois Curfman McInnes 1504e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[]) 150564e87e97SBarry Smith { 1506c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 15073a40ed3dSBarry Smith 15083a40ed3dSBarry Smith PetscFunctionBegin; 1509e32f2f54SBarry Smith if (mat->lda != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get array for Dense matrices with LDA different from number of rows"); 151064e87e97SBarry Smith *array = mat->v; 15113a40ed3dSBarry Smith PetscFunctionReturn(0); 151264e87e97SBarry Smith } 15130754003eSLois Curfman McInnes 1514e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[]) 1515ff14e315SSatish Balay { 15163a40ed3dSBarry Smith PetscFunctionBegin; 151709b544d4SBarry Smith *array = 0; /* user cannot accidently use the array later */ 15183a40ed3dSBarry Smith PetscFunctionReturn(0); 1519ff14e315SSatish Balay } 15200754003eSLois Curfman McInnes 1521dec5eb66SMatthew G Knepley /*@C 15228c778c55SBarry Smith MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored 152373a71a0fSBarry Smith 152473a71a0fSBarry Smith Not Collective 152573a71a0fSBarry Smith 152673a71a0fSBarry Smith Input Parameter: 1527579dbff0SBarry Smith . mat - a MATSEQDENSE or MATMPIDENSE matrix 152873a71a0fSBarry Smith 152973a71a0fSBarry Smith Output Parameter: 153073a71a0fSBarry Smith . array - pointer to the data 153173a71a0fSBarry Smith 153273a71a0fSBarry Smith Level: intermediate 153373a71a0fSBarry Smith 15348c778c55SBarry Smith .seealso: MatDenseRestoreArray() 153573a71a0fSBarry Smith @*/ 15368c778c55SBarry Smith PetscErrorCode MatDenseGetArray(Mat A,PetscScalar **array) 153773a71a0fSBarry Smith { 153873a71a0fSBarry Smith PetscErrorCode ierr; 153973a71a0fSBarry Smith 154073a71a0fSBarry Smith PetscFunctionBegin; 15418c778c55SBarry Smith ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 154273a71a0fSBarry Smith PetscFunctionReturn(0); 154373a71a0fSBarry Smith } 154473a71a0fSBarry Smith 1545dec5eb66SMatthew G Knepley /*@C 1546579dbff0SBarry Smith MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray() 154773a71a0fSBarry Smith 154873a71a0fSBarry Smith Not Collective 154973a71a0fSBarry Smith 155073a71a0fSBarry Smith Input Parameters: 1551579dbff0SBarry Smith . mat - a MATSEQDENSE or MATMPIDENSE matrix 155273a71a0fSBarry Smith . array - pointer to the data 155373a71a0fSBarry Smith 155473a71a0fSBarry Smith Level: intermediate 155573a71a0fSBarry Smith 15568c778c55SBarry Smith .seealso: MatDenseGetArray() 155773a71a0fSBarry Smith @*/ 15588c778c55SBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A,PetscScalar **array) 155973a71a0fSBarry Smith { 156073a71a0fSBarry Smith PetscErrorCode ierr; 156173a71a0fSBarry Smith 156273a71a0fSBarry Smith PetscFunctionBegin; 15638c778c55SBarry Smith ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 156473a71a0fSBarry Smith PetscFunctionReturn(0); 156573a71a0fSBarry Smith } 156673a71a0fSBarry Smith 15677dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B) 15680754003eSLois Curfman McInnes { 1569c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 15706849ba73SBarry Smith PetscErrorCode ierr; 15715d0c19d7SBarry Smith PetscInt i,j,nrows,ncols; 15725d0c19d7SBarry Smith const PetscInt *irow,*icol; 157387828ca2SBarry Smith PetscScalar *av,*bv,*v = mat->v; 15740754003eSLois Curfman McInnes Mat newmat; 15750754003eSLois Curfman McInnes 15763a40ed3dSBarry Smith PetscFunctionBegin; 157778b31e54SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 157878b31e54SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1579e03a110bSBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1580e03a110bSBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 15810754003eSLois Curfman McInnes 1582182d2002SSatish Balay /* Check submatrixcall */ 1583182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 158413f74950SBarry Smith PetscInt n_cols,n_rows; 1585182d2002SSatish Balay ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 158621a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 1587f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 1588c61587bbSBarry Smith ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr); 158921a2c019SBarry Smith } 1590182d2002SSatish Balay newmat = *B; 1591182d2002SSatish Balay } else { 15920754003eSLois Curfman McInnes /* Create and fill new matrix */ 1593ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr); 1594f69a0ea3SMatthew Knepley ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr); 15957adad957SLisandro Dalcin ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 15960298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr); 1597182d2002SSatish Balay } 1598182d2002SSatish Balay 1599182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 1600182d2002SSatish Balay bv = ((Mat_SeqDense*)newmat->data)->v; 1601182d2002SSatish Balay 1602182d2002SSatish Balay for (i=0; i<ncols; i++) { 16036de62eeeSBarry Smith av = v + mat->lda*icol[i]; 16042205254eSKarl Rupp for (j=0; j<nrows; j++) *bv++ = av[irow[j]]; 16050754003eSLois Curfman McInnes } 1606182d2002SSatish Balay 1607182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 16086d4a8577SBarry Smith ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16096d4a8577SBarry Smith ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16100754003eSLois Curfman McInnes 16110754003eSLois Curfman McInnes /* Free work space */ 161278b31e54SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 161378b31e54SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1614182d2002SSatish Balay *B = newmat; 16153a40ed3dSBarry Smith PetscFunctionReturn(0); 16160754003eSLois Curfman McInnes } 16170754003eSLois Curfman McInnes 16187dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1619905e6a2fSBarry Smith { 16206849ba73SBarry Smith PetscErrorCode ierr; 162113f74950SBarry Smith PetscInt i; 1622905e6a2fSBarry Smith 16233a40ed3dSBarry Smith PetscFunctionBegin; 1624905e6a2fSBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1625df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 1626905e6a2fSBarry Smith } 1627905e6a2fSBarry Smith 1628905e6a2fSBarry Smith for (i=0; i<n; i++) { 16297dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1630905e6a2fSBarry Smith } 16313a40ed3dSBarry Smith PetscFunctionReturn(0); 1632905e6a2fSBarry Smith } 1633905e6a2fSBarry Smith 1634e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode) 1635c0aa2d19SHong Zhang { 1636c0aa2d19SHong Zhang PetscFunctionBegin; 1637c0aa2d19SHong Zhang PetscFunctionReturn(0); 1638c0aa2d19SHong Zhang } 1639c0aa2d19SHong Zhang 1640e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode) 1641c0aa2d19SHong Zhang { 1642c0aa2d19SHong Zhang PetscFunctionBegin; 1643c0aa2d19SHong Zhang PetscFunctionReturn(0); 1644c0aa2d19SHong Zhang } 1645c0aa2d19SHong Zhang 1646e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str) 16474b0e389bSBarry Smith { 16484b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data; 16496849ba73SBarry Smith PetscErrorCode ierr; 1650d0f46423SBarry Smith PetscInt lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j; 16513a40ed3dSBarry Smith 16523a40ed3dSBarry Smith PetscFunctionBegin; 165333f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 165433f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 1655cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 16563a40ed3dSBarry Smith PetscFunctionReturn(0); 16573a40ed3dSBarry Smith } 1658e32f2f54SBarry Smith if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)"); 1659a5ce6ee0Svictorle if (lda1>m || lda2>m) { 16600dbb7854Svictorle for (j=0; j<n; j++) { 1661a5ce6ee0Svictorle ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr); 1662a5ce6ee0Svictorle } 1663a5ce6ee0Svictorle } else { 1664d0f46423SBarry Smith ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 1665a5ce6ee0Svictorle } 1666273d9f13SBarry Smith PetscFunctionReturn(0); 1667273d9f13SBarry Smith } 1668273d9f13SBarry Smith 1669e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A) 1670273d9f13SBarry Smith { 1671dfbe8321SBarry Smith PetscErrorCode ierr; 1672273d9f13SBarry Smith 1673273d9f13SBarry Smith PetscFunctionBegin; 1674273d9f13SBarry Smith ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr); 16753a40ed3dSBarry Smith PetscFunctionReturn(0); 16764b0e389bSBarry Smith } 16774b0e389bSBarry Smith 1678ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A) 1679ba337c44SJed Brown { 1680ba337c44SJed Brown Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1681ba337c44SJed Brown PetscInt i,nz = A->rmap->n*A->cmap->n; 1682ba337c44SJed Brown PetscScalar *aa = a->v; 1683ba337c44SJed Brown 1684ba337c44SJed Brown PetscFunctionBegin; 1685ba337c44SJed Brown for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]); 1686ba337c44SJed Brown PetscFunctionReturn(0); 1687ba337c44SJed Brown } 1688ba337c44SJed Brown 1689ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A) 1690ba337c44SJed Brown { 1691ba337c44SJed Brown Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1692ba337c44SJed Brown PetscInt i,nz = A->rmap->n*A->cmap->n; 1693ba337c44SJed Brown PetscScalar *aa = a->v; 1694ba337c44SJed Brown 1695ba337c44SJed Brown PetscFunctionBegin; 1696ba337c44SJed Brown for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1697ba337c44SJed Brown PetscFunctionReturn(0); 1698ba337c44SJed Brown } 1699ba337c44SJed Brown 1700ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 1701ba337c44SJed Brown { 1702ba337c44SJed Brown Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1703ba337c44SJed Brown PetscInt i,nz = A->rmap->n*A->cmap->n; 1704ba337c44SJed Brown PetscScalar *aa = a->v; 1705ba337c44SJed Brown 1706ba337c44SJed Brown PetscFunctionBegin; 1707ba337c44SJed Brown for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1708ba337c44SJed Brown PetscFunctionReturn(0); 1709ba337c44SJed Brown } 1710284134d9SBarry Smith 1711a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 1712150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 1713a9fe9ddaSSatish Balay { 1714a9fe9ddaSSatish Balay PetscErrorCode ierr; 1715a9fe9ddaSSatish Balay 1716a9fe9ddaSSatish Balay PetscFunctionBegin; 1717a9fe9ddaSSatish Balay if (scall == MAT_INITIAL_MATRIX) { 17183ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1719a9fe9ddaSSatish Balay ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr); 17203ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1721a9fe9ddaSSatish Balay } 17223ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 1723a9fe9ddaSSatish Balay ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr); 17243ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 1725a9fe9ddaSSatish Balay PetscFunctionReturn(0); 1726a9fe9ddaSSatish Balay } 1727a9fe9ddaSSatish Balay 1728a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C) 1729a9fe9ddaSSatish Balay { 1730ee16a9a1SHong Zhang PetscErrorCode ierr; 1731d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 1732ee16a9a1SHong Zhang Mat Cmat; 1733a9fe9ddaSSatish Balay 1734ee16a9a1SHong Zhang PetscFunctionBegin; 1735e32f2f54SBarry Smith if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n); 1736ee16a9a1SHong Zhang ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr); 1737ee16a9a1SHong Zhang ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 1738ee16a9a1SHong Zhang ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 17390298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 1740d73949e8SHong Zhang 1741ee16a9a1SHong Zhang *C = Cmat; 1742ee16a9a1SHong Zhang PetscFunctionReturn(0); 1743ee16a9a1SHong Zhang } 1744a9fe9ddaSSatish Balay 1745a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 1746a9fe9ddaSSatish Balay { 1747a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1748a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense*)B->data; 1749a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense*)C->data; 17500805154bSBarry Smith PetscBLASInt m,n,k; 1751a9fe9ddaSSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 1752c5df96a5SBarry Smith PetscErrorCode ierr; 1753fd4e9aacSBarry Smith PetscBool flg; 1754a9fe9ddaSSatish Balay 1755a9fe9ddaSSatish Balay PetscFunctionBegin; 1756fd4e9aacSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr); 1757fd4e9aacSBarry Smith if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense"); 1758fd4e9aacSBarry Smith 1759fd4e9aacSBarry Smith /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/ 1760fd4e9aacSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr); 1761fd4e9aacSBarry Smith if (flg) { 1762fd4e9aacSBarry Smith C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense; 1763fd4e9aacSBarry Smith ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr); 1764fd4e9aacSBarry Smith PetscFunctionReturn(0); 1765fd4e9aacSBarry Smith } 1766fd4e9aacSBarry Smith 1767fd4e9aacSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr); 1768fd4e9aacSBarry Smith if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense"); 1769*8208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr); 1770*8208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr); 1771c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr); 17725ca1cc5dSStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda)); 1773a9fe9ddaSSatish Balay PetscFunctionReturn(0); 1774a9fe9ddaSSatish Balay } 1775a9fe9ddaSSatish Balay 177675648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 1777a9fe9ddaSSatish Balay { 1778a9fe9ddaSSatish Balay PetscErrorCode ierr; 1779a9fe9ddaSSatish Balay 1780a9fe9ddaSSatish Balay PetscFunctionBegin; 1781a9fe9ddaSSatish Balay if (scall == MAT_INITIAL_MATRIX) { 17823ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 178375648e8dSHong Zhang ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr); 17843ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1785a9fe9ddaSSatish Balay } 17863ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 178775648e8dSHong Zhang ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr); 17883ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 1789a9fe9ddaSSatish Balay PetscFunctionReturn(0); 1790a9fe9ddaSSatish Balay } 1791a9fe9ddaSSatish Balay 179275648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C) 1793a9fe9ddaSSatish Balay { 1794ee16a9a1SHong Zhang PetscErrorCode ierr; 1795d0f46423SBarry Smith PetscInt m=A->cmap->n,n=B->cmap->n; 1796ee16a9a1SHong Zhang Mat Cmat; 1797a9fe9ddaSSatish Balay 1798ee16a9a1SHong Zhang PetscFunctionBegin; 1799e32f2f54SBarry Smith if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->rmap->n %d != B->rmap->n %d\n",A->rmap->n,B->rmap->n); 1800ee16a9a1SHong Zhang ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr); 1801ee16a9a1SHong Zhang ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 1802ee16a9a1SHong Zhang ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 18030298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 18042205254eSKarl Rupp 1805ee16a9a1SHong Zhang Cmat->assembled = PETSC_TRUE; 18062205254eSKarl Rupp 1807ee16a9a1SHong Zhang *C = Cmat; 1808ee16a9a1SHong Zhang PetscFunctionReturn(0); 1809ee16a9a1SHong Zhang } 1810a9fe9ddaSSatish Balay 181175648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 1812a9fe9ddaSSatish Balay { 1813a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1814a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense*)B->data; 1815a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense*)C->data; 18160805154bSBarry Smith PetscBLASInt m,n,k; 1817a9fe9ddaSSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 1818c5df96a5SBarry Smith PetscErrorCode ierr; 1819a9fe9ddaSSatish Balay 1820a9fe9ddaSSatish Balay PetscFunctionBegin; 1821*8208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr); 1822*8208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr); 1823c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr); 18245ca1cc5dSStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda)); 1825a9fe9ddaSSatish Balay PetscFunctionReturn(0); 1826a9fe9ddaSSatish Balay } 1827985db425SBarry Smith 1828e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[]) 1829985db425SBarry Smith { 1830985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1831985db425SBarry Smith PetscErrorCode ierr; 1832d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 1833985db425SBarry Smith PetscScalar *x; 1834985db425SBarry Smith MatScalar *aa = a->v; 1835985db425SBarry Smith 1836985db425SBarry Smith PetscFunctionBegin; 1837e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1838985db425SBarry Smith 1839985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 1840985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1841985db425SBarry Smith ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 1842e32f2f54SBarry Smith if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1843985db425SBarry Smith for (i=0; i<m; i++) { 1844985db425SBarry Smith x[i] = aa[i]; if (idx) idx[i] = 0; 1845985db425SBarry Smith for (j=1; j<n; j++) { 1846985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;} 1847985db425SBarry Smith } 1848985db425SBarry Smith } 1849985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1850985db425SBarry Smith PetscFunctionReturn(0); 1851985db425SBarry Smith } 1852985db425SBarry Smith 1853e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[]) 1854985db425SBarry Smith { 1855985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1856985db425SBarry Smith PetscErrorCode ierr; 1857d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 1858985db425SBarry Smith PetscScalar *x; 1859985db425SBarry Smith PetscReal atmp; 1860985db425SBarry Smith MatScalar *aa = a->v; 1861985db425SBarry Smith 1862985db425SBarry Smith PetscFunctionBegin; 1863e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1864985db425SBarry Smith 1865985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 1866985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1867985db425SBarry Smith ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 1868e32f2f54SBarry Smith if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1869985db425SBarry Smith for (i=0; i<m; i++) { 18709189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 1871985db425SBarry Smith for (j=1; j<n; j++) { 1872985db425SBarry Smith atmp = PetscAbsScalar(aa[i+m*j]); 1873985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;} 1874985db425SBarry Smith } 1875985db425SBarry Smith } 1876985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1877985db425SBarry Smith PetscFunctionReturn(0); 1878985db425SBarry Smith } 1879985db425SBarry Smith 1880e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[]) 1881985db425SBarry Smith { 1882985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1883985db425SBarry Smith PetscErrorCode ierr; 1884d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 1885985db425SBarry Smith PetscScalar *x; 1886985db425SBarry Smith MatScalar *aa = a->v; 1887985db425SBarry Smith 1888985db425SBarry Smith PetscFunctionBegin; 1889e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1890985db425SBarry Smith 1891985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 1892985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1893985db425SBarry Smith ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 1894e32f2f54SBarry Smith if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1895985db425SBarry Smith for (i=0; i<m; i++) { 1896985db425SBarry Smith x[i] = aa[i]; if (idx) idx[i] = 0; 1897985db425SBarry Smith for (j=1; j<n; j++) { 1898985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;} 1899985db425SBarry Smith } 1900985db425SBarry Smith } 1901985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1902985db425SBarry Smith PetscFunctionReturn(0); 1903985db425SBarry Smith } 1904985db425SBarry Smith 1905e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col) 19068d0534beSBarry Smith { 19078d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 19088d0534beSBarry Smith PetscErrorCode ierr; 19098d0534beSBarry Smith PetscScalar *x; 19108d0534beSBarry Smith 19118d0534beSBarry Smith PetscFunctionBegin; 1912e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 19138d0534beSBarry Smith 19148d0534beSBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1915d0f46423SBarry Smith ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 19168d0534beSBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 19178d0534beSBarry Smith PetscFunctionReturn(0); 19188d0534beSBarry Smith } 19198d0534beSBarry Smith 19200716a85fSBarry Smith 19210716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms) 19220716a85fSBarry Smith { 19230716a85fSBarry Smith PetscErrorCode ierr; 19240716a85fSBarry Smith PetscInt i,j,m,n; 19250716a85fSBarry Smith PetscScalar *a; 19260716a85fSBarry Smith 19270716a85fSBarry Smith PetscFunctionBegin; 19280716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 19290716a85fSBarry Smith ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr); 19308c778c55SBarry Smith ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr); 19310716a85fSBarry Smith if (type == NORM_2) { 19320716a85fSBarry Smith for (i=0; i<n; i++) { 19330716a85fSBarry Smith for (j=0; j<m; j++) { 19340716a85fSBarry Smith norms[i] += PetscAbsScalar(a[j]*a[j]); 19350716a85fSBarry Smith } 19360716a85fSBarry Smith a += m; 19370716a85fSBarry Smith } 19380716a85fSBarry Smith } else if (type == NORM_1) { 19390716a85fSBarry Smith for (i=0; i<n; i++) { 19400716a85fSBarry Smith for (j=0; j<m; j++) { 19410716a85fSBarry Smith norms[i] += PetscAbsScalar(a[j]); 19420716a85fSBarry Smith } 19430716a85fSBarry Smith a += m; 19440716a85fSBarry Smith } 19450716a85fSBarry Smith } else if (type == NORM_INFINITY) { 19460716a85fSBarry Smith for (i=0; i<n; i++) { 19470716a85fSBarry Smith for (j=0; j<m; j++) { 19480716a85fSBarry Smith norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]); 19490716a85fSBarry Smith } 19500716a85fSBarry Smith a += m; 19510716a85fSBarry Smith } 1952ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType"); 19538c778c55SBarry Smith ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr); 19540716a85fSBarry Smith if (type == NORM_2) { 19558f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 19560716a85fSBarry Smith } 19570716a85fSBarry Smith PetscFunctionReturn(0); 19580716a85fSBarry Smith } 19590716a85fSBarry Smith 196073a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqDense(Mat x,PetscRandom rctx) 196173a71a0fSBarry Smith { 196273a71a0fSBarry Smith PetscErrorCode ierr; 196373a71a0fSBarry Smith PetscScalar *a; 196473a71a0fSBarry Smith PetscInt m,n,i; 196573a71a0fSBarry Smith 196673a71a0fSBarry Smith PetscFunctionBegin; 196773a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 19688c778c55SBarry Smith ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr); 196973a71a0fSBarry Smith for (i=0; i<m*n; i++) { 197073a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr); 197173a71a0fSBarry Smith } 19728c778c55SBarry Smith ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr); 197373a71a0fSBarry Smith PetscFunctionReturn(0); 197473a71a0fSBarry Smith } 197573a71a0fSBarry Smith 19763b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool *missing,PetscInt *d) 19773b49f96aSBarry Smith { 19783b49f96aSBarry Smith PetscFunctionBegin; 19793b49f96aSBarry Smith *missing = PETSC_FALSE; 19803b49f96aSBarry Smith PetscFunctionReturn(0); 19813b49f96aSBarry Smith } 198273a71a0fSBarry Smith 1983abc3b08eSStefano Zampini 1984289bc588SBarry Smith /* -------------------------------------------------------------------*/ 1985a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense, 1986905e6a2fSBarry Smith MatGetRow_SeqDense, 1987905e6a2fSBarry Smith MatRestoreRow_SeqDense, 1988905e6a2fSBarry Smith MatMult_SeqDense, 198997304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 19907c922b88SBarry Smith MatMultTranspose_SeqDense, 19917c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 1992db4efbfdSBarry Smith 0, 1993db4efbfdSBarry Smith 0, 1994db4efbfdSBarry Smith 0, 1995db4efbfdSBarry Smith /* 10*/ 0, 1996905e6a2fSBarry Smith MatLUFactor_SeqDense, 1997905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 199841f059aeSBarry Smith MatSOR_SeqDense, 1999ec8511deSBarry Smith MatTranspose_SeqDense, 200097304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 2001905e6a2fSBarry Smith MatEqual_SeqDense, 2002905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 2003905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 2004905e6a2fSBarry Smith MatNorm_SeqDense, 2005c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 2006c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 2007905e6a2fSBarry Smith MatSetOption_SeqDense, 2008905e6a2fSBarry Smith MatZeroEntries_SeqDense, 2009d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 2010db4efbfdSBarry Smith 0, 2011db4efbfdSBarry Smith 0, 2012db4efbfdSBarry Smith 0, 2013db4efbfdSBarry Smith 0, 20144994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 2015273d9f13SBarry Smith 0, 2016905e6a2fSBarry Smith 0, 201773a71a0fSBarry Smith 0, 201873a71a0fSBarry Smith 0, 2019d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 2020a5ae1ecdSBarry Smith 0, 2021a5ae1ecdSBarry Smith 0, 2022a5ae1ecdSBarry Smith 0, 2023a5ae1ecdSBarry Smith 0, 2024d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 20257dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 2026a5ae1ecdSBarry Smith 0, 20274b0e389bSBarry Smith MatGetValues_SeqDense, 2028a5ae1ecdSBarry Smith MatCopy_SeqDense, 2029d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 2030a5ae1ecdSBarry Smith MatScale_SeqDense, 20317d68702bSBarry Smith MatShift_Basic, 2032a5ae1ecdSBarry Smith 0, 20333f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 203473a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 2035a5ae1ecdSBarry Smith 0, 2036a5ae1ecdSBarry Smith 0, 2037a5ae1ecdSBarry Smith 0, 2038a5ae1ecdSBarry Smith 0, 2039d519adbfSMatthew Knepley /* 54*/ 0, 2040a5ae1ecdSBarry Smith 0, 2041a5ae1ecdSBarry Smith 0, 2042a5ae1ecdSBarry Smith 0, 2043a5ae1ecdSBarry Smith 0, 2044d519adbfSMatthew Knepley /* 59*/ 0, 2045e03a110bSBarry Smith MatDestroy_SeqDense, 2046e03a110bSBarry Smith MatView_SeqDense, 2047357abbc8SBarry Smith 0, 204897304618SKris Buschelman 0, 2049d519adbfSMatthew Knepley /* 64*/ 0, 205097304618SKris Buschelman 0, 205197304618SKris Buschelman 0, 205297304618SKris Buschelman 0, 205397304618SKris Buschelman 0, 2054d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 205597304618SKris Buschelman 0, 205697304618SKris Buschelman 0, 205797304618SKris Buschelman 0, 205897304618SKris Buschelman 0, 2059d519adbfSMatthew Knepley /* 74*/ 0, 206097304618SKris Buschelman 0, 206197304618SKris Buschelman 0, 206297304618SKris Buschelman 0, 206397304618SKris Buschelman 0, 2064d519adbfSMatthew Knepley /* 79*/ 0, 206597304618SKris Buschelman 0, 206697304618SKris Buschelman 0, 206797304618SKris Buschelman 0, 20685bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 2069865e5f61SKris Buschelman 0, 20701cbb95d3SBarry Smith MatIsHermitian_SeqDense, 2071865e5f61SKris Buschelman 0, 2072865e5f61SKris Buschelman 0, 2073865e5f61SKris Buschelman 0, 2074d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqDense_SeqDense, 2075a9fe9ddaSSatish Balay MatMatMultSymbolic_SeqDense_SeqDense, 2076a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 2077abc3b08eSStefano Zampini MatPtAP_SeqDense_SeqDense, 2078abc3b08eSStefano Zampini MatPtAPSymbolic_SeqDense_SeqDense, 2079abc3b08eSStefano Zampini /* 94*/ MatPtAPNumeric_SeqDense_SeqDense, 20805df89d91SHong Zhang 0, 20815df89d91SHong Zhang 0, 20825df89d91SHong Zhang 0, 2083284134d9SBarry Smith 0, 2084d519adbfSMatthew Knepley /* 99*/ 0, 2085284134d9SBarry Smith 0, 2086284134d9SBarry Smith 0, 2087ba337c44SJed Brown MatConjugate_SeqDense, 2088f73d5cc4SBarry Smith 0, 2089ba337c44SJed Brown /*104*/ 0, 2090ba337c44SJed Brown MatRealPart_SeqDense, 2091ba337c44SJed Brown MatImaginaryPart_SeqDense, 2092985db425SBarry Smith 0, 2093985db425SBarry Smith 0, 2094*8208b9aeSStefano Zampini /*109*/ 0, 2095985db425SBarry Smith 0, 20968d0534beSBarry Smith MatGetRowMin_SeqDense, 2097aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 20983b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 2099aabbc4fbSShri Abhyankar /*114*/ 0, 2100aabbc4fbSShri Abhyankar 0, 2101aabbc4fbSShri Abhyankar 0, 2102aabbc4fbSShri Abhyankar 0, 2103aabbc4fbSShri Abhyankar 0, 2104aabbc4fbSShri Abhyankar /*119*/ 0, 2105aabbc4fbSShri Abhyankar 0, 2106aabbc4fbSShri Abhyankar 0, 21070716a85fSBarry Smith 0, 21080716a85fSBarry Smith 0, 21090716a85fSBarry Smith /*124*/ 0, 21105df89d91SHong Zhang MatGetColumnNorms_SeqDense, 21115df89d91SHong Zhang 0, 21125df89d91SHong Zhang 0, 21135df89d91SHong Zhang 0, 21145df89d91SHong Zhang /*129*/ 0, 211575648e8dSHong Zhang MatTransposeMatMult_SeqDense_SeqDense, 211675648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqDense_SeqDense, 211775648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 21183964eb88SJed Brown 0, 21193964eb88SJed Brown /*134*/ 0, 21203964eb88SJed Brown 0, 21213964eb88SJed Brown 0, 21223964eb88SJed Brown 0, 21233964eb88SJed Brown 0, 21243964eb88SJed Brown /*139*/ 0, 2125f9426fe0SMark Adams 0, 21263964eb88SJed Brown 0 2127985db425SBarry Smith }; 212890ace30eSBarry Smith 21294b828684SBarry Smith /*@C 2130fafbff53SBarry Smith MatCreateSeqDense - Creates a sequential dense matrix that 2131d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 2132d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 2133289bc588SBarry Smith 2134db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2135db81eaa0SLois Curfman McInnes 213620563c6bSBarry Smith Input Parameters: 2137db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 21380c775827SLois Curfman McInnes . m - number of rows 213918f449edSLois Curfman McInnes . n - number of columns 21400298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 2141dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 214220563c6bSBarry Smith 214320563c6bSBarry Smith Output Parameter: 214444cd7ae7SLois Curfman McInnes . A - the matrix 214520563c6bSBarry Smith 2146b259b22eSLois Curfman McInnes Notes: 214718f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 214818f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 21490298fd71SBarry Smith set data=NULL. 215018f449edSLois Curfman McInnes 2151027ccd11SLois Curfman McInnes Level: intermediate 2152027ccd11SLois Curfman McInnes 2153dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS 2154d65003e9SLois Curfman McInnes 215569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues() 215620563c6bSBarry Smith @*/ 21577087cfbeSBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A) 2158289bc588SBarry Smith { 2159dfbe8321SBarry Smith PetscErrorCode ierr; 21603b2fbd54SBarry Smith 21613a40ed3dSBarry Smith PetscFunctionBegin; 2162f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 2163f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 2164273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr); 2165273d9f13SBarry Smith ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr); 2166273d9f13SBarry Smith PetscFunctionReturn(0); 2167273d9f13SBarry Smith } 2168273d9f13SBarry Smith 2169273d9f13SBarry Smith /*@C 2170273d9f13SBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements 2171273d9f13SBarry Smith 2172273d9f13SBarry Smith Collective on MPI_Comm 2173273d9f13SBarry Smith 2174273d9f13SBarry Smith Input Parameters: 21751c4f3114SJed Brown + B - the matrix 21760298fd71SBarry Smith - data - the array (or NULL) 2177273d9f13SBarry Smith 2178273d9f13SBarry Smith Notes: 2179273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 2180273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 2181284134d9SBarry Smith need not call this routine. 2182273d9f13SBarry Smith 2183273d9f13SBarry Smith Level: intermediate 2184273d9f13SBarry Smith 2185273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS 2186273d9f13SBarry Smith 218769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA() 2188867c911aSBarry Smith 2189273d9f13SBarry Smith @*/ 21907087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetPreallocation(Mat B,PetscScalar data[]) 2191273d9f13SBarry Smith { 21924ac538c5SBarry Smith PetscErrorCode ierr; 2193a23d5eceSKris Buschelman 2194a23d5eceSKris Buschelman PetscFunctionBegin; 21954ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr); 2196a23d5eceSKris Buschelman PetscFunctionReturn(0); 2197a23d5eceSKris Buschelman } 2198a23d5eceSKris Buschelman 21997087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data) 2200a23d5eceSKris Buschelman { 2201273d9f13SBarry Smith Mat_SeqDense *b; 2202dfbe8321SBarry Smith PetscErrorCode ierr; 2203273d9f13SBarry Smith 2204273d9f13SBarry Smith PetscFunctionBegin; 2205273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2206a868139aSShri Abhyankar 220734ef9618SShri Abhyankar ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 220834ef9618SShri Abhyankar ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 220934ef9618SShri Abhyankar 2210273d9f13SBarry Smith b = (Mat_SeqDense*)B->data; 221186d161a7SShri Abhyankar b->Mmax = B->rmap->n; 221286d161a7SShri Abhyankar b->Nmax = B->cmap->n; 221386d161a7SShri Abhyankar if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n; 221486d161a7SShri Abhyankar 2215220afb94SBarry Smith ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr); 22169e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 22179e8f95c4SLisandro Dalcin if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); } 2218e92229d0SSatish Balay ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr); 22193bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr); 22202205254eSKarl Rupp 22219e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 2222273d9f13SBarry Smith } else { /* user-allocated storage */ 22239e8f95c4SLisandro Dalcin if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); } 2224273d9f13SBarry Smith b->v = data; 2225273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 2226273d9f13SBarry Smith } 22270450473dSBarry Smith B->assembled = PETSC_TRUE; 2228273d9f13SBarry Smith PetscFunctionReturn(0); 2229273d9f13SBarry Smith } 2230273d9f13SBarry Smith 223165b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 2232cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 22338baccfbdSHong Zhang { 2234d77f618aSHong Zhang Mat mat_elemental; 2235d77f618aSHong Zhang PetscErrorCode ierr; 2236d77f618aSHong Zhang PetscScalar *array,*v_colwise; 2237d77f618aSHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols; 2238d77f618aSHong Zhang 22398baccfbdSHong Zhang PetscFunctionBegin; 2240d77f618aSHong Zhang ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr); 2241d77f618aSHong Zhang ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr); 2242d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 2243d77f618aSHong Zhang k = 0; 2244d77f618aSHong Zhang for (j=0; j<N; j++) { 2245d77f618aSHong Zhang cols[j] = j; 2246d77f618aSHong Zhang for (i=0; i<M; i++) { 2247d77f618aSHong Zhang v_colwise[j*M+i] = array[k++]; 2248d77f618aSHong Zhang } 2249d77f618aSHong Zhang } 2250d77f618aSHong Zhang for (i=0; i<M; i++) { 2251d77f618aSHong Zhang rows[i] = i; 2252d77f618aSHong Zhang } 2253d77f618aSHong Zhang ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr); 2254d77f618aSHong Zhang 2255d77f618aSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 2256d77f618aSHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2257d77f618aSHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 2258d77f618aSHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 2259d77f618aSHong Zhang 2260d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 2261d77f618aSHong Zhang ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr); 2262d77f618aSHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2263d77f618aSHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2264d77f618aSHong Zhang ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr); 2265d77f618aSHong Zhang 2266511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 226728be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 2268d77f618aSHong Zhang } else { 2269d77f618aSHong Zhang *newmat = mat_elemental; 2270d77f618aSHong Zhang } 22718baccfbdSHong Zhang PetscFunctionReturn(0); 22728baccfbdSHong Zhang } 227365b80a83SHong Zhang #endif 22748baccfbdSHong Zhang 22751b807ce4Svictorle /*@C 22761b807ce4Svictorle MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array 22771b807ce4Svictorle 22781b807ce4Svictorle Input parameter: 22791b807ce4Svictorle + A - the matrix 22801b807ce4Svictorle - lda - the leading dimension 22811b807ce4Svictorle 22821b807ce4Svictorle Notes: 2283867c911aSBarry Smith This routine is to be used in conjunction with MatSeqDenseSetPreallocation(); 22841b807ce4Svictorle it asserts that the preallocation has a leading dimension (the LDA parameter 22851b807ce4Svictorle of Blas and Lapack fame) larger than M, the first dimension of the matrix. 22861b807ce4Svictorle 22871b807ce4Svictorle Level: intermediate 22881b807ce4Svictorle 22891b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS 22901b807ce4Svictorle 2291284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize() 2292867c911aSBarry Smith 22931b807ce4Svictorle @*/ 22947087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetLDA(Mat B,PetscInt lda) 22951b807ce4Svictorle { 22961b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense*)B->data; 229721a2c019SBarry Smith 22981b807ce4Svictorle PetscFunctionBegin; 2299e32f2f54SBarry Smith if (lda < B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"LDA %D must be at least matrix dimension %D",lda,B->rmap->n); 23001b807ce4Svictorle b->lda = lda; 230121a2c019SBarry Smith b->changelda = PETSC_FALSE; 230221a2c019SBarry Smith b->Mmax = PetscMax(b->Mmax,lda); 23031b807ce4Svictorle PetscFunctionReturn(0); 23041b807ce4Svictorle } 23051b807ce4Svictorle 23060bad9183SKris Buschelman /*MC 2307fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 23080bad9183SKris Buschelman 23090bad9183SKris Buschelman Options Database Keys: 23100bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions() 23110bad9183SKris Buschelman 23120bad9183SKris Buschelman Level: beginner 23130bad9183SKris Buschelman 231489665df3SBarry Smith .seealso: MatCreateSeqDense() 231589665df3SBarry Smith 23160bad9183SKris Buschelman M*/ 23170bad9183SKris Buschelman 23188cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B) 2319273d9f13SBarry Smith { 2320273d9f13SBarry Smith Mat_SeqDense *b; 2321dfbe8321SBarry Smith PetscErrorCode ierr; 23227c334f02SBarry Smith PetscMPIInt size; 2323273d9f13SBarry Smith 2324273d9f13SBarry Smith PetscFunctionBegin; 2325ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 2326e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 232755659b69SBarry Smith 2328b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 2329549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 233044cd7ae7SLois Curfman McInnes B->data = (void*)b; 233118f449edSLois Curfman McInnes 2332273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 23334e220ebcSLois Curfman McInnes 2334bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr); 2335bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr); 2336bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr); 23378baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 23388baccfbdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr); 23398baccfbdSHong Zhang #endif 2340bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr); 2341bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr); 2342bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr); 2343bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr); 2344abc3b08eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr); 23453bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr); 23463bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr); 23473bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr); 234817667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr); 23493a40ed3dSBarry Smith PetscFunctionReturn(0); 2350289bc588SBarry Smith } 2351